# HG changeset patch # User Sam Lantinga # Date 1142126309 0 # Node ID ad887c9887130fe5f38c0e720de4f23502d23bbe # Parent 3968f7cba10c109e45f60a2278aa529fb1cd9f92 Fixed bug #150 memory leak in SDL_thread.c diff -r 3968f7cba10c -r ad887c988713 src/thread/SDL_thread.c --- 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 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(); } } diff -r 3968f7cba10c -r ad887c988713 src/thread/irix/SDL_syssem.c --- 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);