mirror of
https://github.com/wxWidgets/Phoenix.git
synced 2025-12-16 01:30:07 +01:00
Update to sip 4.14.4
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxPython/Phoenix/trunk@73655 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
4
build.py
4
build.py
@@ -54,9 +54,9 @@ isDarwin = sys.platform == "darwin"
|
||||
|
||||
# Some tools will be downloaded for the builds. These are the versions and
|
||||
# MD5s of the tool binaries currently in use.
|
||||
sipCurrentVersion = '4.14.1'
|
||||
sipCurrentVersion = '4.14.4'
|
||||
sipMD5 = {
|
||||
'darwin' : '40854cc412e486909a289c1ffcd4e633',
|
||||
'darwin' : 'dd8d1128fc43586072206038bfa35a66',
|
||||
'win32' : 'acfd4033565c754895e658b9fa993a56',
|
||||
'linux' : '11fe8b21434d67b024ef204351877e79',
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The implementation of the supprt for setting API versions.
|
||||
*
|
||||
* Copyright (c) 2012 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
* Copyright (c) 2013 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
*
|
||||
* This file is part of SIP.
|
||||
*
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// This contains all the C++ code that is needed by the sip module.
|
||||
//
|
||||
// Copyright (c) 2012 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2013 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of SIP.
|
||||
//
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The implementation of the different descriptors.
|
||||
*
|
||||
* Copyright (c) 2012 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
* Copyright (c) 2013 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
*
|
||||
* This file is part of SIP.
|
||||
*
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This module implements a hash table class for mapping C/C++ addresses to the
|
||||
* corresponding wrapped Python object.
|
||||
*
|
||||
* Copyright (c) 2012 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
* Copyright (c) 2013 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
*
|
||||
* This file is part of SIP.
|
||||
*
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* The SIP library code that implements the interface to the optional module
|
||||
* supplied Qt support.
|
||||
*
|
||||
* Copyright (c) 2012 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
* Copyright (c) 2013 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
*
|
||||
* This file is part of SIP.
|
||||
*
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The SIP module interface.
|
||||
*
|
||||
* Copyright (c) 2012 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
* Copyright (c) 2013 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
*
|
||||
* This file is part of SIP.
|
||||
*
|
||||
@@ -54,8 +54,8 @@ extern "C" {
|
||||
/*
|
||||
* Define the SIP version number.
|
||||
*/
|
||||
#define SIP_VERSION 0x040e01
|
||||
#define SIP_VERSION_STR "4.14.1"
|
||||
#define SIP_VERSION 0x040e04
|
||||
#define SIP_VERSION_STR "4.14.4"
|
||||
|
||||
|
||||
/*
|
||||
@@ -68,6 +68,11 @@ extern "C" {
|
||||
*
|
||||
* History:
|
||||
*
|
||||
* 9.2 Added sip_gilstate_t and SIP_RELEASE_GIL to the public API.
|
||||
* Renamed sip_api_call_error_handler() to
|
||||
* sip_api_call_error_handler_old().
|
||||
* Added the new sip_api_call_error_handler() to the private API.
|
||||
*
|
||||
* 9.1 Added the capsule type.
|
||||
* Added the 'z' format character to sip_api_build_result().
|
||||
* Added the 'z', '!' and '$' format characters to
|
||||
@@ -186,7 +191,7 @@ extern "C" {
|
||||
* 0.0 Original version.
|
||||
*/
|
||||
#define SIP_API_MAJOR_NR 9
|
||||
#define SIP_API_MINOR_NR 1
|
||||
#define SIP_API_MINOR_NR 2
|
||||
|
||||
|
||||
/* The name of the sip module. */
|
||||
@@ -343,7 +348,9 @@ typedef void *(*sipCastFunc)(void *, const struct _sipTypeDef *);
|
||||
typedef const struct _sipTypeDef *(*sipSubClassConvertFunc)(void **);
|
||||
typedef int (*sipConvertToFunc)(PyObject *, void **, int *, PyObject *);
|
||||
typedef PyObject *(*sipConvertFromFunc)(void *, PyObject *);
|
||||
typedef void (*sipVirtErrorHandlerFunc)(struct _sipSimpleWrapper *);
|
||||
typedef void (*sipVirtErrorHandlerFunc)(struct _sipSimpleWrapper *,
|
||||
sip_gilstate_t);
|
||||
typedef void (*sipVirtErrorHandlerFuncOld)(struct _sipSimpleWrapper *);
|
||||
typedef int (*sipVirtHandlerFunc)(sip_gilstate_t, sipVirtErrorHandlerFunc,
|
||||
struct _sipSimpleWrapper *, PyObject *, ...);
|
||||
typedef void (*sipAssignFunc)(void *, SIP_SSIZE_T, const void *);
|
||||
@@ -1454,8 +1461,10 @@ typedef struct _sipAPIDef {
|
||||
int (*api_parse_result_ex)(sip_gilstate_t, sipVirtErrorHandlerFunc,
|
||||
sipSimpleWrapper *, PyObject *method, PyObject *res,
|
||||
const char *fmt, ...);
|
||||
void (*api_call_error_handler)(sipVirtErrorHandlerFunc,
|
||||
void (*api_call_error_handler_old)(sipVirtErrorHandlerFuncOld,
|
||||
sipSimpleWrapper *);
|
||||
void (*api_call_error_handler)(sipVirtErrorHandlerFunc,
|
||||
sipSimpleWrapper *, sip_gilstate_t);
|
||||
} sipAPIDef;
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This file defines the SIP library internal interfaces.
|
||||
*
|
||||
* Copyright (c) 2012 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
* Copyright (c) 2013 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
*
|
||||
* This file is part of SIP.
|
||||
*
|
||||
@@ -127,7 +127,8 @@ int sip_api_save_slot(sipSlot *sp, PyObject *rxObj, const char *slot);
|
||||
sipClassTypeDef *sipGetGeneratedClassType(sipEncodedTypeDef *enc,
|
||||
const sipClassTypeDef *ctd);
|
||||
void sipSaveMethod(sipPyMethod *pm,PyObject *meth);
|
||||
void *sipGetPending(sipWrapper **op, int *fp);
|
||||
int sipGetPending(void **pp, sipWrapper **op, int *fp);
|
||||
int sipIsPending();
|
||||
PyObject *sipWrapSimpleInstance(void *cppPtr, const sipTypeDef *td,
|
||||
sipWrapper *owner, int initflags);
|
||||
void *sipConvertRxEx(sipWrapper *txSelf, const char *sigargs,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* SIP library code.
|
||||
*
|
||||
* Copyright (c) 2012 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
* Copyright (c) 2013 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
*
|
||||
* This file is part of SIP.
|
||||
*
|
||||
@@ -185,7 +185,9 @@ static int sip_api_parse_result_ex(sip_gilstate_t gil_state,
|
||||
static int sip_api_parse_result(int *isErr, PyObject *method, PyObject *res,
|
||||
const char *fmt, ...);
|
||||
static void sip_api_call_error_handler(sipVirtErrorHandlerFunc error_handler,
|
||||
sipSimpleWrapper *py_self);
|
||||
sipSimpleWrapper *py_self, sip_gilstate_t gil_state);
|
||||
static void sip_api_call_error_handler_old(
|
||||
sipVirtErrorHandlerFuncOld error_handler, sipSimpleWrapper *py_self);
|
||||
static void sip_api_trace(unsigned mask,const char *fmt,...);
|
||||
static void sip_api_transfer_back(PyObject *self);
|
||||
static void sip_api_transfer_to(PyObject *self, PyObject *owner);
|
||||
@@ -370,6 +372,7 @@ static const sipAPIDef sip_api = {
|
||||
sip_api_parse_kwd_args,
|
||||
sip_api_add_exception,
|
||||
sip_api_parse_result_ex,
|
||||
sip_api_call_error_handler_old,
|
||||
sip_api_call_error_handler
|
||||
};
|
||||
|
||||
@@ -527,6 +530,7 @@ static sipSymbol *sipSymbolList = NULL; /* The list of published symbols. */
|
||||
static sipAttrGetter *sipAttrGetters = NULL; /* The list of attribute getters. */
|
||||
static sipPyObject *sipRegisteredPyTypes = NULL; /* Registered Python types. */
|
||||
static PyInterpreterState *sipInterpreter = NULL; /* The interpreter. */
|
||||
static int destroy_on_exit = TRUE; /* Destroy owned objects on exit. */
|
||||
|
||||
|
||||
static void addClassSlots(sipWrapperType *wt, sipClassTypeDef *ctd);
|
||||
@@ -620,6 +624,7 @@ static PyObject *wrapInstance(PyObject *self, PyObject *args);
|
||||
static PyObject *unwrapInstance(PyObject *self, PyObject *args);
|
||||
static PyObject *transferBack(PyObject *self, PyObject *args);
|
||||
static PyObject *transferTo(PyObject *self, PyObject *args);
|
||||
static PyObject *setDestroyOnExit(PyObject *self, PyObject *args);
|
||||
static void print_object(const char *label, PyObject *obj);
|
||||
static void addToParent(sipWrapper *self, sipWrapper *owner);
|
||||
static void removeFromParent(sipWrapper *self);
|
||||
@@ -705,6 +710,7 @@ PyMODINIT_FUNC SIP_MODULE_ENTRY(void)
|
||||
{"ispyowned", isPyOwned, METH_VARARGS, NULL},
|
||||
{"setapi", sipSetAPI, METH_VARARGS, NULL},
|
||||
{"setdeleted", setDeleted, METH_VARARGS, NULL},
|
||||
{"setdestroyonexit", setDestroyOnExit, METH_VARARGS, NULL},
|
||||
{"settracemask", setTraceMask, METH_VARARGS, NULL},
|
||||
{"transferback", transferBack, METH_VARARGS, NULL},
|
||||
{"transferto", transferTo, METH_VARARGS, NULL},
|
||||
@@ -1222,6 +1228,21 @@ static PyObject *wrapInstance(PyObject *self, PyObject *args)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set the destroy on exit flag.
|
||||
*/
|
||||
static PyObject *setDestroyOnExit(PyObject *self, PyObject *args)
|
||||
{
|
||||
if (PyArg_ParseTuple(args, "i:setdestroyonexit", &destroy_on_exit))
|
||||
{
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Register a client module. A negative value is returned and an exception
|
||||
* raised if there was an error.
|
||||
@@ -2229,20 +2250,38 @@ static int sip_api_parse_result_ex(sip_gilstate_t gil_state,
|
||||
|
||||
Py_DECREF(method);
|
||||
|
||||
SIP_RELEASE_GIL(gil_state);
|
||||
|
||||
if (rc < 0)
|
||||
sip_api_call_error_handler(error_handler, py_self);
|
||||
sip_api_call_error_handler(error_handler, py_self, gil_state);
|
||||
|
||||
SIP_RELEASE_GIL(gil_state);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Call a virtual error handler.
|
||||
* Call a virtual error handler. This is called with the GIL and from the
|
||||
* thread that raised the error.
|
||||
*/
|
||||
static void sip_api_call_error_handler(sipVirtErrorHandlerFunc error_handler,
|
||||
sipSimpleWrapper *py_self)
|
||||
sipSimpleWrapper *py_self, sip_gilstate_t sipGILState)
|
||||
{
|
||||
if (error_handler != NULL)
|
||||
error_handler(py_self, sipGILState);
|
||||
else
|
||||
PyErr_Print();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Call a virtual error handler. This is called without the GIL. This is
|
||||
* deprecated.
|
||||
*/
|
||||
#if SIP_API_MAJOR_NR != 9
|
||||
#error Remove deprecated error handler support.
|
||||
#endif
|
||||
static void sip_api_call_error_handler_old(
|
||||
sipVirtErrorHandlerFuncOld error_handler, sipSimpleWrapper *py_self)
|
||||
{
|
||||
if (error_handler != NULL)
|
||||
{
|
||||
@@ -2251,6 +2290,10 @@ static void sip_api_call_error_handler(sipVirtErrorHandlerFunc error_handler,
|
||||
else
|
||||
{
|
||||
SIP_BLOCK_THREADS
|
||||
/*
|
||||
* The current thread may not be the one that raised the exception and
|
||||
* so may not print anything. This is why this function is deprecated.
|
||||
*/
|
||||
PyErr_Print();
|
||||
SIP_UNBLOCK_THREADS
|
||||
}
|
||||
@@ -9245,7 +9288,7 @@ static PyObject *sipSimpleWrapper_new(sipWrapperType *wt, PyObject *args,
|
||||
/*
|
||||
* See if the object is being created explicitly rather than being wrapped.
|
||||
*/
|
||||
if (sipGetPending(NULL, NULL) == NULL)
|
||||
if (!sipIsPending())
|
||||
{
|
||||
/*
|
||||
* See if it cannot be instantiated or sub-classed from Python, eg.
|
||||
@@ -9314,7 +9357,10 @@ static int sipSimpleWrapper_init(sipSimpleWrapper *self, PyObject *args,
|
||||
unused = NULL;
|
||||
|
||||
/* Check there is no existing C++ instance waiting to be wrapped. */
|
||||
if ((sipNew = sipGetPending(&owner, &sipFlags)) == NULL)
|
||||
if (sipGetPending(&sipNew, &owner, &sipFlags) < 0)
|
||||
return -1;
|
||||
|
||||
if (sipNew == NULL)
|
||||
{
|
||||
PyObject *parseErr = NULL;
|
||||
|
||||
@@ -9915,17 +9961,7 @@ static int sipWrapper_clear(sipWrapper *self)
|
||||
|
||||
/* Detach children (which will be owned by C/C++). */
|
||||
while ((sw = (sipSimpleWrapper *)self->first_child) != NULL)
|
||||
{
|
||||
/*
|
||||
* Although this object is being garbage collected it doesn't follow
|
||||
* that it's children should be. So we make sure that the child stays
|
||||
* alive and remember we have done so.
|
||||
*/
|
||||
Py_INCREF(sw);
|
||||
sipSetCppHasRef(sw);
|
||||
|
||||
removeFromParent(self->first_child);
|
||||
}
|
||||
|
||||
return vret;
|
||||
}
|
||||
@@ -10364,8 +10400,6 @@ static void addTypeSlots(PyHeapTypeObject *heap_to, sipPySlotDef *slots)
|
||||
*/
|
||||
static void forgetObject(sipSimpleWrapper *sw)
|
||||
{
|
||||
const sipClassTypeDef *ctd;
|
||||
|
||||
/*
|
||||
* This is needed because we release the GIL when calling a C++ dtor.
|
||||
* Without it the cyclic garbage collector can be invoked from another
|
||||
@@ -10385,10 +10419,11 @@ static void forgetObject(sipSimpleWrapper *sw)
|
||||
*/
|
||||
sipOMRemoveObject(&cppPyMap, sw);
|
||||
|
||||
if (getPtrTypeDef(sw, &ctd) != NULL)
|
||||
if (sipInterpreter != NULL || destroy_on_exit)
|
||||
{
|
||||
/* Call the C++ dtor if there is one. */
|
||||
if (ctd->ctd_dealloc != NULL)
|
||||
const sipClassTypeDef *ctd;
|
||||
|
||||
if (getPtrTypeDef(sw, &ctd) != NULL && ctd->ctd_dealloc != NULL)
|
||||
ctd->ctd_dealloc(sw);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* C++ classes that provide a thread interface to interact properly with the
|
||||
* Python threading infrastructure.
|
||||
*
|
||||
* Copyright (c) 2012 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
* Copyright (c) 2013 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
*
|
||||
* This file is part of SIP.
|
||||
*
|
||||
@@ -47,46 +47,45 @@ typedef struct _threadDef {
|
||||
struct _threadDef *next; /* Next in the list. */
|
||||
} threadDef;
|
||||
|
||||
|
||||
static threadDef *threads = NULL; /* Linked list of threads. */
|
||||
|
||||
|
||||
static threadDef *currentThreadDef(void);
|
||||
static threadDef *currentThreadDef(int auto_alloc);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static pendingDef pending; /* An object waiting to be wrapped. */
|
||||
static pendingDef *get_pending(int auto_alloc);
|
||||
|
||||
|
||||
/*
|
||||
* Get the address of any C/C++ object waiting to be wrapped.
|
||||
* Get the address etc. of any C/C++ object waiting to be wrapped.
|
||||
*/
|
||||
void *sipGetPending(sipWrapper **op, int *fp)
|
||||
int sipGetPending(void **pp, sipWrapper **op, int *fp)
|
||||
{
|
||||
pendingDef *pp;
|
||||
pendingDef *pd;
|
||||
|
||||
#ifdef WITH_THREAD
|
||||
threadDef *thread;
|
||||
if ((pd = get_pending(TRUE)) == NULL)
|
||||
return -1;
|
||||
|
||||
if ((thread = currentThreadDef()) != NULL)
|
||||
pp = &thread->pending;
|
||||
else
|
||||
pp = &pending;
|
||||
#else
|
||||
pp = &pending;
|
||||
#endif
|
||||
*pp = pd->cpp;
|
||||
*op = pd->owner;
|
||||
*fp = pd->flags;
|
||||
|
||||
if (pp->cpp != NULL)
|
||||
{
|
||||
if (op != NULL)
|
||||
*op = pp->owner;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fp != NULL)
|
||||
*fp = pp->flags;
|
||||
}
|
||||
|
||||
return pp->cpp;
|
||||
/*
|
||||
* Return TRUE if anything is pending.
|
||||
*/
|
||||
int sipIsPending()
|
||||
{
|
||||
pendingDef *pd;
|
||||
|
||||
if ((pd = get_pending(FALSE)) == NULL)
|
||||
return FALSE;
|
||||
|
||||
return (pd->cpp != NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -98,11 +97,8 @@ PyObject *sipWrapSimpleInstance(void *cppPtr, const sipTypeDef *td,
|
||||
{
|
||||
static PyObject *nullargs = NULL;
|
||||
|
||||
pendingDef old_pending;
|
||||
pendingDef old_pending, *pd;
|
||||
PyObject *self;
|
||||
#ifdef WITH_THREAD
|
||||
threadDef *thread;
|
||||
#endif
|
||||
|
||||
if (nullargs == NULL && (nullargs = PyTuple_New(0)) == NULL)
|
||||
return NULL;
|
||||
@@ -119,41 +115,18 @@ PyObject *sipWrapSimpleInstance(void *cppPtr, const sipTypeDef *td,
|
||||
* recursively. Therefore we save any existing pending object before
|
||||
* setting the new one.
|
||||
*/
|
||||
#ifdef WITH_THREAD
|
||||
if ((thread = currentThreadDef()) != NULL)
|
||||
{
|
||||
old_pending = thread->pending;
|
||||
if ((pd = get_pending(TRUE)) == NULL)
|
||||
return NULL;
|
||||
|
||||
thread->pending.cpp = cppPtr;
|
||||
thread->pending.owner = owner;
|
||||
thread->pending.flags = flags;
|
||||
}
|
||||
else
|
||||
{
|
||||
old_pending = pending;
|
||||
old_pending = *pd;
|
||||
|
||||
pending.cpp = cppPtr;
|
||||
pending.owner = owner;
|
||||
pending.flags = flags;
|
||||
}
|
||||
#else
|
||||
old_pending = pending;
|
||||
|
||||
pending.cpp = cppPtr;
|
||||
pending.owner = owner;
|
||||
pending.flags = flags;
|
||||
#endif
|
||||
pd->cpp = cppPtr;
|
||||
pd->owner = owner;
|
||||
pd->flags = flags;
|
||||
|
||||
self = PyObject_Call((PyObject *)sipTypeAsPyTypeObject(td), nullargs, NULL);
|
||||
|
||||
#ifdef WITH_THREAD
|
||||
if (thread != NULL)
|
||||
thread->pending = old_pending;
|
||||
else
|
||||
pending = old_pending;
|
||||
#else
|
||||
pending = old_pending;
|
||||
#endif
|
||||
*pd = old_pending;
|
||||
|
||||
return self;
|
||||
}
|
||||
@@ -163,44 +136,52 @@ PyObject *sipWrapSimpleInstance(void *cppPtr, const sipTypeDef *td,
|
||||
* This is called from a newly created thread to initialise some thread local
|
||||
* storage.
|
||||
*/
|
||||
#if SIP_API_MAJOR_NR != 9
|
||||
#error Remove deprecated sip_api_start_thread().
|
||||
#endif
|
||||
void sip_api_start_thread(void)
|
||||
{
|
||||
#ifdef WITH_THREAD
|
||||
threadDef *thread;
|
||||
|
||||
/* Save the thread ID. First, find an empty slot in the list. */
|
||||
for (thread = threads; thread != NULL; thread = thread->next)
|
||||
if (thread->thr_ident == 0)
|
||||
break;
|
||||
|
||||
if (thread == NULL)
|
||||
{
|
||||
thread = sip_api_malloc(sizeof (threadDef));
|
||||
thread->next = threads;
|
||||
threads = thread;
|
||||
}
|
||||
|
||||
if (thread != NULL)
|
||||
{
|
||||
thread->thr_ident = PyThread_get_thread_ident();
|
||||
thread->pending.cpp = NULL;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* The thread local storage allocation now happens when it is needed, so
|
||||
* this is now redundant.
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Handle the termination of a thread. The thread state should already have
|
||||
* been handled by the last call to PyGILState_Release().
|
||||
* Handle the termination of a thread.
|
||||
*/
|
||||
void sip_api_end_thread(void)
|
||||
{
|
||||
#ifdef WITH_THREAD
|
||||
threadDef *thread;
|
||||
PyGILState_STATE gil = PyGILState_Ensure();
|
||||
|
||||
/* We have the GIL at this point. */
|
||||
if ((thread = currentThreadDef()) != NULL)
|
||||
if ((thread = currentThreadDef(FALSE)) != NULL)
|
||||
thread->thr_ident = 0;
|
||||
|
||||
PyGILState_Release(gil);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return the pending data for the current thread, allocating it if necessary,
|
||||
* or NULL if there was an error.
|
||||
*/
|
||||
static pendingDef *get_pending(int auto_alloc)
|
||||
{
|
||||
#ifdef WITH_THREAD
|
||||
threadDef *thread;
|
||||
|
||||
if ((thread = currentThreadDef(auto_alloc)) == NULL)
|
||||
return NULL;
|
||||
|
||||
return &thread->pending;
|
||||
#else
|
||||
static pendingDef pending;
|
||||
|
||||
return &pending;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -208,17 +189,47 @@ void sip_api_end_thread(void)
|
||||
#ifdef WITH_THREAD
|
||||
|
||||
/*
|
||||
* Return the thread data for the current thread or NULL if it wasn't
|
||||
* recognised.
|
||||
* Return the thread data for the current thread, allocating it if necessary,
|
||||
* or NULL if there was an error.
|
||||
*/
|
||||
static threadDef *currentThreadDef(void)
|
||||
static threadDef *currentThreadDef(int auto_alloc)
|
||||
{
|
||||
threadDef *thread;
|
||||
threadDef *thread, *empty = NULL;
|
||||
long ident = PyThread_get_thread_ident();
|
||||
|
||||
/* See if we already know about the thread. */
|
||||
for (thread = threads; thread != NULL; thread = thread->next)
|
||||
{
|
||||
if (thread->thr_ident == ident)
|
||||
break;
|
||||
return thread;
|
||||
|
||||
if (thread->thr_ident == 0)
|
||||
empty = thread;
|
||||
}
|
||||
|
||||
if (!auto_alloc)
|
||||
{
|
||||
/* This is not an error. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (empty != NULL)
|
||||
{
|
||||
/* Use an empty entry in the list. */
|
||||
thread = empty;
|
||||
}
|
||||
else if ((thread = sip_api_malloc(sizeof (threadDef))) == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
thread->next = threads;
|
||||
threads = thread;
|
||||
}
|
||||
|
||||
thread->thr_ident = ident;
|
||||
thread->pending.cpp = NULL;
|
||||
|
||||
return thread;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* SIP library code.
|
||||
*
|
||||
* Copyright (c) 2012 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
* Copyright (c) 2013 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
*
|
||||
* This file is part of SIP.
|
||||
*
|
||||
@@ -46,7 +46,7 @@ struct vp_values {
|
||||
static int check_size(PyObject *self);
|
||||
static int check_rw(PyObject *self);
|
||||
static int check_index(PyObject *self, SIP_SSIZE_T idx);
|
||||
#if PY_VERSION_HEX < 0x02060000
|
||||
#if PY_VERSION_HEX < 0x02060300
|
||||
static SIP_SSIZE_T get_value_data(PyObject *value, void **value_ptr);
|
||||
#endif
|
||||
#if PY_VERSION_HEX < 0x02050000
|
||||
@@ -455,7 +455,7 @@ static int sipVoidPtr_ass_subscript(PyObject *self, PyObject *key,
|
||||
{
|
||||
sipVoidPtrObject *v;
|
||||
Py_ssize_t start, size;
|
||||
#if PY_VERSION_HEX >= 0x02060000
|
||||
#if PY_VERSION_HEX >= 0x02060300
|
||||
Py_buffer value_view;
|
||||
#else
|
||||
Py_ssize_t value_size;
|
||||
@@ -502,7 +502,7 @@ static int sipVoidPtr_ass_subscript(PyObject *self, PyObject *key,
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if PY_VERSION_HEX >= 0x02060000
|
||||
#if PY_VERSION_HEX >= 0x02060300
|
||||
if (PyObject_GetBuffer(value, &value_view, PyBUF_CONTIG_RO) < 0)
|
||||
return -1;
|
||||
|
||||
@@ -548,9 +548,9 @@ static PyMappingMethods sipVoidPtr_MappingMethods = {
|
||||
#endif
|
||||
|
||||
|
||||
#if PY_VERSION_HEX >= 0x02060000
|
||||
#if PY_VERSION_HEX >= 0x02060300
|
||||
/*
|
||||
* The buffer implementation for Python v2.6 and later.
|
||||
* The buffer implementation for Python v2.6.3 and later.
|
||||
*/
|
||||
static int sipVoidPtr_getbuffer(PyObject *self, Py_buffer *buf, int flags)
|
||||
{
|
||||
@@ -639,7 +639,7 @@ static PyBufferProcs sipVoidPtr_BufferProcs = {
|
||||
sipVoidPtr_getsegcount, /* bf_getsegcount */
|
||||
#if PY_VERSION_HEX >= 0x02050000
|
||||
(charbufferproc)sipVoidPtr_getreadbuffer, /* bf_getcharbuffer */
|
||||
#if PY_VERSION_HEX >= 0x02060000
|
||||
#if PY_VERSION_HEX >= 0x02060300
|
||||
sipVoidPtr_getbuffer, /* bf_getbuffer */
|
||||
0 /* bf_releasebuffer */
|
||||
#endif
|
||||
@@ -749,27 +749,16 @@ PyTypeObject sipVoidPtr_Type = {
|
||||
*/
|
||||
void *sip_api_convert_to_void_ptr(PyObject *obj)
|
||||
{
|
||||
struct vp_values vp;
|
||||
|
||||
if (obj == NULL)
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "sip.voidptr is NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (obj == Py_None)
|
||||
return NULL;
|
||||
|
||||
if (PyObject_TypeCheck(obj, &sipVoidPtr_Type))
|
||||
return ((sipVoidPtrObject *)obj)->voidptr;
|
||||
|
||||
#if defined(SIP_USE_PYCAPSULE)
|
||||
if (PyCapsule_CheckExact(obj))
|
||||
return PyCapsule_GetPointer(obj, NULL);
|
||||
#endif
|
||||
|
||||
#if defined(SIP_SUPPORT_PYCOBJECT)
|
||||
if (PyCObject_Check(obj))
|
||||
return PyCObject_AsVoidPtr(obj);
|
||||
#endif
|
||||
if (vp_convertor(obj, &vp))
|
||||
return vp.voidptr;
|
||||
|
||||
return PyLong_AsVoidPtr(obj);
|
||||
}
|
||||
@@ -857,7 +846,7 @@ static int check_index(PyObject *self, SIP_SSIZE_T idx)
|
||||
}
|
||||
|
||||
|
||||
#if PY_VERSION_HEX < 0x02060000
|
||||
#if PY_VERSION_HEX < 0x02060300
|
||||
/*
|
||||
* Get the address and size of the data from a value that supports the buffer
|
||||
* interface.
|
||||
@@ -986,6 +975,25 @@ static int vp_convertor(PyObject *arg, struct vp_values *vp)
|
||||
size = ((sipVoidPtrObject *)arg)->size;
|
||||
rw = ((sipVoidPtrObject *)arg)->rw;
|
||||
}
|
||||
#if PY_VERSION_HEX >= 0x02060300
|
||||
else if (PyObject_CheckBuffer(arg))
|
||||
{
|
||||
Py_buffer view;
|
||||
|
||||
if (PyObject_GetBuffer(arg, &view, PyBUF_SIMPLE) < 0)
|
||||
return 0;
|
||||
|
||||
ptr = view.buf;
|
||||
size = view.len;
|
||||
rw = !view.readonly;
|
||||
}
|
||||
#endif
|
||||
#if PY_VERSION_HEX < 0x03000000
|
||||
else if (PyObject_AsReadBuffer(arg, &ptr, &size) >= 0)
|
||||
{
|
||||
rw = (Py_TYPE(arg)->tp_as_buffer->bf_getwritebuffer != NULL);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
ptr = PyLong_AsVoidPtr(arg);
|
||||
@@ -993,9 +1001,9 @@ static int vp_convertor(PyObject *arg, struct vp_values *vp)
|
||||
if (PyErr_Occurred())
|
||||
{
|
||||
#if PY_VERSION_HEX >= 0x03010000
|
||||
PyErr_SetString(PyExc_TypeError, "a single integer, CObject, None or another sip.voidptr object is required");
|
||||
PyErr_SetString(PyExc_TypeError, "a single integer, CObject, None, buffer protocol implementor or another sip.voidptr object is required");
|
||||
#else
|
||||
PyErr_SetString(PyExc_TypeError, "a single integer, Capsule, CObject, None or another sip.voidptr object is required");
|
||||
PyErr_SetString(PyExc_TypeError, "a single integer, Capsule, CObject, None, buffer protocol implementor or another sip.voidptr object is required");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user