~pythonregexp2.7/python/issue2636-05

« back to all changes in this revision

Viewing changes to Modules/_ctypes/_ctypes.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:
3096
3096
        CFuncPtrObject *self;
3097
3097
        PyObject *callable;
3098
3098
        StgDictObject *dict;
3099
 
        ffi_info *thunk;
 
3099
        CThunkObject *thunk;
3100
3100
 
3101
3101
        if (PyTuple_GET_SIZE(args) == 0)
3102
3102
                return GenericCData_new(type, args, kwds);
3153
3153
                return NULL;
3154
3154
        }
3155
3155
 
3156
 
        /*****************************************************************/
3157
 
        /* The thunk keeps unowned references to callable and dict->argtypes
3158
 
           so we have to keep them alive somewhere else: callable is kept in self,
3159
 
           dict->argtypes is in the type's stgdict.
3160
 
        */
3161
3156
        thunk = AllocFunctionCallback(callable,
3162
3157
                                      dict->argtypes,
3163
3158
                                      dict->restype,
3166
3161
                return NULL;
3167
3162
 
3168
3163
        self = (CFuncPtrObject *)GenericCData_new(type, args, kwds);
3169
 
        if (self == NULL)
 
3164
        if (self == NULL) {
 
3165
                Py_DECREF(thunk);
3170
3166
                return NULL;
 
3167
        }
3171
3168
 
3172
3169
        Py_INCREF(callable);
3173
3170
        self->callable = callable;
3174
3171
 
3175
3172
        self->thunk = thunk;
3176
 
        *(void **)self->b_ptr = *(void **)thunk;
3177
 
 
3178
 
        /* We store ourself in self->b_objects[0], because the whole instance
3179
 
           must be kept alive if stored in a structure field, for example.
3180
 
           Cycle GC to the rescue! And we have a unittest proving that this works
3181
 
           correctly...
3182
 
        */
3183
 
 
3184
 
        Py_INCREF((PyObject *)self); /* for KeepRef */
3185
 
        if (-1 == KeepRef((CDataObject *)self, 0, (PyObject *)self)) {
 
3173
        *(void **)self->b_ptr = (void *)thunk->pcl;
 
3174
        
 
3175
        Py_INCREF((PyObject *)thunk); /* for KeepRef */
 
3176
        if (-1 == KeepRef((CDataObject *)self, 0, (PyObject *)thunk)) {
3186
3177
                Py_DECREF((PyObject *)self);
3187
3178
                return NULL;
3188
3179
        }
3189
 
 
3190
3180
        return (PyObject *)self;
3191
3181
}
3192
3182
 
3639
3629
        Py_VISIT(self->argtypes);
3640
3630
        Py_VISIT(self->converters);
3641
3631
        Py_VISIT(self->paramflags);
 
3632
        Py_VISIT(self->thunk);
3642
3633
        return CData_traverse((CDataObject *)self, visit, arg);
3643
3634
}
3644
3635
 
3652
3643
        Py_CLEAR(self->argtypes);
3653
3644
        Py_CLEAR(self->converters);
3654
3645
        Py_CLEAR(self->paramflags);
3655
 
 
3656
 
        if (self->thunk) {
3657
 
                FreeClosure(self->thunk->pcl);
3658
 
                PyMem_Free(self->thunk);
3659
 
                self->thunk = NULL;
3660
 
        }
3661
 
 
 
3646
        Py_CLEAR(self->thunk);
3662
3647
        return CData_clear((CDataObject *)self);
3663
3648
}
3664
3649
 
5186
5171
        if (PyType_Ready(&PyCArg_Type) < 0)
5187
5172
                return;
5188
5173
 
 
5174
        if (PyType_Ready(&CThunk_Type) < 0)
 
5175
                return;
 
5176
 
5189
5177
        /* StgDict is derived from PyDict_Type */
5190
5178
        StgDict_Type.tp_base = &PyDict_Type;
5191
5179
        if (PyType_Ready(&StgDict_Type) < 0)