Fixed bug #150
authorSam Lantinga <slouken@libsdl.org>
Sun, 12 Mar 2006 01:18:29 +0000
changeset 1499ad887c988713
parent 1498 3968f7cba10c
child 1500 f58c88a4dff5
Fixed bug #150
memory leak in SDL_thread.c
src/thread/SDL_thread.c
src/thread/irix/SDL_syssem.c
     1.1 --- a/src/thread/SDL_thread.c	Sun Mar 12 00:57:50 2006 +0000
     1.2 +++ b/src/thread/SDL_thread.c	Sun Mar 12 01:18:29 2006 +0000
     1.3 @@ -37,20 +37,13 @@
     1.4  static int SDL_numthreads = 0;
     1.5  static SDL_Thread **SDL_Threads = NULL;
     1.6  static SDL_mutex *thread_lock = NULL;
     1.7 -int _creating_thread_lock = 0;
     1.8  
     1.9  int SDL_ThreadsInit(void)
    1.10  {
    1.11  	int retval;
    1.12  
    1.13  	retval = 0;
    1.14 -	/* Set the thread lock creation flag so that we can reuse an
    1.15 -	   existing lock on the system - since this mutex never gets
    1.16 -	   destroyed (see SDL_ThreadsQuit()), we want to reuse it.
    1.17 -	*/
    1.18 -	_creating_thread_lock = 1;
    1.19  	thread_lock = SDL_CreateMutex();
    1.20 -	_creating_thread_lock = 0;
    1.21  	if ( thread_lock == NULL ) {
    1.22  		retval = -1;
    1.23  	}
    1.24 @@ -76,15 +69,13 @@
    1.25  /* Routines for manipulating the thread list */
    1.26  static void SDL_AddThread(SDL_Thread *thread)
    1.27  {
    1.28 -	SDL_Thread **threads;
    1.29 -
    1.30  	/* WARNING:
    1.31  	   If the very first threads are created simultaneously, then
    1.32  	   there could be a race condition causing memory corruption.
    1.33  	   In practice, this isn't a problem because by definition there
    1.34  	   is only one thread running the first time this is called.
    1.35  	*/
    1.36 -	if ( thread_lock == NULL ) {
    1.37 +	if ( !thread_lock ) {
    1.38  		if ( SDL_ThreadsInit() < 0 ) {
    1.39  			return;
    1.40  		}
    1.41 @@ -97,17 +88,14 @@
    1.42  			SDL_numthreads, SDL_maxthreads);
    1.43  #endif
    1.44  	if ( SDL_numthreads == SDL_maxthreads ) {
    1.45 -		threads=(SDL_Thread **)SDL_malloc((SDL_maxthreads+ARRAY_CHUNKSIZE)*
    1.46 -		                              (sizeof *threads));
    1.47 +		SDL_Thread **threads;
    1.48 +		threads = (SDL_Thread **)SDL_realloc(SDL_Threads,
    1.49 +			(SDL_maxthreads+ARRAY_CHUNKSIZE)*(sizeof *threads));
    1.50  		if ( threads == NULL ) {
    1.51  			SDL_OutOfMemory();
    1.52  			goto done;
    1.53  		}
    1.54 -		SDL_memcpy(threads, SDL_Threads, SDL_numthreads*(sizeof *threads));
    1.55  		SDL_maxthreads += ARRAY_CHUNKSIZE;
    1.56 -		if ( SDL_Threads ) {
    1.57 -			SDL_free(SDL_Threads);
    1.58 -		}
    1.59  		SDL_Threads = threads;
    1.60  	}
    1.61  	SDL_Threads[SDL_numthreads++] = thread;
    1.62 @@ -119,30 +107,35 @@
    1.63  {
    1.64  	int i;
    1.65  
    1.66 -	if ( thread_lock ) {
    1.67 -		SDL_mutexP(thread_lock);
    1.68 -		for ( i=0; i<SDL_numthreads; ++i ) {
    1.69 -			if ( thread == SDL_Threads[i] ) {
    1.70 -				break;
    1.71 +	if ( !thread_lock ) {
    1.72 +		return;
    1.73 +	}
    1.74 +	SDL_mutexP(thread_lock);
    1.75 +	for ( i=0; i<SDL_numthreads; ++i ) {
    1.76 +		if ( thread == SDL_Threads[i] ) {
    1.77 +			break;
    1.78 +		}
    1.79 +	}
    1.80 +	if ( i < SDL_numthreads ) {
    1.81 +		if ( --SDL_numthreads > 0 ) {
    1.82 +			while ( i < SDL_numthreads ) {
    1.83 +				SDL_Threads[i] = SDL_Threads[i+1];
    1.84 +				++i;
    1.85  			}
    1.86 +		} else {
    1.87 +			SDL_maxthreads = 0;
    1.88 +			SDL_free(SDL_Threads);
    1.89 +			SDL_Threads = NULL;
    1.90  		}
    1.91 -		if ( i < SDL_numthreads ) {
    1.92 -			if ( --SDL_numthreads > 0 ) {
    1.93 -				while ( i < SDL_numthreads ) {
    1.94 -					SDL_Threads[i] = SDL_Threads[i+1];
    1.95 -					++i;
    1.96 -				}
    1.97 -			} else {
    1.98 -				SDL_maxthreads = 0;
    1.99 -				SDL_free(SDL_Threads);
   1.100 -				SDL_Threads = NULL;
   1.101 -			}
   1.102  #ifdef DEBUG_THREADS
   1.103 -			printf("Deleting thread (%d left - %d max)\n",
   1.104 -					SDL_numthreads, SDL_maxthreads);
   1.105 +		printf("Deleting thread (%d left - %d max)\n",
   1.106 +				SDL_numthreads, SDL_maxthreads);
   1.107  #endif
   1.108 -		}
   1.109 -		SDL_mutexV(thread_lock);
   1.110 +	}
   1.111 +	SDL_mutexV(thread_lock);
   1.112 +
   1.113 +	if ( SDL_Threads == NULL ) {
   1.114 +		SDL_ThreadsQuit();
   1.115  	}
   1.116  }
   1.117  
     2.1 --- a/src/thread/irix/SDL_syssem.c	Sun Mar 12 00:57:50 2006 +0000
     2.2 +++ b/src/thread/irix/SDL_syssem.c	Sun Mar 12 01:18:29 2006 +0000
     2.3 @@ -67,30 +67,13 @@
     2.4  	extern int _creating_thread_lock;	/* SDL_threads.c */
     2.5  	SDL_sem *sem;
     2.6  	union semun init;
     2.7 -	key_t key;
     2.8  
     2.9  	sem = (SDL_sem *)SDL_malloc(sizeof(*sem));
    2.10  	if ( sem == NULL ) {
    2.11  		SDL_OutOfMemory();
    2.12  		return(NULL);
    2.13  	}
    2.14 -	/* This flag is true if we are creating the thread manager sem,
    2.15 -	   which is never freed.  This allows us to reuse the same sem.
    2.16 -	*/
    2.17 -	if ( _creating_thread_lock ) {
    2.18 -		key = 'S'+'D'+'L';
    2.19 -	} else {
    2.20 -		key = IPC_PRIVATE;
    2.21 -	}
    2.22 -	/* Keep trying to create sem while we don't own the requested key */
    2.23 -	do {
    2.24 -		if ( key != IPC_PRIVATE ) {
    2.25 -			++key;
    2.26 -		}
    2.27 -		sem->id = semget(key, 1, (0600|IPC_CREAT));
    2.28 -	} while ((sem->id < 0) && (key != IPC_PRIVATE) && (errno == EACCES));
    2.29 -
    2.30 -	/* Report the error if we eventually failed */
    2.31 +	sem->id = semget(IPC_PRIVATE, 1, (0600|IPC_CREAT));
    2.32  	if ( sem->id < 0 ) {
    2.33  		SDL_SetError("Couldn't create semaphore");
    2.34  		SDL_free(sem);