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.
50 lines
1.4 KiB
50 lines
1.4 KiB
/*
|
|
Logic for a better replacement of PyGILState_Ensure().
|
|
|
|
This version is ready to handle the case of a non-Python-started
|
|
thread in which we do a large number of calls to CFFI callbacks. If
|
|
we were to rely on PyGILState_Ensure() for that, we would constantly
|
|
be creating and destroying PyThreadStates---it is slow, and
|
|
PyThreadState_Delete() will actually walk the list of all thread
|
|
states, making it O(n). :-(
|
|
|
|
This version only creates one PyThreadState object the first time we
|
|
see a given thread, and keep it alive until the thread is really
|
|
shut down, using a destructor on the tls key.
|
|
*/
|
|
|
|
#include <pthread.h>
|
|
#include "misc_thread_common.h"
|
|
|
|
|
|
static pthread_key_t cffi_tls_key;
|
|
|
|
static void init_cffi_tls(void)
|
|
{
|
|
if (pthread_key_create(&cffi_tls_key, &cffi_thread_shutdown) != 0)
|
|
PyErr_SetString(PyExc_OSError, "pthread_key_create() failed");
|
|
}
|
|
|
|
static struct cffi_tls_s *_make_cffi_tls(void)
|
|
{
|
|
void *p = calloc(1, sizeof(struct cffi_tls_s));
|
|
if (p == NULL)
|
|
return NULL;
|
|
if (pthread_setspecific(cffi_tls_key, p) != 0) {
|
|
free(p);
|
|
return NULL;
|
|
}
|
|
return p;
|
|
}
|
|
|
|
static struct cffi_tls_s *get_cffi_tls(void)
|
|
{
|
|
void *p = pthread_getspecific(cffi_tls_key);
|
|
if (p == NULL)
|
|
p = _make_cffi_tls();
|
|
return (struct cffi_tls_s *)p;
|
|
}
|
|
|
|
#define save_errno save_errno_only
|
|
#define restore_errno restore_errno_only
|