@@ -354,47 +354,29 @@ _Py_COMP_DIAG_IGNORE_DEPR_DECLS
354354static const _PyRuntimeState initial = _PyRuntimeState_INIT (_PyRuntime );
355355_Py_COMP_DIAG_POP
356356
357+ #define NUMLOCKS 4
358+
357359static 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 ])
360361{
361362 /* Force default allocator, since _PyRuntimeState_Fini() must
362363 use the same allocator than this function. */
363364 PyMemAllocatorEx old_alloc ;
364365 _PyMem_SetDefaultAllocator (PYMEM_DOMAIN_RAW , & old_alloc );
365366
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 ;
390377 }
391378
392379 PyMem_SetAllocator (PYMEM_DOMAIN_RAW , & old_alloc );
393-
394- * plock1 = lock1 ;
395- * plock2 = lock2 ;
396- * plock3 = lock3 ;
397- * plock4 = lock4 ;
398380 return 0 ;
399381}
400382
@@ -403,10 +385,7 @@ init_runtime(_PyRuntimeState *runtime,
403385 void * open_code_hook , void * open_code_userdata ,
404386 _Py_AuditHookEntry * audit_hook_head ,
405387 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 ])
410389{
411390 if (runtime -> _initialized ) {
412391 Py_FatalError ("runtime already initialized" );
@@ -424,17 +403,21 @@ init_runtime(_PyRuntimeState *runtime,
424403
425404 PyPreConfig_InitPythonConfig (& runtime -> preconfig );
426405
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+ }
432416
433417 // Set it to the ID of the main thread of the main interpreter.
434418 runtime -> main_thread = PyThread_get_thread_ident ();
435419
436420 runtime -> unicode_state .ids .next_index = unicode_next_index ;
437- runtime -> unicode_state .ids .lock = unicode_ids_mutex ;
438421
439422 runtime -> _initialized = 1 ;
440423}
@@ -452,8 +435,8 @@ _PyRuntimeState_Init(_PyRuntimeState *runtime)
452435 // is called multiple times.
453436 Py_ssize_t unicode_next_index = runtime -> unicode_state .ids .next_index ;
454437
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 ) {
457440 return _PyStatus_NO_MEMORY ();
458441 }
459442
@@ -474,7 +457,7 @@ _PyRuntimeState_Init(_PyRuntimeState *runtime)
474457 }
475458
476459 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 );
478461
479462 return _PyStatus_OK ();
480463}
@@ -504,10 +487,15 @@ _PyRuntimeState_Fini(_PyRuntimeState *runtime)
504487 LOCK = NULL; \
505488 }
506489
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+ }
511499
512500#undef FREE_LOCK
513501 PyMem_SetAllocator (PYMEM_DOMAIN_RAW , & old_alloc );
@@ -527,25 +515,25 @@ _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime)
527515 PyMemAllocatorEx old_alloc ;
528516 _PyMem_SetDefaultAllocator (PYMEM_DOMAIN_RAW , & old_alloc );
529517
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+ }
534528
535529 PyMem_SetAllocator (PYMEM_DOMAIN_RAW , & old_alloc );
536530
537531 /* bpo-42540: id_mutex is freed by _PyInterpreterState_Delete, which does
538532 * 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 );
540534
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 ) {
547536 return _PyStatus_ERR ("Failed to reinitialize runtime locks" );
548-
549537 }
550538
551539 PyStatus status = gilstate_tss_reinit (runtime );
0 commit comments