~ubuntu-branches/ubuntu/maverick/python3.1/maverick

« back to all changes in this revision

Viewing changes to Modules/_ctypes/callbacks.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2009-03-23 00:01:27 UTC
  • Revision ID: james.westby@ubuntu.com-20090323000127-5fstfxju4ufrhthq
Tags: upstream-3.1~a1+20090322
ImportĀ upstreamĀ versionĀ 3.1~a1+20090322

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "Python.h"
 
2
#include "frameobject.h"
 
3
 
 
4
#include <ffi.h>
 
5
#ifdef MS_WIN32
 
6
#include <windows.h>
 
7
#endif
 
8
#include "ctypes.h"
 
9
 
 
10
/**************************************************************/
 
11
 
 
12
static void
 
13
CThunkObject_dealloc(PyObject *_self)
 
14
{
 
15
        CThunkObject *self = (CThunkObject *)_self;
 
16
        Py_XDECREF(self->converters);
 
17
        Py_XDECREF(self->callable);
 
18
        Py_XDECREF(self->restype);
 
19
        if (self->pcl)
 
20
                FreeClosure(self->pcl);
 
21
        PyObject_Del(self);
 
22
}
 
23
 
 
24
static int
 
25
CThunkObject_traverse(PyObject *_self, visitproc visit, void *arg)
 
26
{
 
27
        CThunkObject *self = (CThunkObject *)_self;
 
28
        Py_VISIT(self->converters);
 
29
        Py_VISIT(self->callable);
 
30
        Py_VISIT(self->restype);
 
31
        return 0;
 
32
}
 
33
 
 
34
static int
 
35
CThunkObject_clear(PyObject *_self)
 
36
{
 
37
        CThunkObject *self = (CThunkObject *)_self;
 
38
        Py_CLEAR(self->converters);
 
39
        Py_CLEAR(self->callable);
 
40
        Py_CLEAR(self->restype);
 
41
        return 0;
 
42
}
 
43
 
 
44
PyTypeObject CThunk_Type = {
 
45
        PyVarObject_HEAD_INIT(NULL, 0)
 
46
        "_ctypes.CThunkObject",
 
47
        sizeof(CThunkObject),                   /* tp_basicsize */
 
48
        sizeof(ffi_type),                       /* tp_itemsize */
 
49
        CThunkObject_dealloc,                   /* tp_dealloc */
 
50
        0,                                      /* tp_print */
 
51
        0,                                      /* tp_getattr */
 
52
        0,                                      /* tp_setattr */
 
53
        0,                                      /* tp_reserved */
 
54
        0,                                      /* tp_repr */
 
55
        0,                                      /* tp_as_number */
 
56
        0,                                      /* tp_as_sequence */
 
57
        0,                                      /* tp_as_mapping */
 
58
        0,                                      /* tp_hash */
 
59
        0,                                      /* tp_call */
 
60
        0,                                      /* tp_str */
 
61
        0,                                      /* tp_getattro */
 
62
        0,                                      /* tp_setattro */
 
63
        0,                                      /* tp_as_buffer */
 
64
        Py_TPFLAGS_DEFAULT,                     /* tp_flags */
 
65
        "CThunkObject",                         /* tp_doc */
 
66
        CThunkObject_traverse,                  /* tp_traverse */
 
67
        CThunkObject_clear,                     /* tp_clear */
 
68
        0,                                      /* tp_richcompare */
 
69
        0,                                      /* tp_weaklistoffset */
 
70
        0,                                      /* tp_iter */
 
71
        0,                                      /* tp_iternext */
 
72
        0,                                      /* tp_methods */
 
73
        0,                                      /* tp_members */
 
74
};
 
75
 
 
76
/**************************************************************/
 
77
 
 
78
static void
 
79
PrintError(char *msg, ...)
 
