static PyObject * semlock_iszero(SemLockObject *self) { #ifdef HAVE_BROKEN_SEM_GETVALUE if (sem_trywait(self->handle) < 0) { if (errno == EAGAIN) Py_RETURN_TRUE; return mp_SetError(NULL, MP_STANDARD_ERROR); } else { if (sem_post(self->handle) < 0) return mp_SetError(NULL, MP_STANDARD_ERROR); Py_RETURN_FALSE; } #else int sval; if (SEM_GETVALUE(self->handle, &sval) < 0) return mp_SetError(NULL, MP_STANDARD_ERROR); return PyBool_FromLong((long)sval == 0); #endif }
static PyObject * semlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { char buffer[256]; SEM_HANDLE handle = SEM_FAILED; int kind, maxvalue, value; PyObject *result; static char *kwlist[] = {"kind", "value", "maxvalue", NULL}; int try = 0; if (!PyArg_ParseTupleAndKeywords(args, kwds, "iii", kwlist, &kind, &value, &maxvalue)) return NULL; if (kind != RECURSIVE_MUTEX && kind != SEMAPHORE) { PyErr_SetString(PyExc_ValueError, "unrecognized kind"); return NULL; } /* Create a semaphore with a unique name. The bytes returned by * _PyOS_URandom() are treated as unsigned long to ensure that the filename * is valid (no special characters). */ do { unsigned long suffix; _PyOS_URandom((char *)&suffix, sizeof(suffix)); PyOS_snprintf(buffer, sizeof(buffer), "/mp%ld-%lu", (long)getpid(), suffix); SEM_CLEAR_ERROR(); handle = SEM_CREATE(buffer, value, maxvalue); } while ((handle == SEM_FAILED) && (errno == EEXIST) && (++try < 100)); /* On Windows we should fail if GetLastError()==ERROR_ALREADY_EXISTS */ if (handle == SEM_FAILED || SEM_GET_LAST_ERROR() != 0) goto failure; if (SEM_UNLINK(buffer) < 0) goto failure; result = newsemlockobject(type, handle, kind, maxvalue); if (!result) goto failure; return result; failure: if (handle != SEM_FAILED) SEM_CLOSE(handle); mp_SetError(NULL, MP_STANDARD_ERROR); return NULL; }
static PyObject * semlock_getvalue(SemLockObject *self) { #ifdef HAVE_BROKEN_SEM_GETVALUE PyErr_SetNone(PyExc_NotImplementedError); return NULL; #else int sval; if (SEM_GETVALUE(self->handle, &sval) < 0) return mp_SetError(NULL, MP_STANDARD_ERROR); /* some posix implementations use negative numbers to indicate the number of waiting threads */ if (sval < 0) sval = 0; return PyInt_FromLong((long)sval); #endif }
static PyObject * semlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { char buffer[256]; SEM_HANDLE handle = SEM_FAILED; int kind, maxvalue, value; PyObject *result; static char *kwlist[] = {"kind", "value", "maxvalue", NULL}; static int counter = 0; if (!PyArg_ParseTupleAndKeywords(args, kwds, "iii", kwlist, &kind, &value, &maxvalue)) return NULL; if (kind != RECURSIVE_MUTEX && kind != SEMAPHORE) { PyErr_SetString(PyExc_ValueError, "unrecognized kind"); return NULL; } PyOS_snprintf(buffer, sizeof(buffer), "/mp%ld-%d", (long)getpid(), counter++); 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; if (SEM_UNLINK(buffer) < 0) goto failure; result = newsemlockobject(type, handle, kind, maxvalue); if (!result) goto failure; return result; failure: if (handle != SEM_FAILED) SEM_CLOSE(handle); mp_SetError(NULL, MP_STANDARD_ERROR); return NULL; }