Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b2a5772

Browse files
committed
It turns out that some calls return AEDesc records that are "borrowed",
the AEDesc data shouldn't be disposed when the Python object is. Added a C call AEDesc_NewBorrowed() to create these objects and a Python method old=AEDesc.AutoDispose(onoff) to change auto-dispose state.
1 parent aac8c58 commit b2a5772

4 files changed

Lines changed: 71 additions & 3 deletions

File tree

Include/pymactoolbox.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ PyObject *PyMac_BuildFSRef(FSRef *); /* Convert FSRef to PyObject */
106106

107107
/* AE exports */
108108
extern PyObject *AEDesc_New(AppleEvent *); /* XXXX Why passed by address?? */
109+
extern PyObject *AEDesc_NewBorrowed(AppleEvent *);
109110
extern int AEDesc_Convert(PyObject *, AppleEvent *);
110111

111112
/* Cm exports */

Mac/Modules/ae/_AEmodule.c

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ extern PyObject *_AEDesc_New(AEDesc *);
3535
extern int _AEDesc_Convert(PyObject *, AEDesc *);
3636

3737
#define AEDesc_New _AEDesc_New
38+
#define AEDesc_NewBorrowed _AEDesc_NewBorrowed
3839
#define AEDesc_Convert _AEDesc_Convert
3940
#endif
4041

@@ -70,6 +71,7 @@ PyTypeObject AEDesc_Type;
7071
typedef struct AEDescObject {
7172
PyObject_HEAD
7273
AEDesc ob_itself;
74+
int ob_owned;
7375
} AEDescObject;
7476

7577
PyObject *AEDesc_New(AEDesc *itself)
@@ -78,6 +80,7 @@ PyObject *AEDesc_New(AEDesc *itself)
7880
it = PyObject_NEW(AEDescObject, &AEDesc_Type);
7981
if (it == NULL) return NULL;
8082
it->ob_itself = *itself;
83+
it->ob_owned = 1;
8184
return (PyObject *)it;
8285
}
8386
int AEDesc_Convert(PyObject *v, AEDesc *p_itself)
@@ -93,7 +96,7 @@ int AEDesc_Convert(PyObject *v, AEDesc *p_itself)
9396

9497
static void AEDesc_dealloc(AEDescObject *self)
9598
{
96-
AEDisposeDesc(&self->ob_itself);
99+
if (self->ob_owned) AEDisposeDesc(&self->ob_itself);
97100
self->ob_type->tp_free((PyObject *)self);
98101
}
99102

@@ -759,6 +762,20 @@ static PyObject *AEDesc_AEResolve(AEDescObject *_self, PyObject *_args)
759762
return _res;
760763
}
761764

765+
static PyObject *AEDesc_AutoDispose(AEDescObject *_self, PyObject *_args)
766+
{
767+
PyObject *_res = NULL;
768+
769+
int onoff, old;
770+
if (!PyArg_ParseTuple(_args, "i", &onoff))
771+
return NULL;
772+
old = _self->ob_owned;
773+
_self->ob_owned = onoff;
774+
_res = Py_BuildValue("i", old);
775+
return _res;
776+
777+
}
778+
762779
static PyMethodDef AEDesc_methods[] = {
763780
{"AECoerceDesc", (PyCFunction)AEDesc_AECoerceDesc, 1,
764781
PyDoc_STR("(DescType toType) -> (AEDesc result)")},
@@ -816,6 +833,8 @@ static PyMethodDef AEDesc_methods[] = {
816833
PyDoc_STR("() -> None")},
817834
{"AEResolve", (PyCFunction)AEDesc_AEResolve, 1,
818835
PyDoc_STR("(short callbackFlags) -> (AEDesc theToken)")},
836+
{"AutoDispose", (PyCFunction)AEDesc_AutoDispose, 1,
837+
PyDoc_STR("(int)->int. Automatically AEDisposeDesc the object on Python object cleanup")},
819838
{NULL, NULL, 0}
820839
};
821840

@@ -1413,6 +1432,17 @@ GenericEventHandler(const AppleEvent *request, AppleEvent *reply, refcontype ref
14131432
return noErr;
14141433
}
14151434

1435+
PyObject *AEDesc_NewBorrowed(AEDesc *itself)
1436+
{
1437+
PyObject *it;
1438+
1439+
it = AEDesc_New(itself);
1440+
if (it)
1441+
((AEDescObject *)it)->ob_owned = 0;
1442+
return (PyObject *)it;
1443+
}
1444+
1445+
14161446