80
{
 
81
        char buf[512];
 
82
        PyObject *f = PySys_GetObject("stderr");
 
83
        va_list marker;
 
84
 
 
85
        va_start(marker, msg);
 
86
        vsnprintf(buf, sizeof(buf), msg, marker);
 
87
        va_end(marker);
 
88
        if (f != NULL && f != Py_None)
 
89
                PyFile_WriteString(buf, f);
 
90
        PyErr_Print();
 
91
}
 
92
 
 
93
 
 
94
/* after code that pyrex generates */
 
95
void _AddTraceback(char *funcname, char *filename, int lineno)
 
96
{
 
97
        PyObject *py_srcfile = 0;
 
98
        PyObject *py_funcname = 0;
 
99
        PyObject *py_globals = 0;
 
100
        PyObject *empty_tuple = 0;
 
101
        PyObject *empty_string = 0;
 
102
        PyCodeObject *py_code = 0;
 
103
        PyFrameObject *py_frame = 0;
 
104
    
 
105
        py_srcfile = PyUnicode_DecodeFSDefault(filename);
 
106
        if (!py_srcfile) goto bad;
 
107
        py_funcname = PyUnicode_FromString(funcname);
 
108
        if (!py_funcname) goto bad;
 
109
        py_globals = PyDict_New();
 
110
        if (!py_globals) goto bad;
 
111
        empty_tuple = PyTuple_New(0);
 
112
        if (!empty_tuple) goto bad;
 
113
        empty_string = PyBytes_FromString("");
 
114
        if (!empty_string) goto bad;
 
115
        py_code = PyCode_New(
 
116
                0,            /*int argcount,*/
 
117
                0,            /*int kwonlyargcount,*/
 
118
                0,            /*int nlocals,*/
 
119
                0,            /*int stacksize,*/
 
120
                0,            /*int flags,*/
 
121
                empty_string, /*PyObject *code,*/
 
122
                empty_tuple,  /*PyObject *consts,*/
 
123
                empty_tuple,  /*PyObject *names,*/
 
124
                empty_tuple,  /*PyObject *varnames,*/
 
125
                empty_tuple,  /*PyObject *freevars,*/
 
126
                empty_tuple,  /*PyObject *cellvars,*/
 
127
                py_srcfile,   /*PyObject *filename,*/
 
128
                py_funcname,  /*PyObject *name,*/
 
129
                lineno,   /*int firstlineno,*/
 
130
                empty_string  /*PyObject *lnotab*/
 
131
                );
 
132
        if (!py_code) goto bad;
 
133
        py_frame = PyFrame_New(
 
134
                PyThreadState_Get(), /*PyThreadState *tstate,*/
 
135
                py_code,             /*PyCodeObject *code,*/
 
136
                py_globals,          /*PyObject *globals,*/
 
137
                0                    /*PyObject *locals*/
 
138
                );
 
139
        if (!py_frame) goto bad;
 
140
        py_frame->f_lineno = lineno;
 
141
        PyTraceBack_Here(py_frame);
 
142
  bad:
 
143
        Py_XDECREF(py_globals);
 
144
        Py_XDECREF(py_srcfile);
 
145
        Py_XDECREF(py_funcname);
 
146
        Py_XDECREF(empty_tuple);
 
147
        Py_XDECREF(empty_string);
 
148
        Py_XDECREF(py_code);
 
149
        Py_XDECREF(py_frame);
 
150
}
 
151
 
 
152
#ifdef MS_WIN32
 
153
/*
 
154
 * We must call AddRef() on non-NULL COM pointers we receive as arguments
 
155
 * to callback functions - these functions are COM method implementations.
 
156
 * The Python instances we create have a __del__ method which calls Release().
 
157
 *
 
158
 * The presence of a class attribute named '_needs_com_addref_' triggers this
 
159
 * behaviour.  It would also be possible to call the AddRef() Python method,
 
160
 * after checking for PyObject_IsTrue(), but this would probably be somewhat
 
161
 * slower.
 
162
 */
 
163
static void
 
