@@ -354,47 +354,29 @@ _Py_COMP_DIAG_IGNORE_DEPR_DECLS
354
354
static const _PyRuntimeState initial = _PyRuntimeState_INIT (_PyRuntime );
355
355
_Py_COMP_DIAG_POP
356
356
357
+ #define NUMLOCKS 4
358
+
357
359
static int
358
- alloc_for_runtime (PyThread_type_lock * plock1 , PyThread_type_lock * plock2 ,
359
- PyThread_type_lock * plock3 , PyThread_type_lock * plock4 )
360
+ alloc_for_runtime (PyThread_type_lock locks [NUMLOCKS ])
360
361
{
361
362
/* Force default allocator, since _PyRuntimeState_Fini() must
362
363
use the same allocator than this function. */
363
364
PyMemAllocatorEx old_alloc ;
364
365
_PyMem_SetDefaultAllocator (PYMEM_DOMAIN_RAW , & old_alloc );
365
366
366
- PyThread_type_lock lock1 = PyThread_allocate_lock ();
367
- if (lock1 == NULL ) {
368
- return -1 ;
369
- }
370
-
371
- PyThread_type_lock lock2 = PyThread_allocate_lock ();
372
- if (lock2 == NULL ) {
373
- PyThread_free_lock (lock1 );
374
- return -1 ;
375
- }
376
-
377
- PyThread_type_lock lock3 = PyThread_allocate_lock ();
378
- if (lock3 == NULL ) {
379
- PyThread_free_lock (lock1 );
380
- PyThread_free_lock (lock2 );
381
- return -1 ;
382
- }
383
-
384
- PyThread_type_lock lock4 = PyThread_allocate_lock ();
385
- if (lock4 == NULL ) {
386
- PyThread_free_lock (lock1 );
387
- PyThread_free_lock (lock2 );
388
- PyThread_free_lock (lock3 );
389
- return -1 ;
367
+ for (int i = 0 ; i < NUMLOCKS ; i ++ ) {
368
+ PyThread_type_lock lock = PyThread_allocate_lock ();
369
+ if (lock == NULL ) {
370
+ for (int j = 0 ; j < i ; j ++ ) {
371
+ PyThread_free_lock (locks [j ]);
372
+ locks [j ] = NULL ;
373
+ }
374
+ break ;
375
+ }
376
+ locks [i ] = lock ;
390
377
}
391
378
392
379
PyMem_SetAllocator (PYMEM_DOMAIN_RAW , & old_alloc );
393
-
394
- * plock1 = lock1 ;
395
- * plock2 = lock2 ;
396
- * plock3 = lock3 ;
397
- * plock4 = lock4 ;
398
380
return 0 ;
399
381
}
400
382
@@ -403,10 +385,7 @@ init_runtime(_PyRuntimeState *runtime,
403
385
void * open_code_hook , void * open_code_userdata ,
404
386
_Py_AuditHookEntry * audit_hook_head ,
405
387
Py_ssize_t unicode_next_index ,
406
- PyThread_type_lock unicode_ids_mutex ,
407
- PyThread_type_lock interpreters_mutex ,
408
- PyThread_type_lock xidregistry_mutex ,
409
- PyThread_type_lock getargs_mutex )
388
+ PyThread_type_lock locks [NUMLOCKS ])
410
389
{
411
390
if (runtime -> _initialized ) {
412
391
Py_FatalError ("runtime already initialized" );
@@ -424,17 +403,21 @@ init_runtime(_PyRuntimeState *runtime,
424
403
425
404
PyPreConfig_InitPythonConfig (& runtime -> preconfig );
426
405
427
- runtime -> interpreters .mutex = interpreters_mutex ;
428
-
429
- runtime -> xidregistry .mutex = xidregistry_mutex ;
430
-
431
- runtime -> getargs .mutex = getargs_mutex ;
406
+ PyThread_type_lock * lockptrs [NUMLOCKS ] = {
407
+ & runtime -> interpreters .mutex ,
408
+ & runtime -> xidregistry .mutex ,
409
+ & runtime -> getargs .mutex ,
410
+ & runtime -> unicode_state .ids .lock ,
411
+ };
412
+ for (int i = 0 ; i < NUMLOCKS ; i ++ ) {
413
+ assert (locks [i ] != NULL );
414
+ * lockptrs [i ] = locks [i ];
415
+ }
432
416
433
417
// Set it to the ID of the main thread of the main interpreter.
434
418
runtime -> main_thread = PyThread_get_thread_ident ();
435
419
436
420
runtime -> unicode_state .ids .next_index = unicode_next_index ;
437
- runtime -> unicode_state .ids .lock = unicode_ids_mutex ;
438
421
439
422
runtime -> _initialized = 1 ;
440
423
}
@@ -452,8 +435,8 @@ _PyRuntimeState_Init(_PyRuntimeState *runtime)
452
435
// is called multiple times.
453
436
Py_ssize_t unicode_next_index = runtime -> unicode_state .ids .next_index ;
454
437
455
- PyThread_type_lock lock1 , lock2 , lock3 , lock4 ;
456
- if (alloc_for_runtime (& lock1 , & lock2 , & lock3 , & lock4 ) != 0 ) {
438
+ PyThread_type_lock locks [ NUMLOCKS ] ;
439
+ if (alloc_for_runtime (locks ) != 0 ) {
457
440
return _PyStatus_NO_MEMORY ();
458
441
}
459
442
@@ -474,7 +457,7 @@ _PyRuntimeState_Init(_PyRuntimeState *runtime)
474
457
}
475
458
476
459
init_runtime (runtime , open_code_hook , open_code_userdata , audit_hook_head ,
477
- unicode_next_index , lock1 , lock2 , lock3 , lock4 );
460
+ unicode_next_index , locks );
478
461
479
462
return _PyStatus_OK ();
480
463
}
@@ -504,10 +487,15 @@ _PyRuntimeState_Fini(_PyRuntimeState *runtime)
504
487
LOCK = NULL; \
505
488
}
506
489
507
- FREE_LOCK (runtime -> interpreters .mutex );
508
- FREE_LOCK (runtime -> xidregistry .mutex );
509
- FREE_LOCK (runtime -> unicode_state .ids .lock );
510
- FREE_LOCK (runtime -> getargs .mutex );
490
+ PyThread_type_lock * lockptrs [NUMLOCKS ] = {
491
+ & runtime -> interpreters .mutex ,
492
+ & runtime -> xidregistry .mutex ,
493
+ & runtime -> getargs .mutex ,
494
+ & runtime -> unicode_state .ids .lock ,
495
+ };
496
+ for (int i = 0 ; i < NUMLOCKS ; i ++ ) {
497
+ FREE_LOCK (* lockptrs [i ]);
498
+ }
511
499
512
500
#undef FREE_LOCK
513
501
PyMem_SetAllocator (PYMEM_DOMAIN_RAW , & old_alloc );
@@ -527,25 +515,25 @@ _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime)
527
515
PyMemAllocatorEx old_alloc ;
528
516
_PyMem_SetDefaultAllocator (PYMEM_DOMAIN_RAW , & old_alloc );
529
517
530
- int reinit_interp = _PyThread_at_fork_reinit (& runtime -> interpreters .mutex );
531
- int reinit_xidregistry = _PyThread_at_fork_reinit (& runtime -> xidregistry .mutex );
532
- int reinit_unicode_ids = _PyThread_at_fork_reinit (& runtime -> unicode_state .ids .lock );
533
- int reinit_getargs = _PyThread_at_fork_reinit (& runtime -> getargs .mutex );
518
+ PyThread_type_lock * lockptrs [NUMLOCKS ] = {
519
+ & runtime -> interpreters .mutex ,
520
+ & runtime -> xidregistry .mutex ,
521
+ & runtime -> getargs .mutex ,
522
+ & runtime -> unicode_state .ids .lock ,
523
+ };
524
+ int reinit_err = 0 ;
525
+ for (int i = 0 ; i < NUMLOCKS ; i ++ ) {
526
+ reinit_err += _PyThread_at_fork_reinit (lockptrs [i ]);
527
+ }
534
528
535
529
PyMem_SetAllocator (PYMEM_DOMAIN_RAW , & old_alloc );
536
530
537
531
/* bpo-42540: id_mutex is freed by _PyInterpreterState_Delete, which does
538
532
* not force the default allocator. */
539
- int reinit_main_id = _PyThread_at_fork_reinit (& runtime -> interpreters .main -> id_mutex );
533
+ reinit_err + = _PyThread_at_fork_reinit (& runtime -> interpreters .main -> id_mutex );
540
534
541
- if (reinit_interp < 0
542
- || reinit_main_id < 0
543
- || reinit_xidregistry < 0
544
- || reinit_unicode_ids < 0
545
- || reinit_getargs < 0 )
546
- {
535
+ if (reinit_err < 0 ) {
547
536
return _PyStatus_ERR ("Failed to reinitialize runtime locks" );
548
-
549
537
}
550
538
551
539
PyStatus status = gilstate_tss_reinit (runtime );
0 commit comments