summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin v. Löwis <martin@v.loewis.de>2002-12-28 09:23:09 (GMT)
committerMartin v. Löwis <martin@v.loewis.de>2002-12-28 09:23:09 (GMT)
commit5b26abb37adc6640bb5cb10cf196f59e77ba05e0 (patch)
tree4d994645e2804c679eb7ee25c789df6641762079
parent276a8f3b80efda91020a8daa1ad2f15b998083d9 (diff)
downloadcpython-5b26abb37adc6640bb5cb10cf196f59e77ba05e0.zip
cpython-5b26abb37adc6640bb5cb10cf196f59e77ba05e0.tar.gz
cpython-5b26abb37adc6640bb5cb10cf196f59e77ba05e0.tar.bz2
Gracefully delay runtime error up to 1s. Add .willdispatch().
-rwxr-xr-xLib/pydoc.py1
-rw-r--r--Modules/_tkinter.c43
2 files changed, 32 insertions, 12 deletions
diff --git a/Lib/pydoc.py b/Lib/pydoc.py
index fe66334..9179721 100755
--- a/Lib/pydoc.py
+++ b/Lib/pydoc.py
@@ -1919,6 +1919,7 @@ def gui():
self.expanded = 0
self.window.wm_geometry('%dx%d' % (self.minwidth, self.minheight))
self.window.wm_minsize(self.minwidth, self.minheight)
+ self.window.tk.willdispatch()
import threading
threading.Thread(
diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c
index 492198e..1122631 100644
--- a/Modules/_tkinter.c
+++ b/Modules/_tkinter.c
@@ -310,6 +310,24 @@ Sleep(int milli)
#endif /* MS_WINDOWS */
#endif /* WITH_THREAD */
+/* Wait up to 1s for the mainloop to come up. */
+
+static int
+WaitForMainloop(TkappObject* self)
+{
+ int i;
+ for (i = 0; i < 10; i++) {
+ if (self->dispatching)
+ return 1;
+ Py_BEGIN_ALLOW_THREADS
+ Sleep(100);
+ Py_END_ALLOW_THREADS
+ }
+ if (self->dispatching)
+ return 1;
+ PyErr_SetString(PyExc_RuntimeError, "main thread is not in main loop");
+ return 0;
+}
static char *
@@ -1138,11 +1156,8 @@ Tkapp_Call(PyObject *_self, PyObject *args)
marshal the parameters to the interpreter thread. */
Tkapp_CallEvent *ev;
PyObject *exc_type, *exc_value, *exc_tb;
- if (!self->dispatching) {
- PyErr_SetString(PyExc_RuntimeError,
- "main thread is not in main loop");
+ if (!WaitForMainloop(self))
return NULL;
- }
ev = (Tkapp_CallEvent*)ckalloc(sizeof(Tkapp_CallEvent));
ev->ev.proc = (Tcl_EventProc*)Tkapp_CallProc;
ev->self = self;
@@ -1427,11 +1442,8 @@ var_invoke(PyObject *_self, char* arg1, char* arg2, char* arg3, int flags,
the call to the interpreter thread, then wait for
completion. */
- if (!self->dispatching) {
- PyErr_SetString(PyExc_RuntimeError,
- "main thread is not in main loop");
+ if (!WaitForMainloop(self))
return NULL;
- }
ev->cond = NULL;
ev->ev.proc = (Tcl_EventProc*)var_proc;
Tkapp_ThreadSend(self, (Tcl_Event*)ev, &ev->cond, &var_mutex);
@@ -1943,11 +1955,8 @@ Tkapp_CreateCommand(PyObject *_self, PyObject *args)
}
if (self->threaded && self->thread_id != Tcl_GetCurrentThread() &&
- !self->dispatching) {
- PyErr_SetString(PyExc_RuntimeError,
- "main thread is not in main loop");
+ !WaitForMainloop(self))
return NULL;
- }
data = PyMem_NEW(PythonCmd_ClientData, 1);
if (!data)
@@ -2423,12 +2432,22 @@ Tkapp_WantObjects(PyObject *self, PyObject *args)
return Py_None;
}
+static PyObject *
+Tkapp_WillDispatch(PyObject *self, PyObject *args)
+{
+
+ ((TkappObject*)self)->dispatching = 1;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
/**** Tkapp Method List ****/
static PyMethodDef Tkapp_methods[] =
{
+ {"willdispatch", Tkapp_WillDispatch, METH_NOARGS},
{"wantobjects", Tkapp_WantObjects, METH_VARARGS},
{"call", Tkapp_Call, METH_OLDARGS},
{"globalcall", Tkapp_GlobalCall, METH_OLDARGS},