Changeset 388 for python/vendor/current/Python/thread.c
- Timestamp:
- Mar 19, 2014, 11:11:30 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
python/vendor/current/Python/thread.c
r2 r388 25 25 26 26 #ifdef __sgi 27 #ifndef HAVE_PTHREAD_H /* XXX Need to check in configure. in*/27 #ifndef HAVE_PTHREAD_H /* XXX Need to check in configure.ac */ 28 28 #undef _POSIX_THREADS 29 29 #endif … … 47 47 48 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 impl imented to support python49 enough of the Posix threads package is implemented to support python 50 50 threads. 51 51 … … 65 65 #ifdef Py_DEBUG 66 66 static int thread_debug = 0; 67 #define dprintf(args) 68 #define d2printf(args) 67 #define dprintf(args) (void)((thread_debug & 1) && printf args) 68 #define d2printf(args) ((thread_debug & 8) && printf args) 69 69 #else 70 70 #define dprintf(args) … … 80 80 { 81 81 #ifdef Py_DEBUG 82 83 84 85 86 87 88 89 82 char *p = Py_GETENV("PYTHONTHREADDEBUG"); 83 84 if (p) { 85 if (*p) 86 thread_debug = atoi(p); 87 else 88 thread_debug = 1; 89 } 90 90 #endif /* Py_DEBUG */ 91 92 93 94 95 91 if (initialized) 92 return; 93 initialized = 1; 94 dprintf(("PyThread_init_thread called\n")); 95 PyThread__init_thread(); 96 96 } 97 97 … … 138 138 #endif 139 139 140 #ifdef WINCE_THREADS141 #include "thread_wince.h"142 #endif143 144 140 #ifdef PLAN9_THREADS 145 141 #include "thread_plan9.h" … … 160 156 PyThread_get_stacksize(void) 161 157 { 162 158 return _pythread_stacksize; 163 159 } 164 160 … … 166 162 in thread_<platform>.h support changing the stack size. 167 163 Return 0 if stack size is valid, 168 169 164 -1 if stack size value is invalid, 165 -2 if setting stack size is not supported. */ 170 166 int 171 167 PyThread_set_stacksize(size_t size) 172 168 { 173 169 #if defined(THREAD_SET_STACKSIZE) 174 170 return THREAD_SET_STACKSIZE(size); 175 171 #else 176 172 return -2; 177 173 #endif 178 174 } … … 226 222 */ 227 223 struct key { 228 229 230 231 232 233 234 235 236 224 /* Next record in the list, or NULL if this is the last record. */ 225 struct key *next; 226 227 /* The thread id, according to PyThread_get_thread_ident(). */ 228 long id; 229 230 /* The key and its associated value. */ 231 int key; 232 void *value; 237 233 }; 238 234 … … 265 261 find_key(int key, void *value) 266 262 { 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 263 struct key *p, *prev_p; 264 long id = PyThread_get_thread_ident(); 265 266 if (!keymutex) 267 return NULL; 268 PyThread_acquire_lock(keymutex, 1); 269 prev_p = NULL; 270 for (p = keyhead; p != NULL; p = p->next) { 271 if (p->id == id && p->key == key) 272 goto Done; 273 /* Sanity check. These states should never happen but if 274 * they do we must abort. Otherwise we'll end up spinning in 275 * in a tight loop with the lock held. A similar check is done 276 * in pystate.c tstate_delete_common(). */ 277 if (p == prev_p) 278 Py_FatalError("tls find_key: small circular list(!)"); 279 prev_p = p; 280 if (p->next == keyhead) 281 Py_FatalError("tls find_key: circular list(!)"); 282 } 283 if (value == NULL) { 284 assert(p == NULL); 285 goto Done; 286 } 287 p = (struct key *)malloc(sizeof(struct key)); 288 if (p != NULL) { 289 p->id = id; 290 p->key = key; 291 p->value = value; 292 p->next = keyhead; 293 keyhead = p; 294 } 299 295 Done: 300 301 296 PyThread_release_lock(keymutex); 297 return p; 302 298 } 303 299 … … 309 305 PyThread_create_key(void) 310 306 { 311 312 313 314 315 316 307 /* All parts of this function are wrong if it's called by multiple 308 * threads simultaneously. 309 */ 310 if (keymutex == NULL) 311 keymutex = PyThread_allocate_lock(); 312 return ++nkeys; 317 313 } 318 314 … … 321 317 PyThread_delete_key(int key) 322 318 { 323 324 325 326 327 328 329 330 331 332 333 334 335 336 319 struct key *p, **q; 320 321 PyThread_acquire_lock(keymutex, 1); 322 q = &keyhead; 323 while ((p = *q) != NULL) { 324 if (p->key == key) { 325 *q = p->next; 326 free((void *)p); 327 /* NB This does *not* free p->value! */ 328 } 329 else 330 q = &p->next; 331 } 332 PyThread_release_lock(keymutex); 337 333 } 338 334 … … 346 342 PyThread_set_key_value(int key, void *value) 347 343 { 348 349 350 351 352 353 354 355 344 struct key *p; 345 346 assert(value != NULL); 347 p = find_key(key, value); 348 if (p == NULL) 349 return -1; 350 else 351 return 0; 356 352 } 357 353 … … 362 358 PyThread_get_key_value(int key) 363 359 { 364 365 366 367 368 369 360 struct key *p = find_key(key, NULL); 361 362 if (p == NULL) 363 return NULL; 364 else 365 return p->value; 370 366 } 371 367 … … 374 370 PyThread_delete_key_value(int key) 375 371 { 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 372 long id = PyThread_get_thread_ident(); 373 struct key *p, **q; 374 375 PyThread_acquire_lock(keymutex, 1); 376 q = &keyhead; 377 while ((p = *q) != NULL) { 378 if (p->key == key && p->id == id) { 379 *q = p->next; 380 free((void *)p); 381 /* NB This does *not* free p->value! */ 382 break; 383 } 384 else 385 q = &p->next; 386 } 387 PyThread_release_lock(keymutex); 392 388 } 393 389 … … 400 396 PyThread_ReInitTLS(void) 401 397 { 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 398 long id = PyThread_get_thread_ident(); 399 struct key *p, **q; 400 401 if (!keymutex) 402 return; 403 404 /* As with interpreter_lock in PyEval_ReInitThreads() 405 we just create a new lock without freeing the old one */ 406 keymutex = PyThread_allocate_lock(); 407 408 /* Delete all keys which do not match the current thread id */ 409 q = &keyhead; 410 while ((p = *q) != NULL) { 411 if (p->id != id) { 412 *q = p->next; 413 free((void *)p); 414 /* NB This does *not* free p->value! */ 415 } 416 else 417 q = &p->next; 418 } 423 419 } 424 420
Note:
See TracChangeset
for help on using the changeset viewer.