summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorGuilherme Polo <ggpolo@gmail.com>2009-02-06 23:16:11 (GMT)
committerGuilherme Polo <ggpolo@gmail.com>2009-02-06 23:16:11 (GMT)
commit491aee20c0282fe7e456796f31328a21b02abba3 (patch)
treea6b71b31885a7ed8cded04b9ff742bb8d16df9e9 /Modules
parentb41bc91549fdcdb2d206271edd0cccabe56664f8 (diff)
downloadcpython-491aee20c0282fe7e456796f31328a21b02abba3.zip
cpython-491aee20c0282fe7e456796f31328a21b02abba3.tar.gz
cpython-491aee20c0282fe7e456796f31328a21b02abba3.tar.bz2
Merged revisions 69376-69377 via svnmerge from
svn+ssh://pythondev/python/trunk ........ r69376 | guilherme.polo | 2009-02-06 20:26:22 -0200 (Fri, 06 Feb 2009) | 3 lines Partial fix to issue #1731706: memory leak in Tkapp_Call when calling from a thread different than the one that created the Tcl interpreter. ........ r69377 | guilherme.polo | 2009-02-06 20:48:07 -0200 (Fri, 06 Feb 2009) | 5 lines Issue #1731706: Call Tcl_ConditionFinalize for Tcl_Conditions that will not be used again (this requires Tcl/Tk 8.3.1), also fix a memory leak in Tkapp_Call when calling from a thread different than the one that created the Tcl interpreter. ........
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_tkinter.c46
1 files changed, 28 insertions, 18 deletions
diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c
index eed7177..645f984 100644
--- a/Modules/_tkinter.c
+++ b/Modules/_tkinter.c
@@ -9,9 +9,9 @@ Copyright (C) 1994 Steen Lumholt.
/* TCL/TK VERSION INFO:
- Only Tcl/Tk 8.2 and later are supported. Older versions are not
- supported. (Use Python 2.2 if you cannot upgrade your Tcl/Tk
- libraries.)
+ Only Tcl/Tk 8.3.1 and later are supported. Older versions are not
+ supported. Use Python 2.6 or older if you cannot upgrade your
+ Tcl/Tk libraries.
*/
/* XXX Further speed-up ideas, involving Tcl 8.0 features:
@@ -1085,7 +1085,7 @@ typedef struct Tkapp_CallEvent {
int flags;
PyObject **res;
PyObject **exc_type, **exc_value, **exc_tb;
- Tcl_Condition done;
+ Tcl_Condition *done;
} Tkapp_CallEvent;
void
@@ -1208,10 +1208,12 @@ Tkapp_CallProc(Tkapp_CallEvent *e, int flags)
*(e->res) = Tkapp_CallResult(e->self);
}
LEAVE_PYTHON
- done:
+
+ Tkapp_CallDeallocArgs(objv, objStore, objc);
+done:
/* Wake up calling thread. */
Tcl_MutexLock(&call_mutex);
- Tcl_ConditionNotify(&e->done);
+ Tcl_ConditionNotify(e->done);
Tcl_MutexUnlock(&call_mutex);
return 1;
}
@@ -1249,6 +1251,7 @@ Tkapp_Call(PyObject *selfptr, PyObject *args)
/* We cannot call the command directly. Instead, we must
marshal the parameters to the interpreter thread. */
Tkapp_CallEvent *ev;
+ Tcl_Condition cond = NULL;
PyObject *exc_type, *exc_value, *exc_tb;
if (!WaitForMainloop(self))
return NULL;
@@ -1260,9 +1263,9 @@ Tkapp_Call(PyObject *selfptr, PyObject *args)
ev->exc_type = &exc_type;
ev->exc_value = &exc_value;
ev->exc_tb = &exc_tb;
- ev->done = (Tcl_Condition)0;
+ ev->done = &cond;
- Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done, &call_mutex);
+ Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &call_mutex);
if (res == NULL) {
if (exc_type)
@@ -1270,6 +1273,7 @@ Tkapp_Call(PyObject *selfptr, PyObject *args)
else
PyErr_SetObject(Tkinter_TclError, exc_value);
}
+ Tcl_ConditionFinalize(&cond);
}
else
#endif
@@ -1455,7 +1459,7 @@ typedef struct VarEvent {
PyObject **res;
PyObject **exc_type;
PyObject **exc_val;
- Tcl_Condition cond;
+ Tcl_Condition *cond;
} VarEvent;
static int
@@ -1499,7 +1503,7 @@ var_proc(VarEvent* ev, int flags)
ENTER_PYTHON
var_perform(ev);
Tcl_MutexLock(&var_mutex);
- Tcl_ConditionNotify(&ev->cond);
+ Tcl_ConditionNotify(ev->cond);
Tcl_MutexUnlock(&var_mutex);
LEAVE_PYTHON
return 1;
@@ -1514,6 +1518,7 @@ var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags)
TkappObject *self = (TkappObject*)selfptr;
VarEvent *ev;
PyObject *res, *exc_type, *exc_val;
+ Tcl_Condition cond = NULL;
/* The current thread is not the interpreter thread. Marshal
the call to the interpreter thread, then wait for
@@ -1530,9 +1535,10 @@ var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags)
ev->res = &res;
ev->exc_type = &exc_type;
ev->exc_val = &exc_val;
- ev->cond = NULL;
+ ev->cond = &cond;
ev->ev.proc = (Tcl_EventProc*)var_proc;
- Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->cond, &var_mutex);
+ Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &var_mutex);
+ Tcl_ConditionFinalize(&cond);
if (!res) {
PyErr_SetObject(exc_type, exc_val);
Py_DECREF(exc_type);
@@ -2019,7 +2025,7 @@ typedef struct CommandEvent{
int create;
int *status;
ClientData *data;
- Tcl_Condition done;
+ Tcl_Condition *done;
} CommandEvent;
static int
@@ -2032,7 +2038,7 @@ Tkapp_CommandProc(CommandEvent *ev, int flags)
else
*ev->status = Tcl_DeleteCommand(ev->interp, ev->name);
Tcl_MutexLock(&command_mutex);
- Tcl_ConditionNotify(&ev->done);
+ Tcl_ConditionNotify(ev->done);
Tcl_MutexUnlock(&command_mutex);
return 1;
}
@@ -2068,6 +2074,7 @@ Tkapp_CreateCommand(PyObject *selfptr, PyObject *args)
data->func = func;
if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
+ Tcl_Condition cond = NULL;
CommandEvent *ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
ev->interp = self->interp;
@@ -2075,8 +2082,9 @@ Tkapp_CreateCommand(PyObject *selfptr, PyObject *args)
ev->name = cmdName;
ev->data = (ClientData)data;
ev->status = &err;
- ev->done = NULL;
- Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done, &command_mutex);
+ ev->done = &cond;
+ Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &command_mutex);
+ Tcl_ConditionFinalize(&cond);
}
else {
ENTER_TCL
@@ -2107,6 +2115,7 @@ Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args)
if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName))
return NULL;
if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) {
+ Tcl_Condition cond = NULL;
CommandEvent *ev;
ev = (CommandEvent*)ckalloc(sizeof(CommandEvent));
ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc;
@@ -2114,9 +2123,10 @@ Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args)
ev->create = 0;
ev->name = cmdName;
ev->status = &err;
- ev->done = NULL;
- Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->done,
+ ev->done = &cond;
+ Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond,
&command_mutex);
+ Tcl_ConditionFinalize(&cond);
}
else {
ENTER_TCL