164
TryAddRef(StgDictObject *dict, CDataObject *obj)
 
165
{
 
166
        IUnknown *punk;
 
167
 
 
168
        if (NULL == PyDict_GetItemString((PyObject *)dict, "_needs_com_addref_"))
 
169
                return;
 
170
 
 
171
        punk = *(IUnknown **)obj->b_ptr;
 
172
        if (punk)
 
173
                punk->lpVtbl->AddRef(punk);
 
174
        return;
 
175
}
 
176
#endif
 
177
 
 
178
/******************************************************************************
 
179
 *
 
180
 * Call the python object with all arguments
 
181
 *
 
182
 */
 
183
static void _CallPythonObject(void *mem,
 
184
                              ffi_type *restype,
 
185
                              SETFUNC setfunc,
 
186
                              PyObject *callable,
 
187
                              PyObject *converters,
 
188
                              int flags,
 
189
                              void **pArgs)
 
190
{
 
191
        Py_ssize_t i;
 
192
        PyObject *result;
 
193
        PyObject *arglist = NULL;
 
194
        Py_ssize_t nArgs;
 
195
        PyObject *error_object = NULL;
 
196
        int *space;
 
197
#ifdef WITH_THREAD
 
198
        PyGILState_STATE state = PyGILState_Ensure();
 
199
#endif
 
200
 
 
201
        nArgs = PySequence_Length(converters);
 
202
        /* Hm. What to return in case of error?
 
203
           For COM, 0xFFFFFFFF seems better than 0.
 
204
        */
 
205
        if (nArgs < 0) {
 
206
                PrintError("BUG: PySequence_Length");
 
207
                goto Done;
 
208
        }
 
209
 
 
210
        arglist = PyTuple_New(nArgs);
 
211
        if (!arglist) {
 
212
                PrintError("PyTuple_New()");
 
213
                goto Done;
 
214
        }
 
215
        for (i = 0; i < nArgs; ++i) {
 
216
                /* Note: new reference! */
 
217
                PyObject *cnv = PySequence_GetItem(converters, i);
 
218
                StgDictObject *dict;
 
219
                if (cnv)
 
220
                        dict = PyType_stgdict(cnv);
 
221
                else {
 
222
                        PrintError("Getting argument converter %d\n", i);
 
223
                        goto Done;
 
224
                }
 
225
 
 
226
                if (dict && dict->getfunc && !IsSimpleSubType(cnv)) {
 
227
                        PyObject *v = dict->getfunc(*pArgs, dict->size);
 
228
                        if (!v) {
 
229
                                PrintError("create argument %d:\n", i);
 
230
                                Py_DECREF(cnv);
 
231
                                goto Done;
 
232
                        }
 
233
                        PyTuple_SET_ITEM(arglist, i, v);
 
234
                        /* XXX XXX XX
 
235
                           We have the problem that c_byte or c_short have dict->size of
 
236
                           1 resp. 4, but these parameters are pushed as sizeof(int) bytes.
 
237
                           BTW, the same problem occurrs when they are pushed as parameters
 
238
                        */
 
239
                } else if (dict) {
 
240
                        /* Hm, shouldn't we use CData_AtAddress() or something like that instead? */
 
241
                        CDataObject *obj = (CDataObject *)PyObject_CallFunctionObjArgs(cnv, NULL);
 
242
                        if (!obj) {
 
243
                                PrintError("create argument %d:\n", i);
 
244
                                Py_DECREF(cnv);
 
245
                                goto Done;
 
246
                        }
 
247
                        if (!CDataObject_Check(obj)) {
 
248
                                Py_DECREF(obj);
 
249
                                Py_DECREF(cnv);
 
250
                                PrintError("unexpected result of create argument %d:\n", i);
 
251
                                goto Done;
 
252
                        }
 
253
                        memcpy(obj->b_ptr, *pArgs, dict->size);
 
254
                        PyTuple_SET_ITEM(arglist, i, (PyObject *)obj);
 
255
#ifdef MS_WIN32
 
256
                        TryAddRef(dict, obj);
 
257
#endif
 
258
                } else {
 
259
                        PyErr_SetString(PyExc_TypeError,
 
260
                                        "cannot build parameter");
 
261
                        PrintError("Parsing argument %d\n", i);
 
262
                        Py_DECREF(cnv);
 
263
                        goto Done;
 
264
                }
 
265
                Py_DECREF(cnv);
 
266
                /* XXX error handling! */
 
267
                pArgs++;
 
268
        }
 
269
 
 
270
#define CHECK(what, x) \
 
271
if (x == NULL) _AddTraceback(what, "_ctypes/callbacks.c", __LINE__ - 1), PyErr_Print()
 
272
 
 
273
        if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)) {
 
274
                error_object = get_error_object(&space);
 
275
                if (error_object == NULL)
 
276
                        goto Done;
 
277
                if (flags & FUNCFLAG_USE_ERRNO) {
 
278
                        int temp = space[0];
 
279
                        space[0] = errno;
 
280
                        errno = temp;
 
281
                }
 
282
#ifdef MS_WIN32
 
283
                if (flags & FUNCFLAG_USE_LASTERROR) {
 
284
                        int temp = space[1];
 
285
                        space[1] = GetLastError();
 
286
                        SetLastError(temp);
 
287
                }
 
288
#endif
 
289
        }
 
