comparison Python/thread.c @ 61465:e38335d4df91 2.6

Recorded merge of revisions 81029 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r81029 | antoine.pitrou | 2010-05-09 16:46:46 +0200 (dim., 09 mai 2010) | 3 lines Untabify C files. Will watch buildbots. ........
author Antoine Pitrou <solipsis@pitrou.net>
date Sun, 09 May 2010 15:15:40 +0000
parents a8a8232cb541
children 787b969d37f0
comparison
equal deleted inserted replaced
61461:b6e03ca8a206 61465:e38335d4df91
44 #if defined(sun) && !defined(SOLARIS_THREADS) 44 #if defined(sun) && !defined(SOLARIS_THREADS)
45 #define SUN_LWP 45 #define SUN_LWP
46 #endif 46 #endif
47 47
48 /* Check if we're running on HP-UX and _SC_THREADS is defined. If so, then 48 /* Check if we're running on HP-UX and _SC_THREADS is defined. If so, then
49 enough of the Posix threads package is implimented to support python 49 enough of the Posix threads package is implimented to support python
50 threads. 50 threads.
51 51
52 This is valid for HP-UX 11.23 running on an ia64 system. If needed, add 52 This is valid for HP-UX 11.23 running on an ia64 system. If needed, add
53 a check of __ia64 to verify that we're running on a ia64 system instead 53 a check of __ia64 to verify that we're running on a ia64 system instead
54 of a pa-risc system. 54 of a pa-risc system.
62 #endif /* _POSIX_THREADS */ 62 #endif /* _POSIX_THREADS */
63 63
64 64
65 #ifdef Py_DEBUG 65 #ifdef Py_DEBUG
66 static int thread_debug = 0; 66 static int thread_debug = 0;
67 #define dprintf(args) (void)((thread_debug & 1) && printf args) 67 #define dprintf(args) (void)((thread_debug & 1) && printf args)
68 #define d2printf(args) ((thread_debug & 8) && printf args) 68 #define d2printf(args) ((thread_debug & 8) && printf args)
69 #else 69 #else
70 #define dprintf(args) 70 #define dprintf(args)
71 #define d2printf(args) 71 #define d2printf(args)
72 #endif 72 #endif
73 73
77 77
78 void 78 void
79 PyThread_init_thread(void) 79 PyThread_init_thread(void)
80 { 80 {
81 #ifdef Py_DEBUG 81 #ifdef Py_DEBUG
82 char *p = Py_GETENV("PYTHONTHREADDEBUG"); 82 char *p = Py_GETENV("PYTHONTHREADDEBUG");
83 83
84 if (p) { 84 if (p) {
85 if (*p) 85 if (*p)
86 thread_debug = atoi(p); 86 thread_debug = atoi(p);
87 else 87 else
88 thread_debug = 1; 88 thread_debug = 1;
89 } 89 }
90 #endif /* Py_DEBUG */ 90 #endif /* Py_DEBUG */
91 if (initialized) 91 if (initialized)
92 return; 92 return;
93 initialized = 1; 93 initialized = 1;
94 dprintf(("PyThread_init_thread called\n")); 94 dprintf(("PyThread_init_thread called\n"));
95 PyThread__init_thread(); 95 PyThread__init_thread();
96 } 96 }
97 97
98 /* Support for runtime thread stack size tuning. 98 /* Support for runtime thread stack size tuning.
99 A value of 0 means using the platform's default stack size 99 A value of 0 means using the platform's default stack size
100 or the size specified by the THREAD_STACK_SIZE macro. */ 100 or the size specified by the THREAD_STACK_SIZE macro. */
157 157
158 /* return the current thread stack size */ 158 /* return the current thread stack size */
159 size_t 159 size_t
160 PyThread_get_stacksize(void) 160 PyThread_get_stacksize(void)
161 { 161 {
162 return _pythread_stacksize; 162 return _pythread_stacksize;
163 } 163 }
164 164
165 /* Only platforms defining a THREAD_SET_STACKSIZE() macro 165 /* Only platforms defining a THREAD_SET_STACKSIZE() macro
166 in thread_<platform>.h support changing the stack size. 166 in thread_<platform>.h support changing the stack size.
167 Return 0 if stack size is valid, 167 Return 0 if stack size is valid,
168 -1 if stack size value is invalid, 168 -1 if stack size value is invalid,
169 -2 if setting stack size is not supported. */ 169 -2 if setting stack size is not supported. */
170 int 170 int
171 PyThread_set_stacksize(size_t size) 171 PyThread_set_stacksize(size_t size)
172 { 172 {
173 #if defined(THREAD_SET_STACKSIZE) 173 #if defined(THREAD_SET_STACKSIZE)
174 return THREAD_SET_STACKSIZE(size); 174 return THREAD_SET_STACKSIZE(size);
175 #else 175 #else
176 return -2; 176 return -2;
177 #endif 177 #endif
178 } 178 }
179 179
180 #ifndef Py_HAVE_NATIVE_TLS 180 #ifndef Py_HAVE_NATIVE_TLS
181 /* If the platform has not supplied a platform specific 181 /* If the platform has not supplied a platform specific
223 /* A singly-linked list of struct key objects remembers all the key->value 223 /* A singly-linked list of struct key objects remembers all the key->value
224 * associations. File static keyhead heads the list. keymutex is used 224 * associations. File static keyhead heads the list. keymutex is used
225 * to enforce exclusion internally. 225 * to enforce exclusion internally.
226 */ 226 */
227 struct key { 227 struct key {
228 /* Next record in the list, or NULL if this is the last record. */ 228 /* Next record in the list, or NULL if this is the last record. */
229 struct key *next; 229 struct key *next;
230 230
231 /* The thread id, according to PyThread_get_thread_ident(). */ 231 /* The thread id, according to PyThread_get_thread_ident(). */
232 long id; 232 long id;
233 233
234 /* The key and its associated value. */ 234 /* The key and its associated value. */
235 int key; 235 int key;
236 void *value; 236 void *value;
237 }; 237 };
238 238
239 static struct key *keyhead = NULL; 239 static struct key *keyhead = NULL;
240 static PyThread_type_lock keymutex = NULL; 240 static PyThread_type_lock keymutex = NULL;
241 static int nkeys = 0; /* PyThread_create_key() hands out nkeys+1 next */ 241 static int nkeys = 0; /* PyThread_create_key() hands out nkeys+1 next */
262 * segfaults. Now we lock the whole routine. 262 * segfaults. Now we lock the whole routine.
263 */ 263 */
264 static struct key * 264 static struct key *
265 find_key(int key, void *value) 265 find_key(int key, void *value)
266 { 266 {
267 struct key *p, *prev_p; 267 struct key *p, *prev_p;
268 long id = PyThread_get_thread_ident(); 268 long id = PyThread_get_thread_ident();
269 269
270 if (!keymutex) 270 if (!keymutex)
271 return NULL; 271 return NULL;
272 PyThread_acquire_lock(keymutex, 1); 272 PyThread_acquire_lock(keymutex, 1);
273 prev_p = NULL; 273 prev_p = NULL;
274 for (p = keyhead; p != NULL; p = p->next) { 274 for (p = keyhead; p != NULL; p = p->next) {
275 if (p->id == id && p->key == key) 275 if (p->id == id && p->key == key)
276 goto Done; 276 goto Done;
277 /* Sanity check. These states should never happen but if 277 /* Sanity check. These states should never happen but if
278 * they do we must abort. Otherwise we'll end up spinning in 278 * they do we must abort. Otherwise we'll end up spinning in
279 * in a tight loop with the lock held. A similar check is done 279 * in a tight loop with the lock held. A similar check is done
280 * in pystate.c tstate_delete_common(). */ 280 * in pystate.c tstate_delete_common(). */
281 if (p == prev_p) 281 if (p == prev_p)
282 Py_FatalError("tls find_key: small circular list(!)"); 282 Py_FatalError("tls find_key: small circular list(!)");
283 prev_p = p; 283 prev_p = p;
284 if (p->next == keyhead) 284 if (p->next == keyhead)
285 Py_FatalError("tls find_key: circular list(!)"); 285 Py_FatalError("tls find_key: circular list(!)");
286 } 286 }
287 if (value == NULL) { 287 if (value == NULL) {
288 assert(p == NULL); 288 assert(p == NULL);
289 goto Done; 289 goto Done;
290 } 290 }
291 p = (struct key *)malloc(sizeof(struct key)); 291 p = (struct key *)malloc(sizeof(struct key));
292 if (p != NULL) { 292 if (p != NULL) {
293 p->id = id; 293 p->id = id;
294 p->key = key; 294 p->key = key;
295 p->value = value; 295 p->value = value;
296 p->next = keyhead; 296 p->next = keyhead;
297 keyhead = p; 297 keyhead = p;
298 } 298 }
299 Done: 299 Done:
300 PyThread_release_lock(keymutex); 300 PyThread_release_lock(keymutex);
301 return p; 301 return p;
302 } 302 }
303 303
304 /* Return a new key. This must be called before any other functions in 304 /* Return a new key. This must be called before any other functions in
305 * this family, and callers must arrange to serialize calls to this 305 * this family, and callers must arrange to serialize calls to this
306 * function. No violations are detected. 306 * function. No violations are detected.
307 */ 307 */
308 int 308 int
309 PyThread_create_key(void) 309 PyThread_create_key(void)
310 { 310 {
311 /* All parts of this function are wrong if it's called by multiple 311 /* All parts of this function are wrong if it's called by multiple
312 * threads simultaneously. 312 * threads simultaneously.
313 */ 313 */
314 if (keymutex == NULL) 314 if (keymutex == NULL)
315 keymutex = PyThread_allocate_lock(); 315 keymutex = PyThread_allocate_lock();
316 return ++nkeys; 316 return ++nkeys;
317 } 317 }
318 318
319 /* Forget the associations for key across *all* threads. */ 319 /* Forget the associations for key across *all* threads. */
320 void 320 void
321 PyThread_delete_key(int key) 321 PyThread_delete_key(int key)
322 { 322 {
323 struct key *p, **q; 323 struct key *p, **q;
324 324
325 PyThread_acquire_lock(keymutex, 1); 325 PyThread_acquire_lock(keymutex, 1);
326 q = &keyhead; 326 q = &keyhead;
327 while ((p = *q) != NULL) { 327 while ((p = *q) != NULL) {
328 if (p->key == key) { 328 if (p->key == key) {
329 *q = p->next; 329 *q = p->next;
330 free((void *)p); 330 free((void *)p);
331 /* NB This does *not* free p->value! */ 331 /* NB This does *not* free p->value! */
332 } 332 }
333 else 333 else
334 q = &p->next; 334 q = &p->next;
335 } 335 }
336 PyThread_release_lock(keymutex); 336 PyThread_release_lock(keymutex);
337 } 337 }
338 338
339 /* Confusing: If the current thread has an association for key, 339 /* Confusing: If the current thread has an association for key,
340 * value is ignored, and 0 is returned. Else an attempt is made to create 340 * value is ignored, and 0 is returned. Else an attempt is made to create
341 * an association of key to value for the current thread. 0 is returned 341 * an association of key to value for the current thread. 0 is returned
343 * to create the association. value must not be NULL. 343 * to create the association. value must not be NULL.
344 */ 344 */
345 int 345 int
346 PyThread_set_key_value(int key, void *value) 346 PyThread_set_key_value(int key, void *value)
347 { 347 {
348 struct key *p; 348 struct key *p;
349 349
350 assert(value != NULL); 350 assert(value != NULL);
351 p = find_key(key, value); 351 p = find_key(key, value);
352 if (p == NULL) 352 if (p == NULL)
353 return -1; 353 return -1;
354 else 354 else
355 return 0; 355 return 0;
356 } 356 }
357 357
358 /* Retrieve the value associated with key in the current thread, or NULL 358 /* Retrieve the value associated with key in the current thread, or NULL
359 * if the current thread doesn't have an association for key. 359 * if the current thread doesn't have an association for key.
360 */ 360 */
361 void * 361 void *
362 PyThread_get_key_value(int key) 362 PyThread_get_key_value(int key)
363 { 363 {
364 struct key *p = find_key(key, NULL); 364 struct key *p = find_key(key, NULL);
365 365
366 if (p == NULL) 366 if (p == NULL)
367 return NULL; 367 return NULL;
368 else 368 else
369 return p->value; 369 return p->value;
370 } 370 }
371 371
372 /* Forget the current thread's association for key, if any. */ 372 /* Forget the current thread's association for key, if any. */
373 void 373 void
374 PyThread_delete_key_value(int key) 374 PyThread_delete_key_value(int key)
375 { 375 {
376 long id = PyThread_get_thread_ident(); 376 long id = PyThread_get_thread_ident();
377 struct key *p, **q; 377 struct key *p, **q;
378 378
379 PyThread_acquire_lock(keymutex, 1); 379 PyThread_acquire_lock(keymutex, 1);
380 q = &keyhead; 380 q = &keyhead;
381 while ((p = *q) != NULL) { 381 while ((p = *q) != NULL) {
382 if (p->key == key && p->id == id) { 382 if (p->key == key && p->id == id) {
383 *q = p->next; 383 *q = p->next;
384 free((void *)p); 384 free((void *)p);
385 /* NB This does *not* free p->value! */ 385 /* NB This does *not* free p->value! */
386 break; 386 break;
387 } 387 }
388 else 388 else
389 q = &p->next; 389 q = &p->next;
390 } 390 }
391 PyThread_release_lock(keymutex); 391 PyThread_release_lock(keymutex);
392 } 392 }
393 393
394 /* Forget everything not associated with the current thread id. 394 /* Forget everything not associated with the current thread id.
395 * This function is called from PyOS_AfterFork(). It is necessary 395 * This function is called from PyOS_AfterFork(). It is necessary
396 * because other thread ids which were in use at the time of the fork 396 * because other thread ids which were in use at the time of the fork
397 * may be reused for new threads created in the forked process. 397 * may be reused for new threads created in the forked process.
398 */ 398 */
399 void 399 void
400 PyThread_ReInitTLS(void) 400 PyThread_ReInitTLS(void)
401 { 401 {
402 long id = PyThread_get_thread_ident(); 402 long id = PyThread_get_thread_ident();
403 struct key *p, **q; 403 struct key *p, **q;
404 404
405 if (!keymutex) 405 if (!keymutex)
406 return; 406 return;
407 407
408 /* As with interpreter_lock in PyEval_ReInitThreads() 408 /* As with interpreter_lock in PyEval_ReInitThreads()
409 we just create a new lock without freeing the old one */ 409 we just create a new lock without freeing the old one */
410 keymutex = PyThread_allocate_lock(); 410 keymutex = PyThread_allocate_lock();
411 411
412 /* Delete all keys which do not match the current thread id */ 412 /* Delete all keys which do not match the current thread id */
413 q = &keyhead; 413 q = &keyhead;
414 while ((p = *q) != NULL) { 414 while ((p = *q) != NULL) {
415 if (p->id != id) { 415 if (p->id != id) {
416 *q = p->next; 416 *q = p->next;
417 free((void *)p); 417 free((void *)p);
418 /* NB This does *not* free p->value! */ 418 /* NB This does *not* free p->value! */
419 } 419 }
420 else 420 else
421 q = &p->next; 421 q = &p->next;
422 } 422 }
423 } 423 }
424 424
425 #endif /* Py_HAVE_NATIVE_TLS */ 425 #endif /* Py_HAVE_NATIVE_TLS */