Feature or enhancement
Proposal:
It would be helpful to expose _PyCriticalSection_BeginMutex as a public API.
There are times when one does not have really have a PyObject, but still might want to use a critical section. For example, we wanted to use a critical section to protect some initialization code in a C extension module, where we wanted to write something like this:
static PyMutex mu; static PyObject* mymodule = nullptr; // It is important that we use a critical section here rather than a regular // PyMutex, say 'M', because we need to avoid the following deadlock: // * thread T1 holds M and calls ImportModule, which attempts to acquire a // critical section C. // * thread T2 holds critical section C and attempts to call this code and // acquire M. // In general, if you're going to hold a lock while calling into Python code, it had better be a critical section. PyCriticalSection cs; _PyCriticalSection_BeginMutex(&cs, &mu); if (!mymodule) { PyObject *m = PyImport_ImportModule("mymodule"); // Importing may have released the critical section, so it is possible // another thread might have populated mymodule. Make sure we clean up after // ourselves in that case. std::swap(mymodule, m); Py_XDECREF(m); } PyCriticalSection_End(&cs);
Currently one would have to write something like the following instead:
static PyObject object_for_mu; // Not really an object, we just want its mutex. static PyObject* mymodule = nullptr; PyCriticalSection cs; PyCriticalSection_Begin(&cs, &object_for_mu); if (!mymodule) { PyObject *m = PyImport_ImportModule("mymodule"); std::swap(mymodule, m); Py_XDECREF(m); } PyCriticalSection_End(&cs);
Has this already been discussed elsewhere?
This is a minor feature, which does not need previous discussion elsewhere
Links to previous discussion of this feature:
No response