diff options
Diffstat (limited to 'python/sip/siplib/threads.c')
-rw-r--r-- | python/sip/siplib/threads.c | 223 |
1 files changed, 0 insertions, 223 deletions
diff --git a/python/sip/siplib/threads.c b/python/sip/siplib/threads.c deleted file mode 100644 index c4ee75ff..00000000 --- a/python/sip/siplib/threads.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Thread support for the SIP library. This module provides the hooks for - * C++ classes that provide a thread interface to interact properly with the - * Python threading infrastructure. - * - * Copyright (c) 2007 - * Riverbank Computing Limited <info@riverbankcomputing.co.uk> - * - * This file is part of SIP. - * - * This copy of SIP is licensed for use under the terms of the SIP License - * Agreement. See the file LICENSE for more details. - * - * SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - */ - - -#include "sip.h" -#include "sipint.h" - - -/* - * The data associated with pending request to wrap an object. - */ -typedef struct _pendingDef { - void *cpp; /* The C/C++ object ot be wrapped. */ - sipWrapper *owner; /* The owner of the object. */ - int flags; /* The flags. */ -} pendingDef; - - -#ifdef WITH_THREAD - -#include <pythread.h> - - -/* - * The per thread data we need to maintain. - */ -typedef struct _threadDef { - long thr_ident; /* The thread identifier. */ - pendingDef pending; /* An object waiting to be wrapped. */ - struct _threadDef *next; /* Next in the list. */ -} threadDef; - - -static threadDef *threads = NULL; /* Linked list of threads. */ - - -static threadDef *currentThreadDef(void); - -#endif - - -static pendingDef pending; /* An object waiting to be wrapped. */ - - -/* - * Get the address of any C/C++ object waiting to be wrapped. - */ -void *sipGetPending(sipWrapper **op, int *fp) -{ - pendingDef *pp; - -#ifdef WITH_THREAD - threadDef *td; - - if ((td = currentThreadDef()) != NULL) - pp = &td->pending; - else - pp = &pending; -#else - pp = &pending; -#endif - - if (pp->cpp != NULL) - { - if (op != NULL) - *op = pp->owner; - - if (fp != NULL) - *fp = pp->flags; - } - - return pp->cpp; -} - - -/* - * Convert a new C/C++ pointer to a Python instance. - */ -PyObject *sipWrapSimpleInstance(void *cppPtr, sipWrapperType *type, - sipWrapper *owner, int flags) -{ - static PyObject *nullargs = NULL; - - pendingDef old_pending; - PyObject *self; -#ifdef WITH_THREAD - threadDef *td; -#endif - - if (nullargs == NULL && (nullargs = PyTuple_New(0)) == NULL) - return NULL; - - if (cppPtr == NULL) - { - Py_INCREF(Py_None); - return Py_None; - } - - /* - * Object creation can trigger the Python garbage collector which in turn - * can execute arbitrary Python code which can then call this function - * recursively. Therefore we save any existing pending object before - * setting the new one. - */ -#ifdef WITH_THREAD - if ((td = currentThreadDef()) != NULL) - { - old_pending = td->pending; - - td->pending.cpp = cppPtr; - td->pending.owner = owner; - td->pending.flags = flags; - } - else - { - old_pending = pending; - - pending.cpp = cppPtr; - pending.owner = owner; - pending.flags = flags; - } -#else - old_pending = pending; - - pending.cpp = cppPtr; - pending.owner = owner; - pending.flags = flags; -#endif - - self = PyObject_Call((PyObject *)type, nullargs, NULL); - -#ifdef WITH_THREAD - if (td != NULL) - td->pending = old_pending; - else - pending = old_pending; -#else - pending = old_pending; -#endif - - return self; -} - - -/* - * This is called from a newly created thread to initialise some thread local - * storage. - */ -void sip_api_start_thread(void) -{ -#ifdef WITH_THREAD - threadDef *td; - - /* Save the thread ID. First, find an empty slot in the list. */ - for (td = threads; td != NULL; td = td->next) - if (td->thr_ident == 0) - break; - - if (td == NULL) - { - td = sip_api_malloc(sizeof (threadDef)); - td->next = threads; - threads = td; - } - - if (td != NULL) - { - td->thr_ident = PyThread_get_thread_ident(); - td->pending.cpp = NULL; - } -#endif -} - - -/* - * Handle the termination of a thread. The thread state should already have - * been handled by the last call to PyGILState_Release(). - */ -void sip_api_end_thread(void) -{ -#ifdef WITH_THREAD - threadDef *td; - - /* We have the GIL at this point. */ - if ((td = currentThreadDef()) != NULL) - td->thr_ident = 0; -#endif -} - - -#ifdef WITH_THREAD - -/* - * Return the thread data for the current thread or NULL if it wasn't - * recognised. - */ -static threadDef *currentThreadDef(void) -{ - threadDef *td; - long ident = PyThread_get_thread_ident(); - - for (td = threads; td != NULL; td = td->next) - if (td->thr_ident == ident) - break; - - return td; -} - -#endif |