comparison src/thread/SDL_thread.c @ 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 9fb0eee04dd9
children 97d0966f4bf7
comparison
equal deleted inserted replaced
1498:3968f7cba10c 1499:ad887c988713
35 */ 35 */
36 static int SDL_maxthreads = 0; 36 static int SDL_maxthreads = 0;
37 static int SDL_numthreads = 0; 37 static int SDL_numthreads = 0;
38 static SDL_Thread **SDL_Threads = NULL; 38 static SDL_Thread **SDL_Threads = NULL;
39 static SDL_mutex *thread_lock = NULL; 39 static SDL_mutex *thread_lock = NULL;
40 int _creating_thread_lock = 0;
41 40
42 int SDL_ThreadsInit(void) 41 int SDL_ThreadsInit(void)
43 { 42 {
44 int retval; 43 int retval;
45 44
46 retval = 0; 45 retval = 0;
47 /* Set the thread lock creation flag so that we can reuse an
48 existing lock on the system - since this mutex never gets
49 destroyed (see SDL_ThreadsQuit()), we want to reuse it.
50 */
51 _creating_thread_lock = 1;
52 thread_lock = SDL_CreateMutex(); 46 thread_lock = SDL_CreateMutex();
53 _creating_thread_lock = 0;
54 if ( thread_lock == NULL ) { 47 if ( thread_lock == NULL ) {
55 retval = -1; 48 retval = -1;
56 } 49 }
57 return(retval); 50 return(retval);
58 } 51 }
74 } 67 }
75 68
76 /* Routines for manipulating the thread list */ 69 /* Routines for manipulating the thread list */
77 static void SDL_AddThread(SDL_Thread *thread) 70 static void SDL_AddThread(SDL_Thread *thread)
78 { 71 {
79 SDL_Thread **threads;
80
81 /* WARNING: 72 /* WARNING:
82 If the very first threads are created simultaneously, then 73 If the very first threads are created simultaneously, then
83 there could be a race condition causing memory corruption. 74 there could be a race condition causing memory corruption.
84 In practice, this isn't a problem because by definition there 75 In practice, this isn't a problem because by definition there
85 is only one thread running the first time this is called. 76 is only one thread running the first time this is called.
86 */ 77 */
87 if ( thread_lock == NULL ) { 78 if ( !thread_lock ) {
88 if ( SDL_ThreadsInit() < 0 ) { 79 if ( SDL_ThreadsInit() < 0 ) {
89 return; 80 return;
90 } 81 }
91 } 82 }
92 SDL_mutexP(thread_lock); 83 SDL_mutexP(thread_lock);
95 #ifdef DEBUG_THREADS 86 #ifdef DEBUG_THREADS
96 printf("Adding thread (%d already - %d max)\n", 87 printf("Adding thread (%d already - %d max)\n",
97 SDL_numthreads, SDL_maxthreads); 88 SDL_numthreads, SDL_maxthreads);
98 #endif 89 #endif
99 if ( SDL_numthreads == SDL_maxthreads ) { 90 if ( SDL_numthreads == SDL_maxthreads ) {
100 threads=(SDL_Thread **)SDL_malloc((SDL_maxthreads+ARRAY_CHUNKSIZE)* 91 SDL_Thread **threads;
101 (sizeof *threads)); 92 threads = (SDL_Thread **)SDL_realloc(SDL_Threads,
93 (SDL_maxthreads+ARRAY_CHUNKSIZE)*(sizeof *threads));
102 if ( threads == NULL ) { 94 if ( threads == NULL ) {
103 SDL_OutOfMemory(); 95 SDL_OutOfMemory();
104 goto done; 96 goto done;
105 } 97 }
106 SDL_memcpy(threads, SDL_Threads, SDL_numthreads*(sizeof *threads));
107 SDL_maxthreads += ARRAY_CHUNKSIZE; 98 SDL_maxthreads += ARRAY_CHUNKSIZE;
108 if ( SDL_Threads ) {
109 SDL_free(SDL_Threads);
110 }
111 SDL_Threads = threads; 99 SDL_Threads = threads;
112 } 100 }
113 SDL_Threads[SDL_numthreads++] = thread; 101 SDL_Threads[SDL_numthreads++] = thread;
114 done: 102 done:
115 SDL_mutexV(thread_lock); 103 SDL_mutexV(thread_lock);
117 105
118 static void SDL_DelThread(SDL_Thread *thread) 106 static void SDL_DelThread(SDL_Thread *thread)
119 { 107 {
120 int i; 108 int i;
121 109
122 if ( thread_lock ) { 110 if ( !thread_lock ) {
123 SDL_mutexP(thread_lock); 111 return;
124 for ( i=0; i<SDL_numthreads; ++i ) { 112 }
125 if ( thread == SDL_Threads[i] ) { 113 SDL_mutexP(thread_lock);
126 break; 114 for ( i=0; i<SDL_numthreads; ++i ) {
115 if ( thread == SDL_Threads[i] ) {
116 break;
117 }
118 }
119 if ( i < SDL_numthreads ) {
120 if ( --SDL_numthreads > 0 ) {
121 while ( i < SDL_numthreads ) {
122 SDL_Threads[i] = SDL_Threads[i+1];
123 ++i;
127 } 124 }
128 } 125 } else {
129 if ( i < SDL_numthreads ) { 126 SDL_maxthreads = 0;
130 if ( --SDL_numthreads > 0 ) { 127 SDL_free(SDL_Threads);
131 while ( i < SDL_numthreads ) { 128 SDL_Threads = NULL;
132 SDL_Threads[i] = SDL_Threads[i+1]; 129 }
133 ++i;
134 }
135 } else {
136 SDL_maxthreads = 0;
137 SDL_free(SDL_Threads);
138 SDL_Threads = NULL;
139 }
140 #ifdef DEBUG_THREADS 130 #ifdef DEBUG_THREADS
141 printf("Deleting thread (%d left - %d max)\n", 131 printf("Deleting thread (%d left - %d max)\n",
142 SDL_numthreads, SDL_maxthreads); 132 SDL_numthreads, SDL_maxthreads);
143 #endif 133 #endif
144 } 134 }
145 SDL_mutexV(thread_lock); 135 SDL_mutexV(thread_lock);
136
137 if ( SDL_Threads == NULL ) {
138 SDL_ThreadsQuit();
146 } 139 }
147 } 140 }
148 141
149 /* The default (non-thread-safe) global error variable */ 142 /* The default (non-thread-safe) global error variable */
150 static SDL_error SDL_global_error; 143 static SDL_error SDL_global_error;