@@ -390,7 +390,8 @@ shm_semlock_counters = {
390390 .shmlock_name = {0 },
391391 .handle_shmlock = (SEM_HANDLE )0 ,
392392 .header = (HeaderObject * )NULL ,
393- .counters = (CounterObject * )NULL
393+ .counters = (CounterObject * )NULL ,
394+ .max_open_sems = 0
394395};
395396
396397/*
@@ -435,12 +436,34 @@ _init_shm_names(pid_t pid)
435436 "%s%ld" , SHMLOCK_NAME , (long )pid );
436437}
437438
439+ static void
440+ _init_sem_max_from_kern_posix (int value )
441+ {
442+ shm_semlock_counters .max_open_sems = value /2 ;
443+ }
444+
438445/*
439446Public entry point called from multiprocessing_exec().
440- Builds names from getpid() and exposes them as module attributes.
447+ Builds names from getpid(), get 'kern.posix.sem.max' value and exposes them as module attributes.
441448*/
449+
442450int
443- _PyMp_init_shm_names (PyObject * module )
451+ _get_sem_max_from_kern_posix (void )
452+ {
453+ int value ;
454+ size_t len = sizeof (value );
455+
456+ if (sysctlbyname ("kern.posix.sem.max" , & value , & len , NULL , 0 ) < 0 ) {
457+ value = sysconf (_SC_SEM_NSEMS_MAX );
458+ if (value < 0 ) {
459+ return 5000 ;
460+ }
461+ }
462+ return value ;
463+ }
464+
465+ int
466+ _PyMp_init_module_constants (PyObject * module )
444467{
445468 _init_shm_names (getpid ());
446469 if (PyModule_AddStringConstant (module , "_MACOSX_SHAREDMEM_NAME" ,
@@ -449,6 +472,14 @@ _PyMp_init_shm_names(PyObject *module)
449472 if (PyModule_AddStringConstant (module , "_MACOSX_SHMLOCK_NAME" ,
450473 shm_semlock_counters .shmlock_name ) < 0 )
451474 return -1 ;
475+
476+ // A mutex is associated to each semaphore, so we could only open
477+ // value//2 MacOSX semaphores.
478+ int value = _get_sem_max_from_kern_posix ();
479+ _init_sem_max_from_kern_posix (value );
480+ if (PyModule_AddIntConstant (module , "_MACOSX_MAX_OPEN_SEMS" ,
481+ value /2 ) < 0 )
482+ return -1 ;
452483 return 0 ;
453484}
454485
@@ -716,7 +747,7 @@ create_shm_semlock_counters(const char *from_sem_name) {
716747 header = shm_semlock_counters .header ;
717748
718749 header -> size_shm = size_shm ;
719- header -> n_slots = CALC_NB_SLOTS ( size_shm - sizeof ( HeaderObject )) ;
750+ header -> n_slots = shm_semlock_counters . max_open_sems ;
720751 header -> n_semlocks = 0 ;
721752 header -> sizeof_counter = sizeof (CounterObject );
722753 res = 0 ;
@@ -799,7 +830,7 @@ _search_counter_from_sem_name(const char *sem_name)
799830 HeaderObject * header = shm_semlock_counters .header ;
800831 CounterObject * counter = shm_semlock_counters .counters ;
801832
802- for (int i = 0 , j = 0 ; i < header -> n_slots && j < header -> n_semlocks ; i ++ , counter ++ ) {
833+ for (Py_ssize_t i = 0 , j = 0 ; i < header -> n_slots && j < header -> n_semlocks ; i ++ , counter ++ ) {
803834 if (counter -> sem_name [0 ] != 0 ) {
804835 if (!PyOS_stricmp (counter -> sem_name , sem_name )) {
805836 return counter ;
@@ -819,12 +850,11 @@ _search_counter_free_slot(void)
819850 HeaderObject * header = shm_semlock_counters .header ;
820851 CounterObject * counter = shm_semlock_counters .counters ;
821852
822- for (int i = 0 ; i < header -> n_slots ; i ++ , counter ++ ) {
853+ for (Py_ssize_t i = 0 ; i < header -> n_slots ; i ++ , counter ++ ) {
823854 if (counter -> sem_name [0 ] == 0 ) {
824855 return counter ;
825856 }
826857 }
827-
828858 /*
829859 Not enough memory: see NSEMS_MAX in semaphore_macosx.h.
830860 */
@@ -1175,6 +1205,7 @@ _multiprocessing_SemLock_impl(PyTypeObject *type, int kind, int value,
11751205 SEM_HANDLE handle = SEM_FAILED ;
11761206 PyObject * result ;
11771207 char * name_copy = NULL ;
1208+ int err = 0 ;
11781209#ifdef HAVE_BROKEN_SEM_GETVALUE
11791210 char mutex_name [SIZE_MUTEX_NAME ];
11801211 SEM_HANDLE handle_mutex = SEM_FAILED ;
@@ -1252,7 +1283,10 @@ _multiprocessing_SemLock_impl(PyTypeObject *type, int kind, int value,
12521283 failure :
12531284#ifdef HAVE_BROKEN_SEM_GETVALUE
12541285 if (ISSEMAPHORE_FROM_ARGS (maxvalue , kind )) {
1286+ // Save errno before releasing the lock, as sem_post can change it
1287+ err = errno ;
12551288 RELEASE_SHMLOCK ;
1289+ errno = err ;
12561290 }
12571291 failure_shmlock :
12581292#endif /* HAVE_BROKEN_SEM_GETVALUE*/
0 commit comments