17db96d56Sopenharmony_ci/* 27db96d56Sopenharmony_ci * A type which wraps a semaphore 37db96d56Sopenharmony_ci * 47db96d56Sopenharmony_ci * semaphore.c 57db96d56Sopenharmony_ci * 67db96d56Sopenharmony_ci * Copyright (c) 2006-2008, R Oudkerk 77db96d56Sopenharmony_ci * Licensed to PSF under a Contributor Agreement. 87db96d56Sopenharmony_ci */ 97db96d56Sopenharmony_ci 107db96d56Sopenharmony_ci#include "multiprocessing.h" 117db96d56Sopenharmony_ci 127db96d56Sopenharmony_ci#ifdef HAVE_MP_SEMAPHORE 137db96d56Sopenharmony_ci 147db96d56Sopenharmony_cienum { RECURSIVE_MUTEX, SEMAPHORE }; 157db96d56Sopenharmony_ci 167db96d56Sopenharmony_citypedef struct { 177db96d56Sopenharmony_ci PyObject_HEAD 187db96d56Sopenharmony_ci SEM_HANDLE handle; 197db96d56Sopenharmony_ci unsigned long last_tid; 207db96d56Sopenharmony_ci int count; 217db96d56Sopenharmony_ci int maxvalue; 227db96d56Sopenharmony_ci int kind; 237db96d56Sopenharmony_ci char *name; 247db96d56Sopenharmony_ci} SemLockObject; 257db96d56Sopenharmony_ci 267db96d56Sopenharmony_ci/*[python input] 277db96d56Sopenharmony_ciclass SEM_HANDLE_converter(CConverter): 287db96d56Sopenharmony_ci type = "SEM_HANDLE" 297db96d56Sopenharmony_ci format_unit = '"F_SEM_HANDLE"' 307db96d56Sopenharmony_ci 317db96d56Sopenharmony_ci[python start generated code]*/ 327db96d56Sopenharmony_ci/*[python end generated code: output=da39a3ee5e6b4b0d input=3e0ad43e482d8716]*/ 337db96d56Sopenharmony_ci 347db96d56Sopenharmony_ci/*[clinic input] 357db96d56Sopenharmony_cimodule _multiprocessing 367db96d56Sopenharmony_ciclass _multiprocessing.SemLock "SemLockObject *" "&_PyMp_SemLockType" 377db96d56Sopenharmony_ci[clinic start generated code]*/ 387db96d56Sopenharmony_ci/*[clinic end generated code: output=da39a3ee5e6b4b0d input=935fb41b7d032599]*/ 397db96d56Sopenharmony_ci 407db96d56Sopenharmony_ci#include "clinic/semaphore.c.h" 417db96d56Sopenharmony_ci 427db96d56Sopenharmony_ci#define ISMINE(o) (o->count > 0 && PyThread_get_thread_ident() == o->last_tid) 437db96d56Sopenharmony_ci 447db96d56Sopenharmony_ci 457db96d56Sopenharmony_ci#ifdef MS_WINDOWS 467db96d56Sopenharmony_ci 477db96d56Sopenharmony_ci/* 487db96d56Sopenharmony_ci * Windows definitions 497db96d56Sopenharmony_ci */ 507db96d56Sopenharmony_ci 517db96d56Sopenharmony_ci#define SEM_FAILED NULL 527db96d56Sopenharmony_ci 537db96d56Sopenharmony_ci#define SEM_CLEAR_ERROR() SetLastError(0) 547db96d56Sopenharmony_ci#define SEM_GET_LAST_ERROR() GetLastError() 557db96d56Sopenharmony_ci#define SEM_CREATE(name, val, max) CreateSemaphore(NULL, val, max, NULL) 567db96d56Sopenharmony_ci#define SEM_CLOSE(sem) (CloseHandle(sem) ? 0 : -1) 577db96d56Sopenharmony_ci#define SEM_GETVALUE(sem, pval) _GetSemaphoreValue(sem, pval) 587db96d56Sopenharmony_ci#define SEM_UNLINK(name) 0 597db96d56Sopenharmony_ci 607db96d56Sopenharmony_cistatic int 617db96d56Sopenharmony_ci_GetSemaphoreValue(HANDLE handle, long *value) 627db96d56Sopenharmony_ci{ 637db96d56Sopenharmony_ci long previous; 647db96d56Sopenharmony_ci 657db96d56Sopenharmony_ci switch (WaitForSingleObjectEx(handle, 0, FALSE)) { 667db96d56Sopenharmony_ci case WAIT_OBJECT_0: 677db96d56Sopenharmony_ci if (!ReleaseSemaphore(handle, 1, &previous)) 687db96d56Sopenharmony_ci return MP_STANDARD_ERROR; 697db96d56Sopenharmony_ci *value = previous + 1; 707db96d56Sopenharmony_ci return 0; 717db96d56Sopenharmony_ci case WAIT_TIMEOUT: 727db96d56Sopenharmony_ci *value = 0; 737db96d56Sopenharmony_ci return 0; 747db96d56Sopenharmony_ci default: 757db96d56Sopenharmony_ci return MP_STANDARD_ERROR; 767db96d56Sopenharmony_ci } 777db96d56Sopenharmony_ci} 787db96d56Sopenharmony_ci 797db96d56Sopenharmony_ci/*[clinic input] 807db96d56Sopenharmony_ci_multiprocessing.SemLock.acquire 817db96d56Sopenharmony_ci 827db96d56Sopenharmony_ci block as blocking: bool(accept={int}) = True 837db96d56Sopenharmony_ci timeout as timeout_obj: object = None 847db96d56Sopenharmony_ci 857db96d56Sopenharmony_ciAcquire the semaphore/lock. 867db96d56Sopenharmony_ci[clinic start generated code]*/ 877db96d56Sopenharmony_ci 887db96d56Sopenharmony_cistatic PyObject * 897db96d56Sopenharmony_ci_multiprocessing_SemLock_acquire_impl(SemLockObject *self, int blocking, 907db96d56Sopenharmony_ci PyObject *timeout_obj) 917db96d56Sopenharmony_ci/*[clinic end generated code: output=f9998f0b6b0b0872 input=86f05662cf753eb4]*/ 927db96d56Sopenharmony_ci{ 937db96d56Sopenharmony_ci double timeout; 947db96d56Sopenharmony_ci DWORD res, full_msecs, nhandles; 957db96d56Sopenharmony_ci HANDLE handles[2], sigint_event; 967db96d56Sopenharmony_ci 977db96d56Sopenharmony_ci /* calculate timeout */ 987db96d56Sopenharmony_ci if (!blocking) { 997db96d56Sopenharmony_ci full_msecs = 0; 1007db96d56Sopenharmony_ci } else if (timeout_obj == Py_None) { 1017db96d56Sopenharmony_ci full_msecs = INFINITE; 1027db96d56Sopenharmony_ci } else { 1037db96d56Sopenharmony_ci timeout = PyFloat_AsDouble(timeout_obj); 1047db96d56Sopenharmony_ci if (PyErr_Occurred()) 1057db96d56Sopenharmony_ci return NULL; 1067db96d56Sopenharmony_ci timeout *= 1000.0; /* convert to millisecs */ 1077db96d56Sopenharmony_ci if (timeout < 0.0) { 1087db96d56Sopenharmony_ci timeout = 0.0; 1097db96d56Sopenharmony_ci } else if (timeout >= 0.5 * INFINITE) { /* 25 days */ 1107db96d56Sopenharmony_ci PyErr_SetString(PyExc_OverflowError, 1117db96d56Sopenharmony_ci "timeout is too large"); 1127db96d56Sopenharmony_ci return NULL; 1137db96d56Sopenharmony_ci } 1147db96d56Sopenharmony_ci full_msecs = (DWORD)(timeout + 0.5); 1157db96d56Sopenharmony_ci } 1167db96d56Sopenharmony_ci 1177db96d56Sopenharmony_ci /* check whether we already own the lock */ 1187db96d56Sopenharmony_ci if (self->kind == RECURSIVE_MUTEX && ISMINE(self)) { 1197db96d56Sopenharmony_ci ++self->count; 1207db96d56Sopenharmony_ci Py_RETURN_TRUE; 1217db96d56Sopenharmony_ci } 1227db96d56Sopenharmony_ci 1237db96d56Sopenharmony_ci /* check whether we can acquire without releasing the GIL and blocking */ 1247db96d56Sopenharmony_ci if (WaitForSingleObjectEx(self->handle, 0, FALSE) == WAIT_OBJECT_0) { 1257db96d56Sopenharmony_ci self->last_tid = GetCurrentThreadId(); 1267db96d56Sopenharmony_ci ++self->count; 1277db96d56Sopenharmony_ci Py_RETURN_TRUE; 1287db96d56Sopenharmony_ci } 1297db96d56Sopenharmony_ci 1307db96d56Sopenharmony_ci /* prepare list of handles */ 1317db96d56Sopenharmony_ci nhandles = 0; 1327db96d56Sopenharmony_ci handles[nhandles++] = self->handle; 1337db96d56Sopenharmony_ci if (_PyOS_IsMainThread()) { 1347db96d56Sopenharmony_ci sigint_event = _PyOS_SigintEvent(); 1357db96d56Sopenharmony_ci assert(sigint_event != NULL); 1367db96d56Sopenharmony_ci handles[nhandles++] = sigint_event; 1377db96d56Sopenharmony_ci } 1387db96d56Sopenharmony_ci else { 1397db96d56Sopenharmony_ci sigint_event = NULL; 1407db96d56Sopenharmony_ci } 1417db96d56Sopenharmony_ci 1427db96d56Sopenharmony_ci /* do the wait */ 1437db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 1447db96d56Sopenharmony_ci if (sigint_event != NULL) 1457db96d56Sopenharmony_ci ResetEvent(sigint_event); 1467db96d56Sopenharmony_ci res = WaitForMultipleObjectsEx(nhandles, handles, FALSE, full_msecs, FALSE); 1477db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 1487db96d56Sopenharmony_ci 1497db96d56Sopenharmony_ci /* handle result */ 1507db96d56Sopenharmony_ci switch (res) { 1517db96d56Sopenharmony_ci case WAIT_TIMEOUT: 1527db96d56Sopenharmony_ci Py_RETURN_FALSE; 1537db96d56Sopenharmony_ci case WAIT_OBJECT_0 + 0: 1547db96d56Sopenharmony_ci self->last_tid = GetCurrentThreadId(); 1557db96d56Sopenharmony_ci ++self->count; 1567db96d56Sopenharmony_ci Py_RETURN_TRUE; 1577db96d56Sopenharmony_ci case WAIT_OBJECT_0 + 1: 1587db96d56Sopenharmony_ci errno = EINTR; 1597db96d56Sopenharmony_ci return PyErr_SetFromErrno(PyExc_OSError); 1607db96d56Sopenharmony_ci case WAIT_FAILED: 1617db96d56Sopenharmony_ci return PyErr_SetFromWindowsErr(0); 1627db96d56Sopenharmony_ci default: 1637db96d56Sopenharmony_ci PyErr_Format(PyExc_RuntimeError, "WaitForSingleObject() or " 1647db96d56Sopenharmony_ci "WaitForMultipleObjects() gave unrecognized " 1657db96d56Sopenharmony_ci "value %u", res); 1667db96d56Sopenharmony_ci return NULL; 1677db96d56Sopenharmony_ci } 1687db96d56Sopenharmony_ci} 1697db96d56Sopenharmony_ci 1707db96d56Sopenharmony_ci/*[clinic input] 1717db96d56Sopenharmony_ci_multiprocessing.SemLock.release 1727db96d56Sopenharmony_ci 1737db96d56Sopenharmony_ciRelease the semaphore/lock. 1747db96d56Sopenharmony_ci[clinic start generated code]*/ 1757db96d56Sopenharmony_ci 1767db96d56Sopenharmony_cistatic PyObject * 1777db96d56Sopenharmony_ci_multiprocessing_SemLock_release_impl(SemLockObject *self) 1787db96d56Sopenharmony_ci/*[clinic end generated code: output=b22f53ba96b0d1db input=ba7e63a961885d3d]*/ 1797db96d56Sopenharmony_ci{ 1807db96d56Sopenharmony_ci if (self->kind == RECURSIVE_MUTEX) { 1817db96d56Sopenharmony_ci if (!ISMINE(self)) { 1827db96d56Sopenharmony_ci PyErr_SetString(PyExc_AssertionError, "attempt to " 1837db96d56Sopenharmony_ci "release recursive lock not owned " 1847db96d56Sopenharmony_ci "by thread"); 1857db96d56Sopenharmony_ci return NULL; 1867db96d56Sopenharmony_ci } 1877db96d56Sopenharmony_ci if (self->count > 1) { 1887db96d56Sopenharmony_ci --self->count; 1897db96d56Sopenharmony_ci Py_RETURN_NONE; 1907db96d56Sopenharmony_ci } 1917db96d56Sopenharmony_ci assert(self->count == 1); 1927db96d56Sopenharmony_ci } 1937db96d56Sopenharmony_ci 1947db96d56Sopenharmony_ci if (!ReleaseSemaphore(self->handle, 1, NULL)) { 1957db96d56Sopenharmony_ci if (GetLastError() == ERROR_TOO_MANY_POSTS) { 1967db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "semaphore or lock " 1977db96d56Sopenharmony_ci "released too many times"); 1987db96d56Sopenharmony_ci return NULL; 1997db96d56Sopenharmony_ci } else { 2007db96d56Sopenharmony_ci return PyErr_SetFromWindowsErr(0); 2017db96d56Sopenharmony_ci } 2027db96d56Sopenharmony_ci } 2037db96d56Sopenharmony_ci 2047db96d56Sopenharmony_ci --self->count; 2057db96d56Sopenharmony_ci Py_RETURN_NONE; 2067db96d56Sopenharmony_ci} 2077db96d56Sopenharmony_ci 2087db96d56Sopenharmony_ci#else /* !MS_WINDOWS */ 2097db96d56Sopenharmony_ci 2107db96d56Sopenharmony_ci/* 2117db96d56Sopenharmony_ci * Unix definitions 2127db96d56Sopenharmony_ci */ 2137db96d56Sopenharmony_ci 2147db96d56Sopenharmony_ci#define SEM_CLEAR_ERROR() 2157db96d56Sopenharmony_ci#define SEM_GET_LAST_ERROR() 0 2167db96d56Sopenharmony_ci#define SEM_CREATE(name, val, max) sem_open(name, O_CREAT | O_EXCL, 0600, val) 2177db96d56Sopenharmony_ci#define SEM_CLOSE(sem) sem_close(sem) 2187db96d56Sopenharmony_ci#define SEM_GETVALUE(sem, pval) sem_getvalue(sem, pval) 2197db96d56Sopenharmony_ci#define SEM_UNLINK(name) sem_unlink(name) 2207db96d56Sopenharmony_ci 2217db96d56Sopenharmony_ci/* OS X 10.4 defines SEM_FAILED as -1 instead of (sem_t *)-1; this gives 2227db96d56Sopenharmony_ci compiler warnings, and (potentially) undefined behaviour. */ 2237db96d56Sopenharmony_ci#ifdef __APPLE__ 2247db96d56Sopenharmony_ci# undef SEM_FAILED 2257db96d56Sopenharmony_ci# define SEM_FAILED ((sem_t *)-1) 2267db96d56Sopenharmony_ci#endif 2277db96d56Sopenharmony_ci 2287db96d56Sopenharmony_ci#ifndef HAVE_SEM_UNLINK 2297db96d56Sopenharmony_ci# define sem_unlink(name) 0 2307db96d56Sopenharmony_ci#endif 2317db96d56Sopenharmony_ci 2327db96d56Sopenharmony_ci#ifndef HAVE_SEM_TIMEDWAIT 2337db96d56Sopenharmony_ci# define sem_timedwait(sem,deadline) sem_timedwait_save(sem,deadline,_save) 2347db96d56Sopenharmony_ci 2357db96d56Sopenharmony_cistatic int 2367db96d56Sopenharmony_cisem_timedwait_save(sem_t *sem, struct timespec *deadline, PyThreadState *_save) 2377db96d56Sopenharmony_ci{ 2387db96d56Sopenharmony_ci int res; 2397db96d56Sopenharmony_ci unsigned long delay, difference; 2407db96d56Sopenharmony_ci struct timeval now, tvdeadline, tvdelay; 2417db96d56Sopenharmony_ci 2427db96d56Sopenharmony_ci errno = 0; 2437db96d56Sopenharmony_ci tvdeadline.tv_sec = deadline->tv_sec; 2447db96d56Sopenharmony_ci tvdeadline.tv_usec = deadline->tv_nsec / 1000; 2457db96d56Sopenharmony_ci 2467db96d56Sopenharmony_ci for (delay = 0 ; ; delay += 1000) { 2477db96d56Sopenharmony_ci /* poll */ 2487db96d56Sopenharmony_ci if (sem_trywait(sem) == 0) 2497db96d56Sopenharmony_ci return 0; 2507db96d56Sopenharmony_ci else if (errno != EAGAIN) 2517db96d56Sopenharmony_ci return MP_STANDARD_ERROR; 2527db96d56Sopenharmony_ci 2537db96d56Sopenharmony_ci /* get current time */ 2547db96d56Sopenharmony_ci if (gettimeofday(&now, NULL) < 0) 2557db96d56Sopenharmony_ci return MP_STANDARD_ERROR; 2567db96d56Sopenharmony_ci 2577db96d56Sopenharmony_ci /* check for timeout */ 2587db96d56Sopenharmony_ci if (tvdeadline.tv_sec < now.tv_sec || 2597db96d56Sopenharmony_ci (tvdeadline.tv_sec == now.tv_sec && 2607db96d56Sopenharmony_ci tvdeadline.tv_usec <= now.tv_usec)) { 2617db96d56Sopenharmony_ci errno = ETIMEDOUT; 2627db96d56Sopenharmony_ci return MP_STANDARD_ERROR; 2637db96d56Sopenharmony_ci } 2647db96d56Sopenharmony_ci 2657db96d56Sopenharmony_ci /* calculate how much time is left */ 2667db96d56Sopenharmony_ci difference = (tvdeadline.tv_sec - now.tv_sec) * 1000000 + 2677db96d56Sopenharmony_ci (tvdeadline.tv_usec - now.tv_usec); 2687db96d56Sopenharmony_ci 2697db96d56Sopenharmony_ci /* check delay not too long -- maximum is 20 msecs */ 2707db96d56Sopenharmony_ci if (delay > 20000) 2717db96d56Sopenharmony_ci delay = 20000; 2727db96d56Sopenharmony_ci if (delay > difference) 2737db96d56Sopenharmony_ci delay = difference; 2747db96d56Sopenharmony_ci 2757db96d56Sopenharmony_ci /* sleep */ 2767db96d56Sopenharmony_ci tvdelay.tv_sec = delay / 1000000; 2777db96d56Sopenharmony_ci tvdelay.tv_usec = delay % 1000000; 2787db96d56Sopenharmony_ci if (select(0, NULL, NULL, NULL, &tvdelay) < 0) 2797db96d56Sopenharmony_ci return MP_STANDARD_ERROR; 2807db96d56Sopenharmony_ci 2817db96d56Sopenharmony_ci /* check for signals */ 2827db96d56Sopenharmony_ci Py_BLOCK_THREADS 2837db96d56Sopenharmony_ci res = PyErr_CheckSignals(); 2847db96d56Sopenharmony_ci Py_UNBLOCK_THREADS 2857db96d56Sopenharmony_ci 2867db96d56Sopenharmony_ci if (res) { 2877db96d56Sopenharmony_ci errno = EINTR; 2887db96d56Sopenharmony_ci return MP_EXCEPTION_HAS_BEEN_SET; 2897db96d56Sopenharmony_ci } 2907db96d56Sopenharmony_ci } 2917db96d56Sopenharmony_ci} 2927db96d56Sopenharmony_ci 2937db96d56Sopenharmony_ci#endif /* !HAVE_SEM_TIMEDWAIT */ 2947db96d56Sopenharmony_ci 2957db96d56Sopenharmony_ci/*[clinic input] 2967db96d56Sopenharmony_ci_multiprocessing.SemLock.acquire 2977db96d56Sopenharmony_ci 2987db96d56Sopenharmony_ci block as blocking: bool(accept={int}) = True 2997db96d56Sopenharmony_ci timeout as timeout_obj: object = None 3007db96d56Sopenharmony_ci 3017db96d56Sopenharmony_ciAcquire the semaphore/lock. 3027db96d56Sopenharmony_ci[clinic start generated code]*/ 3037db96d56Sopenharmony_ci 3047db96d56Sopenharmony_cistatic PyObject * 3057db96d56Sopenharmony_ci_multiprocessing_SemLock_acquire_impl(SemLockObject *self, int blocking, 3067db96d56Sopenharmony_ci PyObject *timeout_obj) 3077db96d56Sopenharmony_ci/*[clinic end generated code: output=f9998f0b6b0b0872 input=86f05662cf753eb4]*/ 3087db96d56Sopenharmony_ci{ 3097db96d56Sopenharmony_ci int res, err = 0; 3107db96d56Sopenharmony_ci struct timespec deadline = {0}; 3117db96d56Sopenharmony_ci 3127db96d56Sopenharmony_ci if (self->kind == RECURSIVE_MUTEX && ISMINE(self)) { 3137db96d56Sopenharmony_ci ++self->count; 3147db96d56Sopenharmony_ci Py_RETURN_TRUE; 3157db96d56Sopenharmony_ci } 3167db96d56Sopenharmony_ci 3177db96d56Sopenharmony_ci int use_deadline = (timeout_obj != Py_None); 3187db96d56Sopenharmony_ci if (use_deadline) { 3197db96d56Sopenharmony_ci double timeout = PyFloat_AsDouble(timeout_obj); 3207db96d56Sopenharmony_ci if (PyErr_Occurred()) { 3217db96d56Sopenharmony_ci return NULL; 3227db96d56Sopenharmony_ci } 3237db96d56Sopenharmony_ci if (timeout < 0.0) { 3247db96d56Sopenharmony_ci timeout = 0.0; 3257db96d56Sopenharmony_ci } 3267db96d56Sopenharmony_ci 3277db96d56Sopenharmony_ci struct timeval now; 3287db96d56Sopenharmony_ci if (gettimeofday(&now, NULL) < 0) { 3297db96d56Sopenharmony_ci PyErr_SetFromErrno(PyExc_OSError); 3307db96d56Sopenharmony_ci return NULL; 3317db96d56Sopenharmony_ci } 3327db96d56Sopenharmony_ci long sec = (long) timeout; 3337db96d56Sopenharmony_ci long nsec = (long) (1e9 * (timeout - sec) + 0.5); 3347db96d56Sopenharmony_ci deadline.tv_sec = now.tv_sec + sec; 3357db96d56Sopenharmony_ci deadline.tv_nsec = now.tv_usec * 1000 + nsec; 3367db96d56Sopenharmony_ci deadline.tv_sec += (deadline.tv_nsec / 1000000000); 3377db96d56Sopenharmony_ci deadline.tv_nsec %= 1000000000; 3387db96d56Sopenharmony_ci } 3397db96d56Sopenharmony_ci 3407db96d56Sopenharmony_ci /* Check whether we can acquire without releasing the GIL and blocking */ 3417db96d56Sopenharmony_ci do { 3427db96d56Sopenharmony_ci res = sem_trywait(self->handle); 3437db96d56Sopenharmony_ci err = errno; 3447db96d56Sopenharmony_ci } while (res < 0 && errno == EINTR && !PyErr_CheckSignals()); 3457db96d56Sopenharmony_ci errno = err; 3467db96d56Sopenharmony_ci 3477db96d56Sopenharmony_ci if (res < 0 && errno == EAGAIN && blocking) { 3487db96d56Sopenharmony_ci /* Couldn't acquire immediately, need to block */ 3497db96d56Sopenharmony_ci do { 3507db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 3517db96d56Sopenharmony_ci if (!use_deadline) { 3527db96d56Sopenharmony_ci res = sem_wait(self->handle); 3537db96d56Sopenharmony_ci } 3547db96d56Sopenharmony_ci else { 3557db96d56Sopenharmony_ci res = sem_timedwait(self->handle, &deadline); 3567db96d56Sopenharmony_ci } 3577db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 3587db96d56Sopenharmony_ci err = errno; 3597db96d56Sopenharmony_ci if (res == MP_EXCEPTION_HAS_BEEN_SET) 3607db96d56Sopenharmony_ci break; 3617db96d56Sopenharmony_ci } while (res < 0 && errno == EINTR && !PyErr_CheckSignals()); 3627db96d56Sopenharmony_ci } 3637db96d56Sopenharmony_ci 3647db96d56Sopenharmony_ci if (res < 0) { 3657db96d56Sopenharmony_ci errno = err; 3667db96d56Sopenharmony_ci if (errno == EAGAIN || errno == ETIMEDOUT) 3677db96d56Sopenharmony_ci Py_RETURN_FALSE; 3687db96d56Sopenharmony_ci else if (errno == EINTR) 3697db96d56Sopenharmony_ci return NULL; 3707db96d56Sopenharmony_ci else 3717db96d56Sopenharmony_ci return PyErr_SetFromErrno(PyExc_OSError); 3727db96d56Sopenharmony_ci } 3737db96d56Sopenharmony_ci 3747db96d56Sopenharmony_ci ++self->count; 3757db96d56Sopenharmony_ci self->last_tid = PyThread_get_thread_ident(); 3767db96d56Sopenharmony_ci 3777db96d56Sopenharmony_ci Py_RETURN_TRUE; 3787db96d56Sopenharmony_ci} 3797db96d56Sopenharmony_ci 3807db96d56Sopenharmony_ci/*[clinic input] 3817db96d56Sopenharmony_ci_multiprocessing.SemLock.release 3827db96d56Sopenharmony_ci 3837db96d56Sopenharmony_ciRelease the semaphore/lock. 3847db96d56Sopenharmony_ci[clinic start generated code]*/ 3857db96d56Sopenharmony_ci 3867db96d56Sopenharmony_cistatic PyObject * 3877db96d56Sopenharmony_ci_multiprocessing_SemLock_release_impl(SemLockObject *self) 3887db96d56Sopenharmony_ci/*[clinic end generated code: output=b22f53ba96b0d1db input=ba7e63a961885d3d]*/ 3897db96d56Sopenharmony_ci{ 3907db96d56Sopenharmony_ci if (self->kind == RECURSIVE_MUTEX) { 3917db96d56Sopenharmony_ci if (!ISMINE(self)) { 3927db96d56Sopenharmony_ci PyErr_SetString(PyExc_AssertionError, "attempt to " 3937db96d56Sopenharmony_ci "release recursive lock not owned " 3947db96d56Sopenharmony_ci "by thread"); 3957db96d56Sopenharmony_ci return NULL; 3967db96d56Sopenharmony_ci } 3977db96d56Sopenharmony_ci if (self->count > 1) { 3987db96d56Sopenharmony_ci --self->count; 3997db96d56Sopenharmony_ci Py_RETURN_NONE; 4007db96d56Sopenharmony_ci } 4017db96d56Sopenharmony_ci assert(self->count == 1); 4027db96d56Sopenharmony_ci } else { 4037db96d56Sopenharmony_ci#ifdef HAVE_BROKEN_SEM_GETVALUE 4047db96d56Sopenharmony_ci /* We will only check properly the maxvalue == 1 case */ 4057db96d56Sopenharmony_ci if (self->maxvalue == 1) { 4067db96d56Sopenharmony_ci /* make sure that already locked */ 4077db96d56Sopenharmony_ci if (sem_trywait(self->handle) < 0) { 4087db96d56Sopenharmony_ci if (errno != EAGAIN) { 4097db96d56Sopenharmony_ci PyErr_SetFromErrno(PyExc_OSError); 4107db96d56Sopenharmony_ci return NULL; 4117db96d56Sopenharmony_ci } 4127db96d56Sopenharmony_ci /* it is already locked as expected */ 4137db96d56Sopenharmony_ci } else { 4147db96d56Sopenharmony_ci /* it was not locked so undo wait and raise */ 4157db96d56Sopenharmony_ci if (sem_post(self->handle) < 0) { 4167db96d56Sopenharmony_ci PyErr_SetFromErrno(PyExc_OSError); 4177db96d56Sopenharmony_ci return NULL; 4187db96d56Sopenharmony_ci } 4197db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "semaphore " 4207db96d56Sopenharmony_ci "or lock released too many " 4217db96d56Sopenharmony_ci "times"); 4227db96d56Sopenharmony_ci return NULL; 4237db96d56Sopenharmony_ci } 4247db96d56Sopenharmony_ci } 4257db96d56Sopenharmony_ci#else 4267db96d56Sopenharmony_ci int sval; 4277db96d56Sopenharmony_ci 4287db96d56Sopenharmony_ci /* This check is not an absolute guarantee that the semaphore 4297db96d56Sopenharmony_ci does not rise above maxvalue. */ 4307db96d56Sopenharmony_ci if (sem_getvalue(self->handle, &sval) < 0) { 4317db96d56Sopenharmony_ci return PyErr_SetFromErrno(PyExc_OSError); 4327db96d56Sopenharmony_ci } else if (sval >= self->maxvalue) { 4337db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "semaphore or lock " 4347db96d56Sopenharmony_ci "released too many times"); 4357db96d56Sopenharmony_ci return NULL; 4367db96d56Sopenharmony_ci } 4377db96d56Sopenharmony_ci#endif 4387db96d56Sopenharmony_ci } 4397db96d56Sopenharmony_ci 4407db96d56Sopenharmony_ci if (sem_post(self->handle) < 0) 4417db96d56Sopenharmony_ci return PyErr_SetFromErrno(PyExc_OSError); 4427db96d56Sopenharmony_ci 4437db96d56Sopenharmony_ci --self->count; 4447db96d56Sopenharmony_ci Py_RETURN_NONE; 4457db96d56Sopenharmony_ci} 4467db96d56Sopenharmony_ci 4477db96d56Sopenharmony_ci#endif /* !MS_WINDOWS */ 4487db96d56Sopenharmony_ci 4497db96d56Sopenharmony_ci/* 4507db96d56Sopenharmony_ci * All platforms 4517db96d56Sopenharmony_ci */ 4527db96d56Sopenharmony_ci 4537db96d56Sopenharmony_cistatic PyObject * 4547db96d56Sopenharmony_cinewsemlockobject(PyTypeObject *type, SEM_HANDLE handle, int kind, int maxvalue, 4557db96d56Sopenharmony_ci char *name) 4567db96d56Sopenharmony_ci{ 4577db96d56Sopenharmony_ci SemLockObject *self = (SemLockObject *)type->tp_alloc(type, 0); 4587db96d56Sopenharmony_ci if (!self) 4597db96d56Sopenharmony_ci return NULL; 4607db96d56Sopenharmony_ci self->handle = handle; 4617db96d56Sopenharmony_ci self->kind = kind; 4627db96d56Sopenharmony_ci self->count = 0; 4637db96d56Sopenharmony_ci self->last_tid = 0; 4647db96d56Sopenharmony_ci self->maxvalue = maxvalue; 4657db96d56Sopenharmony_ci self->name = name; 4667db96d56Sopenharmony_ci return (PyObject*)self; 4677db96d56Sopenharmony_ci} 4687db96d56Sopenharmony_ci 4697db96d56Sopenharmony_ci/*[clinic input] 4707db96d56Sopenharmony_ci@classmethod 4717db96d56Sopenharmony_ci_multiprocessing.SemLock.__new__ 4727db96d56Sopenharmony_ci 4737db96d56Sopenharmony_ci kind: int 4747db96d56Sopenharmony_ci value: int 4757db96d56Sopenharmony_ci maxvalue: int 4767db96d56Sopenharmony_ci name: str 4777db96d56Sopenharmony_ci unlink: bool(accept={int}) 4787db96d56Sopenharmony_ci 4797db96d56Sopenharmony_ci[clinic start generated code]*/ 4807db96d56Sopenharmony_ci 4817db96d56Sopenharmony_cistatic PyObject * 4827db96d56Sopenharmony_ci_multiprocessing_SemLock_impl(PyTypeObject *type, int kind, int value, 4837db96d56Sopenharmony_ci int maxvalue, const char *name, int unlink) 4847db96d56Sopenharmony_ci/*[clinic end generated code: output=30727e38f5f7577a input=b378c3ee27d3a0fa]*/ 4857db96d56Sopenharmony_ci{ 4867db96d56Sopenharmony_ci SEM_HANDLE handle = SEM_FAILED; 4877db96d56Sopenharmony_ci PyObject *result; 4887db96d56Sopenharmony_ci char *name_copy = NULL; 4897db96d56Sopenharmony_ci 4907db96d56Sopenharmony_ci if (kind != RECURSIVE_MUTEX && kind != SEMAPHORE) { 4917db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "unrecognized kind"); 4927db96d56Sopenharmony_ci return NULL; 4937db96d56Sopenharmony_ci } 4947db96d56Sopenharmony_ci 4957db96d56Sopenharmony_ci if (!unlink) { 4967db96d56Sopenharmony_ci name_copy = PyMem_Malloc(strlen(name) + 1); 4977db96d56Sopenharmony_ci if (name_copy == NULL) { 4987db96d56Sopenharmony_ci return PyErr_NoMemory(); 4997db96d56Sopenharmony_ci } 5007db96d56Sopenharmony_ci strcpy(name_copy, name); 5017db96d56Sopenharmony_ci } 5027db96d56Sopenharmony_ci 5037db96d56Sopenharmony_ci SEM_CLEAR_ERROR(); 5047db96d56Sopenharmony_ci handle = SEM_CREATE(name, value, maxvalue); 5057db96d56Sopenharmony_ci /* On Windows we should fail if GetLastError()==ERROR_ALREADY_EXISTS */ 5067db96d56Sopenharmony_ci if (handle == SEM_FAILED || SEM_GET_LAST_ERROR() != 0) 5077db96d56Sopenharmony_ci goto failure; 5087db96d56Sopenharmony_ci 5097db96d56Sopenharmony_ci if (unlink && SEM_UNLINK(name) < 0) 5107db96d56Sopenharmony_ci goto failure; 5117db96d56Sopenharmony_ci 5127db96d56Sopenharmony_ci result = newsemlockobject(type, handle, kind, maxvalue, name_copy); 5137db96d56Sopenharmony_ci if (!result) 5147db96d56Sopenharmony_ci goto failure; 5157db96d56Sopenharmony_ci 5167db96d56Sopenharmony_ci return result; 5177db96d56Sopenharmony_ci 5187db96d56Sopenharmony_ci failure: 5197db96d56Sopenharmony_ci if (handle != SEM_FAILED) 5207db96d56Sopenharmony_ci SEM_CLOSE(handle); 5217db96d56Sopenharmony_ci PyMem_Free(name_copy); 5227db96d56Sopenharmony_ci if (!PyErr_Occurred()) { 5237db96d56Sopenharmony_ci _PyMp_SetError(NULL, MP_STANDARD_ERROR); 5247db96d56Sopenharmony_ci } 5257db96d56Sopenharmony_ci return NULL; 5267db96d56Sopenharmony_ci} 5277db96d56Sopenharmony_ci 5287db96d56Sopenharmony_ci/*[clinic input] 5297db96d56Sopenharmony_ci@classmethod 5307db96d56Sopenharmony_ci_multiprocessing.SemLock._rebuild 5317db96d56Sopenharmony_ci 5327db96d56Sopenharmony_ci handle: SEM_HANDLE 5337db96d56Sopenharmony_ci kind: int 5347db96d56Sopenharmony_ci maxvalue: int 5357db96d56Sopenharmony_ci name: str(accept={str, NoneType}) 5367db96d56Sopenharmony_ci / 5377db96d56Sopenharmony_ci 5387db96d56Sopenharmony_ci[clinic start generated code]*/ 5397db96d56Sopenharmony_ci 5407db96d56Sopenharmony_cistatic PyObject * 5417db96d56Sopenharmony_ci_multiprocessing_SemLock__rebuild_impl(PyTypeObject *type, SEM_HANDLE handle, 5427db96d56Sopenharmony_ci int kind, int maxvalue, 5437db96d56Sopenharmony_ci const char *name) 5447db96d56Sopenharmony_ci/*[clinic end generated code: output=2aaee14f063f3bd9 input=f7040492ac6d9962]*/ 5457db96d56Sopenharmony_ci{ 5467db96d56Sopenharmony_ci char *name_copy = NULL; 5477db96d56Sopenharmony_ci 5487db96d56Sopenharmony_ci if (name != NULL) { 5497db96d56Sopenharmony_ci name_copy = PyMem_Malloc(strlen(name) + 1); 5507db96d56Sopenharmony_ci if (name_copy == NULL) 5517db96d56Sopenharmony_ci return PyErr_NoMemory(); 5527db96d56Sopenharmony_ci strcpy(name_copy, name); 5537db96d56Sopenharmony_ci } 5547db96d56Sopenharmony_ci 5557db96d56Sopenharmony_ci#ifndef MS_WINDOWS 5567db96d56Sopenharmony_ci if (name != NULL) { 5577db96d56Sopenharmony_ci handle = sem_open(name, 0); 5587db96d56Sopenharmony_ci if (handle == SEM_FAILED) { 5597db96d56Sopenharmony_ci PyMem_Free(name_copy); 5607db96d56Sopenharmony_ci return PyErr_SetFromErrno(PyExc_OSError); 5617db96d56Sopenharmony_ci } 5627db96d56Sopenharmony_ci } 5637db96d56Sopenharmony_ci#endif 5647db96d56Sopenharmony_ci 5657db96d56Sopenharmony_ci return newsemlockobject(type, handle, kind, maxvalue, name_copy); 5667db96d56Sopenharmony_ci} 5677db96d56Sopenharmony_ci 5687db96d56Sopenharmony_cistatic void 5697db96d56Sopenharmony_cisemlock_dealloc(SemLockObject* self) 5707db96d56Sopenharmony_ci{ 5717db96d56Sopenharmony_ci if (self->handle != SEM_FAILED) 5727db96d56Sopenharmony_ci SEM_CLOSE(self->handle); 5737db96d56Sopenharmony_ci PyMem_Free(self->name); 5747db96d56Sopenharmony_ci Py_TYPE(self)->tp_free((PyObject*)self); 5757db96d56Sopenharmony_ci} 5767db96d56Sopenharmony_ci 5777db96d56Sopenharmony_ci/*[clinic input] 5787db96d56Sopenharmony_ci_multiprocessing.SemLock._count 5797db96d56Sopenharmony_ci 5807db96d56Sopenharmony_ciNum of `acquire()`s minus num of `release()`s for this process. 5817db96d56Sopenharmony_ci[clinic start generated code]*/ 5827db96d56Sopenharmony_ci 5837db96d56Sopenharmony_cistatic PyObject * 5847db96d56Sopenharmony_ci_multiprocessing_SemLock__count_impl(SemLockObject *self) 5857db96d56Sopenharmony_ci/*[clinic end generated code: output=5ba8213900e517bb input=36fc59b1cd1025ab]*/ 5867db96d56Sopenharmony_ci{ 5877db96d56Sopenharmony_ci return PyLong_FromLong((long)self->count); 5887db96d56Sopenharmony_ci} 5897db96d56Sopenharmony_ci 5907db96d56Sopenharmony_ci/*[clinic input] 5917db96d56Sopenharmony_ci_multiprocessing.SemLock._is_mine 5927db96d56Sopenharmony_ci 5937db96d56Sopenharmony_ciWhether the lock is owned by this thread. 5947db96d56Sopenharmony_ci[clinic start generated code]*/ 5957db96d56Sopenharmony_ci 5967db96d56Sopenharmony_cistatic PyObject * 5977db96d56Sopenharmony_ci_multiprocessing_SemLock__is_mine_impl(SemLockObject *self) 5987db96d56Sopenharmony_ci/*[clinic end generated code: output=92dc98863f4303be input=a96664cb2f0093ba]*/ 5997db96d56Sopenharmony_ci{ 6007db96d56Sopenharmony_ci /* only makes sense for a lock */ 6017db96d56Sopenharmony_ci return PyBool_FromLong(ISMINE(self)); 6027db96d56Sopenharmony_ci} 6037db96d56Sopenharmony_ci 6047db96d56Sopenharmony_ci/*[clinic input] 6057db96d56Sopenharmony_ci_multiprocessing.SemLock._get_value 6067db96d56Sopenharmony_ci 6077db96d56Sopenharmony_ciGet the value of the semaphore. 6087db96d56Sopenharmony_ci[clinic start generated code]*/ 6097db96d56Sopenharmony_ci 6107db96d56Sopenharmony_cistatic PyObject * 6117db96d56Sopenharmony_ci_multiprocessing_SemLock__get_value_impl(SemLockObject *self) 6127db96d56Sopenharmony_ci/*[clinic end generated code: output=64bc1b89bda05e36 input=cb10f9a769836203]*/ 6137db96d56Sopenharmony_ci{ 6147db96d56Sopenharmony_ci#ifdef HAVE_BROKEN_SEM_GETVALUE 6157db96d56Sopenharmony_ci PyErr_SetNone(PyExc_NotImplementedError); 6167db96d56Sopenharmony_ci return NULL; 6177db96d56Sopenharmony_ci#else 6187db96d56Sopenharmony_ci int sval; 6197db96d56Sopenharmony_ci if (SEM_GETVALUE(self->handle, &sval) < 0) 6207db96d56Sopenharmony_ci return _PyMp_SetError(NULL, MP_STANDARD_ERROR); 6217db96d56Sopenharmony_ci /* some posix implementations use negative numbers to indicate 6227db96d56Sopenharmony_ci the number of waiting threads */ 6237db96d56Sopenharmony_ci if (sval < 0) 6247db96d56Sopenharmony_ci sval = 0; 6257db96d56Sopenharmony_ci return PyLong_FromLong((long)sval); 6267db96d56Sopenharmony_ci#endif 6277db96d56Sopenharmony_ci} 6287db96d56Sopenharmony_ci 6297db96d56Sopenharmony_ci/*[clinic input] 6307db96d56Sopenharmony_ci_multiprocessing.SemLock._is_zero 6317db96d56Sopenharmony_ci 6327db96d56Sopenharmony_ciReturn whether semaphore has value zero. 6337db96d56Sopenharmony_ci[clinic start generated code]*/ 6347db96d56Sopenharmony_ci 6357db96d56Sopenharmony_cistatic PyObject * 6367db96d56Sopenharmony_ci_multiprocessing_SemLock__is_zero_impl(SemLockObject *self) 6377db96d56Sopenharmony_ci/*[clinic end generated code: output=815d4c878c806ed7 input=294a446418d31347]*/ 6387db96d56Sopenharmony_ci{ 6397db96d56Sopenharmony_ci#ifdef HAVE_BROKEN_SEM_GETVALUE 6407db96d56Sopenharmony_ci if (sem_trywait(self->handle) < 0) { 6417db96d56Sopenharmony_ci if (errno == EAGAIN) 6427db96d56Sopenharmony_ci Py_RETURN_TRUE; 6437db96d56Sopenharmony_ci return _PyMp_SetError(NULL, MP_STANDARD_ERROR); 6447db96d56Sopenharmony_ci } else { 6457db96d56Sopenharmony_ci if (sem_post(self->handle) < 0) 6467db96d56Sopenharmony_ci return _PyMp_SetError(NULL, MP_STANDARD_ERROR); 6477db96d56Sopenharmony_ci Py_RETURN_FALSE; 6487db96d56Sopenharmony_ci } 6497db96d56Sopenharmony_ci#else 6507db96d56Sopenharmony_ci int sval; 6517db96d56Sopenharmony_ci if (SEM_GETVALUE(self->handle, &sval) < 0) 6527db96d56Sopenharmony_ci return _PyMp_SetError(NULL, MP_STANDARD_ERROR); 6537db96d56Sopenharmony_ci return PyBool_FromLong((long)sval == 0); 6547db96d56Sopenharmony_ci#endif 6557db96d56Sopenharmony_ci} 6567db96d56Sopenharmony_ci 6577db96d56Sopenharmony_ci/*[clinic input] 6587db96d56Sopenharmony_ci_multiprocessing.SemLock._after_fork 6597db96d56Sopenharmony_ci 6607db96d56Sopenharmony_ciRezero the net acquisition count after fork(). 6617db96d56Sopenharmony_ci[clinic start generated code]*/ 6627db96d56Sopenharmony_ci 6637db96d56Sopenharmony_cistatic PyObject * 6647db96d56Sopenharmony_ci_multiprocessing_SemLock__after_fork_impl(SemLockObject *self) 6657db96d56Sopenharmony_ci/*[clinic end generated code: output=718bb27914c6a6c1 input=190991008a76621e]*/ 6667db96d56Sopenharmony_ci{ 6677db96d56Sopenharmony_ci self->count = 0; 6687db96d56Sopenharmony_ci Py_RETURN_NONE; 6697db96d56Sopenharmony_ci} 6707db96d56Sopenharmony_ci 6717db96d56Sopenharmony_ci/*[clinic input] 6727db96d56Sopenharmony_ci_multiprocessing.SemLock.__enter__ 6737db96d56Sopenharmony_ci 6747db96d56Sopenharmony_ciEnter the semaphore/lock. 6757db96d56Sopenharmony_ci[clinic start generated code]*/ 6767db96d56Sopenharmony_ci 6777db96d56Sopenharmony_cistatic PyObject * 6787db96d56Sopenharmony_ci_multiprocessing_SemLock___enter___impl(SemLockObject *self) 6797db96d56Sopenharmony_ci/*[clinic end generated code: output=beeb2f07c858511f input=c5e27d594284690b]*/ 6807db96d56Sopenharmony_ci{ 6817db96d56Sopenharmony_ci return _multiprocessing_SemLock_acquire_impl(self, 1, Py_None); 6827db96d56Sopenharmony_ci} 6837db96d56Sopenharmony_ci 6847db96d56Sopenharmony_ci/*[clinic input] 6857db96d56Sopenharmony_ci_multiprocessing.SemLock.__exit__ 6867db96d56Sopenharmony_ci 6877db96d56Sopenharmony_ci exc_type: object = None 6887db96d56Sopenharmony_ci exc_value: object = None 6897db96d56Sopenharmony_ci exc_tb: object = None 6907db96d56Sopenharmony_ci / 6917db96d56Sopenharmony_ci 6927db96d56Sopenharmony_ciExit the semaphore/lock. 6937db96d56Sopenharmony_ci[clinic start generated code]*/ 6947db96d56Sopenharmony_ci 6957db96d56Sopenharmony_cistatic PyObject * 6967db96d56Sopenharmony_ci_multiprocessing_SemLock___exit___impl(SemLockObject *self, 6977db96d56Sopenharmony_ci PyObject *exc_type, 6987db96d56Sopenharmony_ci PyObject *exc_value, PyObject *exc_tb) 6997db96d56Sopenharmony_ci/*[clinic end generated code: output=3b37c1a9f8b91a03 input=7d644b64a89903f8]*/ 7007db96d56Sopenharmony_ci{ 7017db96d56Sopenharmony_ci return _multiprocessing_SemLock_release_impl(self); 7027db96d56Sopenharmony_ci} 7037db96d56Sopenharmony_ci 7047db96d56Sopenharmony_ci/* 7057db96d56Sopenharmony_ci * Semaphore methods 7067db96d56Sopenharmony_ci */ 7077db96d56Sopenharmony_ci 7087db96d56Sopenharmony_cistatic PyMethodDef semlock_methods[] = { 7097db96d56Sopenharmony_ci _MULTIPROCESSING_SEMLOCK_ACQUIRE_METHODDEF 7107db96d56Sopenharmony_ci _MULTIPROCESSING_SEMLOCK_RELEASE_METHODDEF 7117db96d56Sopenharmony_ci _MULTIPROCESSING_SEMLOCK___ENTER___METHODDEF 7127db96d56Sopenharmony_ci _MULTIPROCESSING_SEMLOCK___EXIT___METHODDEF 7137db96d56Sopenharmony_ci _MULTIPROCESSING_SEMLOCK__COUNT_METHODDEF 7147db96d56Sopenharmony_ci _MULTIPROCESSING_SEMLOCK__IS_MINE_METHODDEF 7157db96d56Sopenharmony_ci _MULTIPROCESSING_SEMLOCK__GET_VALUE_METHODDEF 7167db96d56Sopenharmony_ci _MULTIPROCESSING_SEMLOCK__IS_ZERO_METHODDEF 7177db96d56Sopenharmony_ci _MULTIPROCESSING_SEMLOCK__REBUILD_METHODDEF 7187db96d56Sopenharmony_ci _MULTIPROCESSING_SEMLOCK__AFTER_FORK_METHODDEF 7197db96d56Sopenharmony_ci {NULL} 7207db96d56Sopenharmony_ci}; 7217db96d56Sopenharmony_ci 7227db96d56Sopenharmony_ci/* 7237db96d56Sopenharmony_ci * Member table 7247db96d56Sopenharmony_ci */ 7257db96d56Sopenharmony_ci 7267db96d56Sopenharmony_cistatic PyMemberDef semlock_members[] = { 7277db96d56Sopenharmony_ci {"handle", T_SEM_HANDLE, offsetof(SemLockObject, handle), READONLY, 7287db96d56Sopenharmony_ci ""}, 7297db96d56Sopenharmony_ci {"kind", T_INT, offsetof(SemLockObject, kind), READONLY, 7307db96d56Sopenharmony_ci ""}, 7317db96d56Sopenharmony_ci {"maxvalue", T_INT, offsetof(SemLockObject, maxvalue), READONLY, 7327db96d56Sopenharmony_ci ""}, 7337db96d56Sopenharmony_ci {"name", T_STRING, offsetof(SemLockObject, name), READONLY, 7347db96d56Sopenharmony_ci ""}, 7357db96d56Sopenharmony_ci {NULL} 7367db96d56Sopenharmony_ci}; 7377db96d56Sopenharmony_ci 7387db96d56Sopenharmony_ci/* 7397db96d56Sopenharmony_ci * Semaphore type 7407db96d56Sopenharmony_ci */ 7417db96d56Sopenharmony_ci 7427db96d56Sopenharmony_ciPyTypeObject _PyMp_SemLockType = { 7437db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 7447db96d56Sopenharmony_ci /* tp_name */ "_multiprocessing.SemLock", 7457db96d56Sopenharmony_ci /* tp_basicsize */ sizeof(SemLockObject), 7467db96d56Sopenharmony_ci /* tp_itemsize */ 0, 7477db96d56Sopenharmony_ci /* tp_dealloc */ (destructor)semlock_dealloc, 7487db96d56Sopenharmony_ci /* tp_vectorcall_offset */ 0, 7497db96d56Sopenharmony_ci /* tp_getattr */ 0, 7507db96d56Sopenharmony_ci /* tp_setattr */ 0, 7517db96d56Sopenharmony_ci /* tp_as_async */ 0, 7527db96d56Sopenharmony_ci /* tp_repr */ 0, 7537db96d56Sopenharmony_ci /* tp_as_number */ 0, 7547db96d56Sopenharmony_ci /* tp_as_sequence */ 0, 7557db96d56Sopenharmony_ci /* tp_as_mapping */ 0, 7567db96d56Sopenharmony_ci /* tp_hash */ 0, 7577db96d56Sopenharmony_ci /* tp_call */ 0, 7587db96d56Sopenharmony_ci /* tp_str */ 0, 7597db96d56Sopenharmony_ci /* tp_getattro */ 0, 7607db96d56Sopenharmony_ci /* tp_setattro */ 0, 7617db96d56Sopenharmony_ci /* tp_as_buffer */ 0, 7627db96d56Sopenharmony_ci /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, 7637db96d56Sopenharmony_ci /* tp_doc */ "Semaphore/Mutex type", 7647db96d56Sopenharmony_ci /* tp_traverse */ 0, 7657db96d56Sopenharmony_ci /* tp_clear */ 0, 7667db96d56Sopenharmony_ci /* tp_richcompare */ 0, 7677db96d56Sopenharmony_ci /* tp_weaklistoffset */ 0, 7687db96d56Sopenharmony_ci /* tp_iter */ 0, 7697db96d56Sopenharmony_ci /* tp_iternext */ 0, 7707db96d56Sopenharmony_ci /* tp_methods */ semlock_methods, 7717db96d56Sopenharmony_ci /* tp_members */ semlock_members, 7727db96d56Sopenharmony_ci /* tp_getset */ 0, 7737db96d56Sopenharmony_ci /* tp_base */ 0, 7747db96d56Sopenharmony_ci /* tp_dict */ 0, 7757db96d56Sopenharmony_ci /* tp_descr_get */ 0, 7767db96d56Sopenharmony_ci /* tp_descr_set */ 0, 7777db96d56Sopenharmony_ci /* tp_dictoffset */ 0, 7787db96d56Sopenharmony_ci /* tp_init */ 0, 7797db96d56Sopenharmony_ci /* tp_alloc */ 0, 7807db96d56Sopenharmony_ci /* tp_new */ _multiprocessing_SemLock, 7817db96d56Sopenharmony_ci}; 7827db96d56Sopenharmony_ci 7837db96d56Sopenharmony_ci/* 7847db96d56Sopenharmony_ci * Function to unlink semaphore names 7857db96d56Sopenharmony_ci */ 7867db96d56Sopenharmony_ci 7877db96d56Sopenharmony_ciPyObject * 7887db96d56Sopenharmony_ci_PyMp_sem_unlink(const char *name) 7897db96d56Sopenharmony_ci{ 7907db96d56Sopenharmony_ci if (SEM_UNLINK(name) < 0) { 7917db96d56Sopenharmony_ci _PyMp_SetError(NULL, MP_STANDARD_ERROR); 7927db96d56Sopenharmony_ci return NULL; 7937db96d56Sopenharmony_ci } 7947db96d56Sopenharmony_ci 7957db96d56Sopenharmony_ci Py_RETURN_NONE; 7967db96d56Sopenharmony_ci} 7977db96d56Sopenharmony_ci 7987db96d56Sopenharmony_ci#endif // HAVE_MP_SEMAPHORE 799