|  | @@ -801,20 +801,38 @@ stat(const char *name, struct stat *st)
 | 
											
												
													
														|  |  #endif /* defined(_WIN32_WCE) */
 |  |  #endif /* defined(_WIN32_WCE) */
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +static pthread_mutex_t global_lock_mutex;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +static void
 | 
											
												
													
														|  | 
 |  | +mg_global_lock(void)
 | 
											
												
													
														|  | 
 |  | +{
 | 
											
												
													
														|  | 
 |  | +	(void)pthread_mutex_lock(&global_lock_mutex);
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +static void
 | 
											
												
													
														|  | 
 |  | +mg_global_unlock(void)
 | 
											
												
													
														|  | 
 |  | +{
 | 
											
												
													
														|  | 
 |  | +	(void)pthread_mutex_unlock(&global_lock_mutex);
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  static int
 |  |  static int
 | 
											
												
													
														|  |  mg_atomic_inc(volatile int *addr)
 |  |  mg_atomic_inc(volatile int *addr)
 | 
											
												
													
														|  |  {
 |  |  {
 | 
											
												
													
														|  |  	int ret;
 |  |  	int ret;
 | 
											
												
													
														|  | -#if defined(_WIN32) && !defined(__SYMBIAN32__)
 |  | 
 | 
											
												
													
														|  | 
 |  | +#if defined(_WIN32) && !defined(__SYMBIAN32__) && !defined(NO_ATOMICS)
 | 
											
												
													
														|  |  	/* Depending on the SDK, this function uses either
 |  |  	/* Depending on the SDK, this function uses either
 | 
											
												
													
														|  |  	 * (volatile unsigned int *) or (volatile LONG *),
 |  |  	 * (volatile unsigned int *) or (volatile LONG *),
 | 
											
												
													
														|  |  	 * so whatever you use, the other SDK is likely to raise a warning. */
 |  |  	 * so whatever you use, the other SDK is likely to raise a warning. */
 | 
											
												
													
														|  |  	ret = InterlockedIncrement((volatile long *)addr);
 |  |  	ret = InterlockedIncrement((volatile long *)addr);
 | 
											
												
													
														|  |  #elif defined(__GNUC__)                                                        \
 |  |  #elif defined(__GNUC__)                                                        \
 | 
											
												
													
														|  | -    && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 0)))
 |  | 
 | 
											
												
													
														|  | 
 |  | +    && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 0)))           \
 | 
											
												
													
														|  | 
 |  | +    && !defined(NO_ATOMICS)
 | 
											
												
													
														|  |  	ret = __sync_add_and_fetch(addr, 1);
 |  |  	ret = __sync_add_and_fetch(addr, 1);
 | 
											
												
													
														|  |  #else
 |  |  #else
 | 
											
												
													
														|  | 
 |  | +	mg_global_lock();
 | 
											
												
													
														|  |  	ret = (++(*addr));
 |  |  	ret = (++(*addr));
 | 
											
												
													
														|  | 
 |  | +	mg_global_unlock();
 | 
											
												
													
														|  |  #endif
 |  |  #endif
 | 
											
												
													
														|  |  	return ret;
 |  |  	return ret;
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
										
											
												
													
														|  | @@ -824,16 +842,19 @@ static int
 | 
											
												
													
														|  |  mg_atomic_dec(volatile int *addr)
 |  |  mg_atomic_dec(volatile int *addr)
 | 
											
												
													
														|  |  {
 |  |  {
 | 
											
												
													
														|  |  	int ret;
 |  |  	int ret;
 | 
											
												
													
														|  | -#if defined(_WIN32) && !defined(__SYMBIAN32__)
 |  | 
 | 
											
												
													
														|  | 
 |  | +#if defined(_WIN32) && !defined(__SYMBIAN32__) && !defined(NO_ATOMICS)
 | 
											
												
													
														|  |  	/* Depending on the SDK, this function uses either
 |  |  	/* Depending on the SDK, this function uses either
 | 
											
												
													
														|  |  	 * (volatile unsigned int *) or (volatile LONG *),
 |  |  	 * (volatile unsigned int *) or (volatile LONG *),
 | 
											
												
													
														|  |  	 * so whatever you use, the other SDK is likely to raise a warning. */
 |  |  	 * so whatever you use, the other SDK is likely to raise a warning. */
 | 
											
												
													
														|  |  	ret = InterlockedDecrement((volatile long *)addr);
 |  |  	ret = InterlockedDecrement((volatile long *)addr);
 | 
											
												
													
														|  |  #elif defined(__GNUC__)                                                        \
 |  |  #elif defined(__GNUC__)                                                        \
 | 
											
												
													
														|  | -    && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 0)))
 |  | 
 | 
											
												
													
														|  | 
 |  | +    && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 0)))           \
 | 
											
												
													
														|  | 
 |  | +    && !defined(NO_ATOMICS)
 | 
											
												
													
														|  |  	ret = __sync_sub_and_fetch(addr, 1);
 |  |  	ret = __sync_sub_and_fetch(addr, 1);
 | 
											
												
													
														|  |  #else
 |  |  #else
 | 
											
												
													
														|  | 
 |  | +	mg_global_lock();
 | 
											
												
													
														|  |  	ret = (--(*addr));
 |  |  	ret = (--(*addr));
 | 
											
												
													
														|  | 
 |  | +	mg_global_unlock();
 | 
											
												
													
														|  |  #endif
 |  |  #endif
 | 
											
												
													
														|  |  	return ret;
 |  |  	return ret;
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
										
											
												
													
														|  | @@ -860,13 +881,17 @@ static int64_t
 | 
											
												
													
														|  |  mg_atomic_add(volatile int64_t *addr, int64_t value)
 |  |  mg_atomic_add(volatile int64_t *addr, int64_t value)
 | 
											
												
													
														|  |  {
 |  |  {
 | 
											
												
													
														|  |  	int64_t ret;
 |  |  	int64_t ret;
 | 
											
												
													
														|  | -#if defined(_WIN32) && !defined(__SYMBIAN32__)
 |  | 
 | 
											
												
													
														|  | 
 |  | +#if defined(_WIN32) && !defined(__SYMBIAN32__) && !defined(NO_ATOMICS)
 | 
											
												
													
														|  |  	ret = InterlockedAdd64(addr, value);
 |  |  	ret = InterlockedAdd64(addr, value);
 | 
											
												
													
														|  |  #elif defined(__GNUC__)                                                        \
 |  |  #elif defined(__GNUC__)                                                        \
 | 
											
												
													
														|  | -    && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 0)))
 |  | 
 | 
											
												
													
														|  | 
 |  | +    && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 0)))           \
 | 
											
												
													
														|  | 
 |  | +    && !defined(NO_ATOMICS)
 | 
											
												
													
														|  |  	ret = __sync_add_and_fetch(addr, value);
 |  |  	ret = __sync_add_and_fetch(addr, value);
 | 
											
												
													
														|  |  #else
 |  |  #else
 | 
											
												
													
														|  | -	ret = (++(*addr));
 |  | 
 | 
											
												
													
														|  | 
 |  | +	mg_global_lock();
 | 
											
												
													
														|  | 
 |  | +	*addr += value;
 | 
											
												
													
														|  | 
 |  | +	ret = (*addr);
 | 
											
												
													
														|  | 
 |  | +	mg_global_unlock();
 | 
											
												
													
														|  |  #endif
 |  |  #endif
 | 
											
												
													
														|  |  	return ret;
 |  |  	return ret;
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
										
											
												
													
														|  | @@ -16791,6 +16816,13 @@ mg_init_library(unsigned features)
 | 
											
												
													
														|  |  	unsigned features_to_init = mg_check_feature(features & 0xFFu);
 |  |  	unsigned features_to_init = mg_check_feature(features & 0xFFu);
 | 
											
												
													
														|  |  	unsigned features_inited = features_to_init;
 |  |  	unsigned features_inited = features_to_init;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +	if (mg_init_library_called <= 0) {
 | 
											
												
													
														|  | 
 |  | +		/* Not initialized yet */
 | 
											
												
													
														|  | 
 |  | +		if (0 != pthread_mutex_init(&global_lock_mutex, NULL)) {
 | 
											
												
													
														|  | 
 |  | +			return 0;
 | 
											
												
													
														|  | 
 |  | +		}
 | 
											
												
													
														|  | 
 |  | +	}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  #if !defined(NO_SSL)
 |  |  #if !defined(NO_SSL)
 | 
											
												
													
														|  |  	if (features_to_init & 2) {
 |  |  	if (features_to_init & 2) {
 | 
											
												
													
														|  |  		if (!mg_ssl_initialized) {
 |  |  		if (!mg_ssl_initialized) {
 | 
											
										
											
												
													
														|  | @@ -16840,6 +16872,7 @@ mg_exit_library(void)
 | 
											
												
													
														|  |  			mg_ssl_initialized = 0;
 |  |  			mg_ssl_initialized = 0;
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  |  #endif
 |  |  #endif
 | 
											
												
													
														|  | 
 |  | +		(void)pthread_mutex_destroy(&global_lock_mutex);
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
												
													
														|  |  	return 1;
 |  |  	return 1;
 | 
											
												
													
														|  |  }
 |  |  }
 |