290
 
 
291
        result = PyObject_CallObject(callable, arglist);
 
292
        CHECK("'calling callback function'", result);
 
293
 
 
294
#ifdef MS_WIN32
 
295
        if (flags & FUNCFLAG_USE_LASTERROR) {
 
296
                int temp = space[1];
 
297
                space[1] = GetLastError();
 
298
                SetLastError(temp);
 
299
        }
 
300
#endif
 
301
        if (flags & FUNCFLAG_USE_ERRNO) {
 
302
                int temp = space[0];
 
303
                space[0] = errno;
 
304
                errno = temp;
 
305
        }
 
306
        Py_XDECREF(error_object);
 
307
 
 
308
        if ((restype != &ffi_type_void) && result) {
 
309
                PyObject *keep;
 
310
                assert(setfunc);
 
311
#ifdef WORDS_BIGENDIAN
 
312
                /* See the corresponding code in callproc.c, around line 961 */
 
313
                if (restype->type != FFI_TYPE_FLOAT && restype->size < sizeof(ffi_arg))
 
314
                        mem = (char *)mem + sizeof(ffi_arg) - restype->size;
 
315
#endif
 
316
                keep = setfunc(mem, result, 0);
 
317
                CHECK("'converting callback result'", keep);
 
318
                /* keep is an object we have to keep alive so that the result
 
319
                   stays valid.  If there is no such object, the setfunc will
 
320
                   have returned Py_None.
 
321
 
 
322
                   If there is such an object, we have no choice than to keep
 
323
                   it alive forever - but a refcount and/or memory leak will
 
324
                   be the result.  EXCEPT when restype is py_object - Python
 
325
                   itself knows how to manage the refcount of these objects.
 
326
                */
 
327
                if (keep == NULL) /* Could not convert callback result. */
 
328
                        PyErr_WriteUnraisable(callable);
 
329
                else if (keep == Py_None) /* Nothing to keep */
 
330
                        Py_DECREF(keep);
 
331
                else if (setfunc != getentry("O")->setfunc) {
 
332
                        if (-1 == PyErr_WarnEx(PyExc_RuntimeWarning,
 
333
                                               "memory leak in callback function.",
 
334
                                               1))
 
335
                                PyErr_WriteUnraisable(callable);
 
336
                }
 
337
        }
 
338
        Py_XDECREF(result);
 
339
  Done:
 
340
        Py_XDECREF(arglist);
 
341
#ifdef WITH_THREAD
 
