|
|
28b261 |
|
|
|
28b261 |
# HG changeset patch
|
|
|
28b261 |
# User Charles-François Natali <cf.natali@gmail.com>
|
|
|
28b261 |
# Date 1455316761 0
|
|
|
28b261 |
# Node ID d3662c088db8fb2c89f754031f18b1543419fed9
|
|
|
28b261 |
# Parent 5715a6d9ff12053e81f7ad75268ac059b079b351
|
|
|
28b261 |
Issue #24303: Fix random EEXIST upon multiprocessing semaphores creation with
|
|
|
28b261 |
Linux PID namespaces enabled.
|
|
|
28b261 |
|
|
|
28b261 |
diff --git a/Modules/_multiprocessing/semaphore.c b/Modules/_multiprocessing/semaphore.c
|
|
|
28b261 |
--- a/Modules/_multiprocessing/semaphore.c
|
|
|
28b261 |
+++ b/Modules/_multiprocessing/semaphore.c
|
|
|
28b261 |
@@ -429,7 +429,7 @@ semlock_new(PyTypeObject *type, PyObject
|
|
|
28b261 |
int kind, maxvalue, value;
|
|
|
28b261 |
PyObject *result;
|
|
|
28b261 |
static char *kwlist[] = {"kind", "value", "maxvalue", NULL};
|
|
|
28b261 |
- static int counter = 0;
|
|
|
28b261 |
+ int try = 0;
|
|
|
28b261 |
|
|
|
28b261 |
if (!PyArg_ParseTupleAndKeywords(args, kwds, "iii", kwlist,
|
|
|
28b261 |
&kind, &value, &maxvalue))
|
|
|
28b261 |
@@ -440,10 +440,18 @@ semlock_new(PyTypeObject *type, PyObject
|
|
|
28b261 |
return NULL;
|
|
|
28b261 |
}
|
|
|
28b261 |
|
|
|
28b261 |
- PyOS_snprintf(buffer, sizeof(buffer), "/mp%ld-%d", (long)getpid(), counter++);
|
|
|
28b261 |
+ /* Create a semaphore with a unique name. The bytes returned by
|
|
|
28b261 |
+ * _PyOS_URandom() are treated as unsigned long to ensure that the filename
|
|
|
28b261 |
+ * is valid (no special characters). */
|
|
|
28b261 |
+ do {
|
|
|
28b261 |
+ unsigned long suffix;
|
|
|
28b261 |
+ _PyOS_URandom((char *)&suffix, sizeof(suffix));
|
|
|
28b261 |
+ PyOS_snprintf(buffer, sizeof(buffer), "/mp%ld-%lu", (long)getpid(),
|
|
|
28b261 |
+ suffix);
|
|
|
28b261 |
+ SEM_CLEAR_ERROR();
|
|
|
28b261 |
+ handle = SEM_CREATE(buffer, value, maxvalue);
|
|
|
28b261 |
+ } while ((handle == SEM_FAILED) && (errno == EEXIST) && (++try < 100));
|
|
|
28b261 |
|
|
|
28b261 |
- SEM_CLEAR_ERROR();
|
|
|
28b261 |
- handle = SEM_CREATE(buffer, value, maxvalue);
|
|
|
28b261 |
/* On Windows we should fail if GetLastError()==ERROR_ALREADY_EXISTS */
|
|
|
28b261 |
if (handle == SEM_FAILED || SEM_GET_LAST_ERROR() != 0)
|
|
|
28b261 |
goto failure;
|
|
|
28b261 |
|