14171447
void init_AE(void)
14181448
{
@@ -1424,6 +1454,7 @@ void init_AE(void)
14241454
upp_AEIdleProc = NewAEIdleUPP(AEIdleProc);
14251455
upp_GenericEventHandler = NewAEEventHandlerUPP(GenericEventHandler);
14261456
PyMac_INIT_TOOLBOX_OBJECT_NEW(AEDesc *, AEDesc_New);
1457+
PyMac_INIT_TOOLBOX_OBJECT_NEW(AEDesc *, AEDesc_NewBorrowed);
14271458
PyMac_INIT_TOOLBOX_OBJECT_CONVERT(AEDesc, AEDesc_Convert);
14281459

14291460

Mac/Modules/ae/aesupport.py

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ def passInput(self, name):
9797
extern int _AEDesc_Convert(PyObject *, AEDesc *);
9898
9999
#define AEDesc_New _AEDesc_New
100+
#define AEDesc_NewBorrowed _AEDesc_NewBorrowed
100101
#define AEDesc_Convert _AEDesc_Convert
101102
#endif
102103
@@ -155,12 +156,24 @@ def passInput(self, name):
155156
Py_DECREF(res);
156157
return noErr;
157158
}
159+
160+
PyObject *AEDesc_NewBorrowed(AEDesc *itself)
161+
{
162+
PyObject *it;
163+
164+
it = AEDesc_New(itself);
165+
if (it)
166+
((AEDescObject *)it)->ob_owned = 0;
167+
return (PyObject *)it;
168+
}
169+
158170
"""
159171

160172
initstuff = initstuff + """
161173
upp_AEIdleProc = NewAEIdleUPP(AEIdleProc);
162174
upp_GenericEventHandler = NewAEEventHandlerUPP(GenericEventHandler);
163175
PyMac_INIT_TOOLBOX_OBJECT_NEW(AEDesc *, AEDesc_New);
176+
PyMac_INIT_TOOLBOX_OBJECT_NEW(AEDesc *, AEDesc_NewBorrowed);
164177
PyMac_INIT_TOOLBOX_OBJECT_CONVERT(AEDesc, AEDesc_Convert);
165178
"""
166179

@@ -197,8 +210,16 @@ def __init__(self, name, prefix = None, itselftype = None):
197210
GlobalObjectDefinition.__init__(self, name, prefix or name, itselftype or name)
198211
self.argref = "*"
199212

200-
def outputFreeIt(self, name):
201-
Output("AEDisposeDesc(&%s);", name)
213+
def outputStructMembers(self):
214+
GlobalObjectDefinition.outputStructMembers(self)
215+
Output("int ob_owned;")
216+
217+
def outputInitStructMembers(self):
218+
GlobalObjectDefinition.outputInitStructMembers(self)
219+
Output("it->ob_owned = 1;")
220+
221+
def outputCleanupStructMembers(self):
222+
Output("if (self->ob_owned) AEDisposeDesc(&self->ob_itself);")
202223

203224
aedescobject = AEDescDefinition('AEDesc')
204225
module.addobject(aedescobject)
@@ -209,6 +230,20 @@ def outputFreeIt(self, name):
209230
execfile('aegen.py')
210231
##execfile('aedatamodelgen.py')
211232

233+
# Manual generator
234+
AutoDispose_body = """
235+
int onoff, old;
236+
if (!PyArg_ParseTuple(_args, "i", &onoff))
237+
return NULL;
238+
old = _self->ob_owned;
239+
_self->ob_owned = onoff;
240+
_res = Py_BuildValue("i", old);
241+
return _res;
242+
"""
243+
f = ManualGenerator("AutoDispose", AutoDispose_body)
244+
f.docstring = lambda: "(int)->int. Automatically AEDisposeDesc the object on Python object cleanup"
245+
aedescmethods.append(f)
246+
212247
for f in functions: module.add(f)
213248
for f in aedescmethods: aedescobject.add(f)
214249

Python/mactoolboxglue.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,7 @@ GLUE_NEW(FSRef *, PyMac_BuildFSRef, "macfs")
534534
GLUE_CONVERT(FSRef, PyMac_GetFSRef, "macfs")
535535

536536
GLUE_NEW(AppleEvent *, AEDesc_New, "Carbon.AE") /* XXXX Why by address? */
537+
GLUE_NEW(AppleEvent *, AEDesc_NewBorrowed, "Carbon.AE")
537538
GLUE_CONVERT(AppleEvent, AEDesc_Convert, "Carbon.AE")
538539

539540
GLUE_NEW(Component, CmpObj_New, "Carbon.Cm")

0 commit comments

Comments
 (0)