342
        PyGILState_Release(state);
 
343
#endif
 
344
}
 
345
 
 
346
static void closure_fcn(ffi_cif *cif,
 
347
                        void *resp,
 
348
                        void **args,
 
349
                        void *userdata)
 
350
{
 
351
        CThunkObject *p = (CThunkObject *)userdata;
 
352
 
 
353
        _CallPythonObject(resp,
 
354
                          p->ffi_restype,
 
355
                          p->setfunc,
 
356
                          p->callable,
 
357
                          p->converters,
 
358
                          p->flags,
 
359
                          args);
 
360
}
 
361
 
 
362
static CThunkObject* CThunkObject_new(Py_ssize_t nArgs)
 
363
{
 
364
        CThunkObject *p;
 
365
        int i;
 
366
 
 
367
        p = PyObject_NewVar(CThunkObject, &CThunk_Type, nArgs);
 
368
        if (p == NULL) {
 
369
                PyErr_NoMemory();
 
370
                return NULL;
 
371
        }
 
372
 
 
373
        p->pcl = NULL;
 
374
        memset(&p->cif, 0, sizeof(p->cif));
 
375
        p->converters = NULL;
 
376
        p->callable = NULL;
 
377
        p->setfunc = NULL;
 
378
        p->ffi_restype = NULL;
 
379
        
 
380
        for (i = 0; i < nArgs + 1; ++i)
 
381
                p->atypes[i] = NULL;
 
382
        return p;
 
383
}
 
384
 
 
385
CThunkObject *AllocFunctionCallback(PyObject *callable,
 
386
                                    PyObject *converters,
 
387
                                    PyObject *restype,
 
388
                                    int flags)
 
389
{
 
390
        int result;
 
391
        CThunkObject *p;
 
392
        Py_ssize_t nArgs, i;
 
393
        ffi_abi cc;
 
394
 
 
395
        nArgs = PySequence_Size(converters);
 
396
        p = CThunkObject_new(nArgs);
 
397
        if (p == NULL)
 
398
                return NULL;
 
399
 
 
400
        assert(CThunk_CheckExact((PyObject *)p));
 
401
 
 
402
        p->pcl = MallocClosure();
 
403
        if (p->pcl == NULL) {
 
404
                PyErr_NoMemory();
 
405
                goto error;
 
406
        }
 
407
 
 
408
        p->flags = flags;
 
409
        for (i = 0; i < nArgs; ++i) {
 
410
                PyObject *cnv = PySequence_GetItem(converters, i);
 
411
                if (cnv == NULL)
 
412
                        goto error;
 
413
                p->atypes[i] = GetType(cnv);
 
414
                Py_DECREF(cnv);
 
415
        }
 
416
        p->atypes[i] = NULL;
 
417
 
 
418
        Py_INCREF(restype);
 
419
        p->restype = restype;
 
420
        if (restype == Py_None) {
 
421
                p->setfunc = NULL;
 
422
                p->ffi_restype = &ffi_type_void;
 
423
        } else {
 
424
                StgDictObject *dict = PyType_stgdict(restype);
 
425
                if (dict == NULL || dict->setfunc == NULL) {
 
426
                  PyErr_SetString(PyExc_TypeError,
 
427
                                  "invalid result type for callback function");
 
428
                  goto error;
 
429
                }
 
430
                p->setfunc = dict->setfunc;
 
431
                p->ffi_restype = &dict->ffi_type_pointer;
 
432
        }
 
433
 
 
434
        cc = FFI_DEFAULT_ABI;
 
435
#if defined(MS_WIN32) && !defined(_WIN32_WCE) && !defined(MS_WIN64)
 
436
        if ((flags & FUNCFLAG_CDECL) == 0)
 
437
                cc = FFI_STDCALL;
 
438
#endif
 
439
        result = ffi_prep_cif(&p->cif, cc,
 
440
                              Py_SAFE_DOWNCAST(nArgs, Py_ssize_t, int),
 
441
                              GetType(restype),
 
442
                              &p->atypes[0]);
 
443
        if (result != FFI_OK) {
 
444
                PyErr_Format(PyExc_RuntimeError,
 
445
                             "ffi_prep_cif failed with %d", result);
 
446
                goto error;
 
447
        }
 
448
        result = ffi_prep_closure(p->pcl, &p->cif, closure_fcn, p);
 
449
        if (result != FFI_OK) {
 
450
                PyErr_Format(PyExc_RuntimeError,
 
451
                             "ffi_prep_closure failed with %d", result);
 
452
                goto error;
 
453
        }
 
454
 
 
455
        Py_INCREF(converters);
 
456
        p->converters = converters;
 
457
        Py_INCREF(callable);
 
458
        p->callable = callable;
 
459
        return p;
 
460
 
 
461
  error:
 
462
        Py_XDECREF(p);
 
463
        return NULL;
 
464
}
 
