~malept/ubuntu/lucid/python2.6/dev-dependency-fix

« back to all changes in this revision

Viewing changes to Modules/_ctypes/callbacks.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2009-02-13 12:51:00 UTC
  • Revision ID: james.westby@ubuntu.com-20090213125100-uufgcb9yeqzujpqw
Tags: upstream-2.6.1
ImportĀ upstreamĀ versionĀ 2.6.1

Show diffs side-by-side

added added

removed removed

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