Mercurial > sdl-ios-xcode
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; |