465
 
 
466
/****************************************************************************
 
467
 *
 
468
 * callback objects: initialization
 
469
 */
 
470
 
 
471
void init_callbacks_in_module(PyObject *m)
 
472
{
 
473
        if (PyType_Ready((PyTypeObject *)&PyType_Type) < 0)
 
474
                return;
 
475
}
 
476
 
 
477
#ifdef MS_WIN32
 
478
 
 
479
static void LoadPython(void)
 
480
{
 
481
        if (!Py_IsInitialized()) {
 
482
#ifdef WITH_THREAD
 
483
                PyEval_InitThreads();
 
484
#endif
 
485
                Py_Initialize();
 
486
        }
 
487
}
 
488
 
 
489
/******************************************************************/
 
490
 
 
491
long Call_GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
 
492
{
 
493
        PyObject *mod, *func, *result;
 
494
        long retval;
 
495
        static PyObject *context;
 
496
 
 
497
        if (context == NULL)
 
498
                context = PyUnicode_InternFromString("_ctypes.DllGetClassObject");
 
499
 
 
500
        mod = PyImport_ImportModuleNoBlock("ctypes");
 
501
        if (!mod) {
 
502
                PyErr_WriteUnraisable(context ? context : Py_None);
 
503
                /* There has been a warning before about this already */
 
504
                return E_FAIL;
 
505
        }
 
506
 
 
507
        func = PyObject_GetAttrString(mod, "DllGetClassObject");
 
508
        Py_DECREF(mod);
 
509
        if (!func) {
 
510
                PyErr_WriteUnraisable(context ? context : Py_None);
 
511
                return E_FAIL;
 
512
        }
 
513
 
 
514
        {
 
515
                PyObject *py_rclsid = PyLong_FromVoidPtr((void *)rclsid);
 
516
                PyObject *py_riid = PyLong_FromVoidPtr((void *)riid);
 
517
                PyObject *py_ppv = PyLong_FromVoidPtr(ppv);
 
518
                if (!py_rclsid || !py_riid || !py_ppv) {
 
519
                        Py_XDECREF(py_rclsid);
 
520
                        Py_XDECREF(py_riid);
 
521
                        Py_XDECREF(py_ppv);
 
522
                        Py_DECREF(func);
 
523
                        PyErr_WriteUnraisable(context ? context : Py_None);
 
524
                        return E_FAIL;
 
525
                }
 
526
                result = PyObject_CallFunctionObjArgs(func,
 
527
                                                      py_rclsid,
 
528
                                                      py_riid,
 
529
                                                      py_ppv,
 
530
                                                      NULL);
 
531
                Py_DECREF(py_rclsid);
 
532
                Py_DECREF(py_riid);
 
533
                Py_DECREF(py_ppv);
 
534
        }
 
535
        Py_DECREF(func);
 
536
        if (!result) {
 
537
                PyErr_WriteUnraisable(context ? context : Py_None);
 
538
                return E_FAIL;
 
539
        }
 
540
 
 
541
        retval = PyLong_AsLong(result);
 
542
        if (PyErr_Occurred()) {
 
543
                PyErr_WriteUnraisable(context ? context : Py_None);
 
544
                retval = E_FAIL;
 
545
        }
 
546
        Py_DECREF(result);
 
547
        return retval;
 
548
}
 
