changeset 1499:ad887c988713

Fixed bug #150 memory leak in SDL_thread.c
author Sam Lantinga <slouken@libsdl.org>
date Sun, 12 Mar 2006 01:18:29 +0000
parents 3968f7cba10c
children f58c88a4dff5
files src/thread/SDL_thread.c src/thread/irix/SDL_syssem.c
diffstat 2 files changed, 30 insertions(+), 54 deletions(-) [+]
line wrap: on
line diff
--- a/src/thread/SDL_thread.c	Sun Mar 12 00:57:50 2006 +0000
+++ b/src/thread/SDL_thread.c	Sun Mar 12 01:18:29 2006 +0000
@@ -37,20 +37,13 @@
 static int SDL_numthreads = 0;
 static SDL_Thread **SDL_Threads = NULL;
 static SDL_mutex *thread_lock = NULL;
-int _creating_thread_lock = 0;
 
 int SDL_ThreadsInit(void)
 {
 	int retval;
 
 	retval = 0;
-	/* Set the thread lock creation flag so that we can reuse an
-	   existing lock on the system - since this mutex never gets
-	   destroyed (see SDL_ThreadsQuit()), we want to reuse it.
-	*/
-	_creating_thread_lock = 1;
 	thread_lock = SDL_CreateMutex();
-	_creating_thread_lock = 0;
 	if ( thread_lock == NULL ) {
 		retval = -1;
 	}
@@ -76,15 +69,13 @@
 /* Routines for manipulating the thread list */
 static void SDL_AddThread(SDL_Thread *thread)
 {
-	SDL_Thread **threads;
-
 	/* WARNING:
 	   If the very first threads are created simultaneously, then
 	   there could be a race condition causing memory corruption.
 	   In practice, this isn't a problem because by definition there
 	   is only one thread running the first time this is called.
 	*/
-	if ( thread_lock == NULL ) {
+	if ( !thread_lock ) {
 		if ( SDL_ThreadsInit() < 0 ) {
 			return;
 		}
@@ -97,17 +88,14 @@
 			SDL_numthreads, SDL_maxthreads);
 #endif
 	if ( SDL_numthreads == SDL_maxthreads ) {
-		threads=(SDL_Thread **)SDL_malloc((SDL_maxthreads+ARRAY_CHUNKSIZE)*
-		                              (sizeof *threads));
+		SDL_Thread **threads;
+		threads = (SDL_Thread **)SDL_realloc(SDL_Threads,
+			(SDL_maxthreads+ARRAY_CHUNKSIZE)*(sizeof *threads));
 		if ( threads == NULL ) {
 			SDL_OutOfMemory();
 			goto done;
 		}
-		SDL_memcpy(threads, SDL_Threads, SDL_numthreads*(sizeof *threads));
 		SDL_maxthreads += ARRAY_CHUNKSIZE;
-		if ( SDL_Threads ) {
-			SDL_free(SDL_Threads);
-		}
 		SDL_Threads = threads;
 	}
 	SDL_Threads[SDL_numthreads++] = thread;
@@ -119,30 +107,35 @@
 {
 	int i;
 
-	if ( thread_lock ) {
-		SDL_mutexP(thread_lock);
-		for ( i=0; i<SDL_numthreads; ++i ) {
-			if ( thread == SDL_Threads[i] ) {
-				break;
-			}
+	if ( !thread_lock ) {
+		return;
+	}
+	SDL_mutexP(thread_lock);
+	for ( i=0; i<SDL_numthreads; ++i ) {
+		if ( thread == SDL_Threads[i] ) {
+			break;
 		}
-		if ( i < SDL_numthreads ) {
-			if ( --SDL_numthreads > 0 ) {
-				while ( i < SDL_numthreads ) {
-					SDL_Threads[i] = SDL_Threads[i+1];
-					++i;
-				}
-			} else {
-				SDL_maxthreads = 0;
-				SDL_free(SDL_Threads);
-				SDL_Threads = NULL;
+	}
+	if ( i < SDL_numthreads ) {
+		if ( --SDL_numthreads > 0 ) {
+			while ( i < SDL_numthreads ) {
+				SDL_Threads[i] = SDL_Threads[i+1];
+				++i;
 			}
+		} else {
+			SDL_maxthreads = 0;
+			SDL_free(SDL_Threads);
+			SDL_Threads = NULL;
+		}
 #ifdef DEBUG_THREADS
-			printf("Deleting thread (%d left - %d max)\n",
-					SDL_numthreads, SDL_maxthreads);
+		printf("Deleting thread (%d left - %d max)\n",
+				SDL_numthreads, SDL_maxthreads);
 #endif
-		}
-		SDL_mutexV(thread_lock);
+	}
+	SDL_mutexV(thread_lock);
+
+	if ( SDL_Threads == NULL ) {
+		SDL_ThreadsQuit();
 	}
 }
 
--- a/src/thread/irix/SDL_syssem.c	Sun Mar 12 00:57:50 2006 +0000
+++ b/src/thread/irix/SDL_syssem.c	Sun Mar 12 01:18:29 2006 +0000
@@ -67,30 +67,13 @@
 	extern int _creating_thread_lock;	/* SDL_threads.c */
 	SDL_sem *sem;
 	union semun init;
-	key_t key;
 
 	sem = (SDL_sem *)SDL_malloc(sizeof(*sem));
 	if ( sem == NULL ) {
 		SDL_OutOfMemory();
 		return(NULL);
 	}
-	/* This flag is true if we are creating the thread manager sem,
-	   which is never freed.  This allows us to reuse the same sem.
-	*/
-	if ( _creating_thread_lock ) {
-		key = 'S'+'D'+'L';
-	} else {
-		key = IPC_PRIVATE;
-	}
-	/* Keep trying to create sem while we don't own the requested key */
-	do {
-		if ( key != IPC_PRIVATE ) {
-			++key;
-		}
-		sem->id = semget(key, 1, (0600|IPC_CREAT));
-	} while ((sem->id < 0) && (key != IPC_PRIVATE) && (errno == EACCES));
-
-	/* Report the error if we eventually failed */
+	sem->id = semget(IPC_PRIVATE, 1, (0600|IPC_CREAT));
 	if ( sem->id < 0 ) {
 		SDL_SetError("Couldn't create semaphore");
 		SDL_free(sem);