~pythonregexp2.7/python/issue2636-05

« back to all changes in this revision

Viewing changes to Modules/_ctypes/callbacks.c

  • Committer: thomas.heller
  • Date: 2008-04-24 18:14:19 UTC
  • Revision ID: svn-v3-trunk1:6015fed2-1504-0410-9fe1-9d1591cc4771:python%2Ftrunk:62481
Remove cyclic reference in CFuncPtr instances; see issue #2682.

Backport candidate for the release25-maint branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#endif
13
13
#include "ctypes.h"
14
14
 
 
15
/**************************************************************/
 
16
 
 
17
static CThunkObject_dealloc(PyObject *_self)
 
18
{
 
19
        CThunkObject *self = (CThunkObject *)_self;
 
20
        Py_XDECREF(self->converters);
 
21
        Py_XDECREF(self->callable);
 
22
        Py_XDECREF(self->restype);
 
23
        if (self->pcl)
 
24
                FreeClosure(self->pcl);
 
25
        PyObject_Del(self);
 
26
}
 
27
 
 
28
static int
 
29
CThunkObject_traverse(PyObject *_self, visitproc visit, void *arg)
 
30
{
 
31
        CThunkObject *self = (CThunkObject *)_self;
 
32
        Py_VISIT(self->converters);
 
33
        Py_VISIT(self->callable);
 
34
        Py_VISIT(self->restype);
 
35
        return 0;
 
36
}
 
37
 
 
38
static int
 
39
CThunkObject_clear(PyObject *_self)
 
40
{
 
41
        CThunkObject *self = (CThunkObject *)_self;
 
42
        Py_CLEAR(self->converters);
 
43
        Py_CLEAR(self->callable);
 
44
        Py_CLEAR(self->restype);
 
45
        return 0;
 
46
}
 
47
 
 
48
PyTypeObject CThunk_Type = {
 
49
        PyVarObject_HEAD_INIT(NULL, 0)
 
50
        "_ctypes.CThunkObject",
 
51
        sizeof(CThunkObject),                   /* tp_basicsize */
 
52
        sizeof(ffi_type),                       /* tp_itemsize */
 
53
        CThunkObject_dealloc,                   /* tp_dealloc */
 
54
        0,                                      /* tp_print */
 
55
        0,                                      /* tp_getattr */
 
56
        0,                                      /* tp_setattr */
 
57
        0,                                      /* tp_compare */
 
58
        0,                                      /* tp_repr */
 
59
        0,                                      /* tp_as_number */
 
60
        0,                                      /* tp_as_sequence */
 
61
        0,                                      /* tp_as_mapping */
 
62
        0,                                      /* tp_hash */
 
63
        0,                                      /* tp_call */
 
64
        0,                                      /* tp_str */
 
65
        0,                                      /* tp_getattro */
 
66
        0,                                      /* tp_setattro */
 
67
        0,                                      /* tp_as_buffer */
 
68
        Py_TPFLAGS_DEFAULT,                     /* tp_flags */
 
69
        "CThunkObject",                         /* tp_doc */
 
70
        CThunkObject_traverse,                  /* tp_traverse */
 
71
        CThunkObject_clear,                     /* tp_clear */
 
72
        0,                                      /* tp_richcompare */
 
73
        0,                                      /* tp_weaklistoffset */
 
74
        0,                                      /* tp_iter */
 
75
        0,                                      /* tp_iternext */
 
76
        0,                                      /* tp_methods */
 
77
        0,                                      /* tp_members */
 
78
};
 
79
 
 
80
/**************************************************************/
 
81
 
15
82
static void
16
83
PrintError(char *msg, ...)
17
84
{
247
314
                        void **args,
248
315
                        void *userdata)
249
316
{
250
 
        ffi_info *p = userdata;
 
317
        CThunkObject *p = (CThunkObject *)userdata;
251
318
 
252
319
        _CallPythonObject(resp,
253
 
                          p->restype,
 
320
                          p->ffi_restype,
254
321
                          p->setfunc,
255
322
                          p->callable,
256
323
                          p->converters,
257
324
                          args);
258
325
}
259
326
 
260
 
ffi_info *AllocFunctionCallback(PyObject *callable,
261
 
                                PyObject *converters,
262
 
                                PyObject *restype,
263
 
                                int is_cdecl)
 
327
static CThunkObject* CThunkObject_new(Py_ssize_t nArgs)
 
328
{
 
329
        CThunkObject *p;
 
330
        int i;
 
331
 
 
332
        p = PyObject_NewVar(CThunkObject, &CThunk_Type, nArgs);
 
333
        if (p == NULL) {
 
334
                PyErr_NoMemory();
 
335
                return NULL;
 
336
        }
 
337
 
 
338
        p->pcl = NULL;
 
339
        memset(&p->cif, 0, sizeof(p->cif));
 
340
        p->converters = NULL;
 
341
        p->callable = NULL;
 
342
        p->setfunc = NULL;
 
343
        p->ffi_restype = NULL;
 
344
        
 
345
        for (i = 0; i < nArgs + 1; ++i)
 
346
                p->atypes[i] = NULL;
 
347
        return p;
 
348
}
 
349
 
 
350
CThunkObject *AllocFunctionCallback(PyObject *callable,
 
351
                                    PyObject *converters,
 
352
                                    PyObject *restype,
 
353
                                    int is_cdecl)
264
354
{
265
355
        int result;
266
 
        ffi_info *p;
 
356
        CThunkObject *p;
267
357
        Py_ssize_t nArgs, i;
268
358
        ffi_abi cc;
269
359
 
270
360
        nArgs = PySequence_Size(converters);
271
 
        p = (ffi_info *)PyMem_Malloc(sizeof(ffi_info) + sizeof(ffi_type) * (nArgs));
272
 
        if (p == NULL) {
273
 
                PyErr_NoMemory();
 
361
        p = CThunkObject_new(nArgs);
 
362
        if (p == NULL)
274
363
                return NULL;
275
 
        }
 
364
 
 
365
        assert(CThunk_CheckExact(p));
 
366
 
276
367
        p->pcl = MallocClosure();
277
368
        if (p->pcl == NULL) {
278
369
                PyErr_NoMemory();
288
379
        }
289
380
        p->atypes[i] = NULL;
290
381
 
 
382
        Py_INCREF(restype);
 
383
        p->restype = restype;
291
384
        if (restype == Py_None) {
292
385
                p->setfunc = NULL;
293
 
                p->restype = &ffi_type_void;
 
386
                p->ffi_restype = &ffi_type_void;
294
387
        } else {
295
388
                StgDictObject *dict = PyType_stgdict(restype);
296
389
                if (dict == NULL || dict->setfunc == NULL) {
299
392
                  goto error;
300
393
                }
301
394
                p->setfunc = dict->setfunc;
302
 
                p->restype = &dict->ffi_type_pointer;
 
395
                p->ffi_restype = &dict->ffi_type_pointer;
303
396
        }
304
397
 
305
398
        cc = FFI_DEFAULT_ABI;
323
416
                goto error;
324
417
        }
325
418
 
 
419
        Py_INCREF(converters);
326
420
        p->converters = converters;
 
421
        Py_INCREF(callable);
327
422
        p->callable = callable;
328
423
        return p;
329
424
 
330
425
  error:
331
 
        if (p) {
332
 
                if (p->pcl)
333
 
                        FreeClosure(p->pcl);
334
 
                PyMem_Free(p);
335
 
        }
 
426
        Py_XDECREF(p);
336
427
        return NULL;
337
428
}
338
429