You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
52 lines
1.7 KiB
52 lines
1.7 KiB
9 years ago
|
Fix for semaphores in pid namespaces
|
||
|
|
||
|
http://bugs.python.org/issue24303
|
||
|
|
||
|
--- a/Modules/_multiprocessing/semaphore.c
|
||
|
+++ b/Modules/_multiprocessing/semaphore.c
|
||
|
@@ -7,6 +7,7 @@
|
||
|
*/
|
||
|
|
||
|
#include "multiprocessing.h"
|
||
|
+#include <time.h>
|
||
|
|
||
|
enum { RECURSIVE_MUTEX, SEMAPHORE };
|
||
|
|
||
|
@@ -419,7 +420,7 @@ semlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||
|
{
|
||
|
char buffer[256];
|
||
|
SEM_HANDLE handle = SEM_FAILED;
|
||
|
- int kind, maxvalue, value;
|
||
|
+ int kind, maxvalue, value, try;
|
||
|
PyObject *result;
|
||
|
static char *kwlist[] = {"kind", "value", "maxvalue", NULL};
|
||
|
static int counter = 0;
|
||
|
@@ -433,10 +434,24 @@ semlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
- PyOS_snprintf(buffer, sizeof(buffer), "/mp%ld-%d", (long)getpid(), counter++);
|
||
|
+ /* With pid namespaces, we may have multiple processes with the same pid.
|
||
|
+ * Instead of relying on the pid to be unique, we use the microseconds time
|
||
|
+ * to attempt to a unique filename. */
|
||
|
+ for (try = 0; try < 100; ++try) {
|
||
|
+ struct timespec tv;
|
||
|
+ long arbitrary = clock_gettime(CLOCK_REALTIME, &tv) ? 0 : tv.tv_nsec;
|
||
|
+ PyOS_snprintf(buffer, sizeof(buffer), "/mp%ld-%d-%ld",
|
||
|
+ (long)getpid(),
|
||
|
+ counter++,
|
||
|
+ arbitrary);
|
||
|
+ SEM_CLEAR_ERROR();
|
||
|
+ handle = SEM_CREATE(buffer, value, maxvalue);
|
||
|
+ if (handle != SEM_FAILED)
|
||
|
+ break;
|
||
|
+ else if (errno != EEXIST)
|
||
|
+ goto failure;
|
||
|
+ }
|
||
|
|
||
|
- SEM_CLEAR_ERROR();
|
||
|
- handle = SEM_CREATE(buffer, value, maxvalue);
|
||
|
/* On Windows we should fail if GetLastError()==ERROR_ALREADY_EXISTS */
|
||
|
if (handle == SEM_FAILED || SEM_GET_LAST_ERROR() != 0)
|
||
|
goto failure;
|