549
 
 
550
STDAPI DllGetClassObject(REFCLSID rclsid,
 
551
                         REFIID riid,
 
552
                         LPVOID *ppv)
 
553
{
 
554
        long result;
 
555
#ifdef WITH_THREAD
 
556
        PyGILState_STATE state;
 
557
#endif
 
558
 
 
559
        LoadPython();
 
560
#ifdef WITH_THREAD
 
561
        state = PyGILState_Ensure();
 
562
#endif
 
563
        result = Call_GetClassObject(rclsid, riid, ppv);
 
564
#ifdef WITH_THREAD
 
565
        PyGILState_Release(state);
 
566
#endif
 
567
        return result;
 
568
}
 
569
 
 
570
long Call_CanUnloadNow(void)
 
571
{
 
572
        PyObject *mod, *func, *result;
 
573
        long retval;
 
574
        static PyObject *context;
 
575
 
 
576
        if (context == NULL)
 
577
                context = PyUnicode_InternFromString("_ctypes.DllCanUnloadNow");
 
578
 
 
579
        mod = PyImport_ImportModuleNoBlock("ctypes");
 
580
        if (!mod) {
 
581
/*              OutputDebugString("Could not import ctypes"); */
 
582
                /* We assume that this error can only occur when shutting
 
583
                   down, so we silently ignore it */
 
584
                PyErr_Clear();
 
585
                return E_FAIL;
 
586
        }
 
587
        /* Other errors cannot be raised, but are printed to stderr */
 
588
        func = PyObject_GetAttrString(mod, "DllCanUnloadNow");
 
589
        Py_DECREF(mod);
 
590
        if (!func) {
 
591
                PyErr_WriteUnraisable(context ? context : Py_None);
 
592
                return E_FAIL;
 
593
        }
 
594
 
 
595
        result = PyObject_CallFunction(func, NULL);
 
596
        Py_DECREF(func);
 
597
        if (!result) {
 
598
                PyErr_WriteUnraisable(context ? context : Py_None);
 
599
                return E_FAIL;
 
600
        }
 
601
 
 
602
        retval = PyLong_AsLong(result);
 
603
        if (PyErr_Occurred()) {
 
604
                PyErr_WriteUnraisable(context ? context : Py_None);
 
605
                retval = E_FAIL;
 
606
        }
 
607
        Py_DECREF(result);
 
608
        return retval;
 
609
}
 
610
 
 
611
/*
 
612
  DllRegisterServer and DllUnregisterServer still missing
 
613
*/
 
614
 
 
615
STDAPI DllCanUnloadNow(void)
 
616
{
 
617
        long result;
 
618
#ifdef WITH_THREAD
 
619
        PyGILState_STATE state = PyGILState_Ensure();
 
620
#endif
 
621
        result = Call_CanUnloadNow();
 
622
#ifdef WITH_THREAD
 
623
        PyGILState_Release(state);
 
624
#endif
 
625
        return result;
 
626
}
 
627
 
 
628
#ifndef Py_NO_ENABLE_SHARED
 
629
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvRes)
 
630
{
 
631
        switch(fdwReason) {
 
632
        case DLL_PROCESS_ATTACH:
 
633
                DisableThreadLibraryCalls(hinstDLL);
 
634
                break;
 
635
        }
 
636
        return TRUE;
 
637
}
 
638
#endif
 
639
 
 
640
#endif
 
641
 
 
642
/*
 
643
 Local Variables:
 
644
 compile-command: "cd .. && python setup.py -q build_ext"
 
645
 End:
 
646
*/