Blame SOURCES/00306-fix-oserror-17-upon-semaphores-creation.patch

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