"Jeff Hobbs" <JeffH@ActiveState.com> writes: > That's correct - I should have looked a bit more into what I did > before (I was always tying in another GUI's event loop). However, > I don't see why you should not consider the extra event source. > Tk uses this itself for X. It would be something like: That does not work, either. I'm using the patch attached below, and I'm getting the output ... setupproc called 729 setupproc called 730 setupproc called 731 setupproc called 732 setupproc called 733 setupproc called 734 setupproc called 735 ... That is, even though the setupproc is called, and even though the select is not blocking anymore, DoOneEvent does not return (I don't see the "Event done" messages). Regards, Martin Index: _tkinter.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_tkinter.c,v retrieving revision 1.123 diff -u -r1.123 _tkinter.c --- _tkinter.c 26 Jan 2002 20:21:50 -0000 1.123 +++ _tkinter.c 22 Feb 2002 09:56:13 -0000 @@ -133,6 +139,10 @@ These locks expand to several statements and brackets; they should not be used in branches of if statements and the like. + To give other threads a chance to access Tcl while the Tk mainloop is + runnning, an input source is registered with Tcl which results in Tcl + not blocking for more than 20ms. + */ static PyThread_type_lock tcl_lock = 0; @@ -237,24 +248,6 @@ /**** Utils ****/ -#ifdef WITH_THREAD -#ifndef MS_WINDOWS - -/* Millisecond sleep() for Unix platforms. */ - -static void -Sleep(int milli) -{ - /* XXX Too bad if you don't have select(). */ - struct timeval t; - t.tv_sec = milli/1000; - t.tv_usec = (milli%1000) * 1000; - select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t); -} -#endif /* MS_WINDOWS */ -#endif /* WITH_THREAD */ - - static char * AsString(PyObject *value, PyObject *tmp) { @@ -1671,6 +1948,37 @@ /** Event Loop **/ +#ifdef WITH_THREAD +static int setupproc_registered; +/* + *---------------------------------------------------------------------- + * + * TkinterSetupProc -- + * + * This procedure implements the setup part of the Tkinter + * event source. It is invoked by Tcl_DoOneEvent before entering + * the notifier to check for events on all displays. + * + * Results: + * None. + * + * Side effects: + * The maximum block time will be set to 20000 usecs to ensure that + * the notifier returns control to Tcl. + * + *---------------------------------------------------------------------- + */ + +static void +TkinterSetupProc(ClientData clientData, int flags) +{ + static Tcl_Time blockTime = { 0, 20000 }; + static int i = 0; + printf("setupproc called %d\n",++i); + Tcl_SetMaxBlockTime(&blockTime); +} +#endif + static PyObject * Tkapp_MainLoop(PyObject *self, PyObject *args) { @@ -1682,22 +1990,29 @@ if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold)) return NULL; +#ifdef WITH_THREAD + if (!setupproc_registered) { + Tcl_CreateEventSource(TkinterSetupProc, NULL, NULL); + setupproc_registered = 1; + } +#endif + quitMainLoop = 0; while (Tk_GetNumMainWindows() > threshold && !quitMainLoop && !errorInCmd) { int result; + #ifdef WITH_THREAD Py_BEGIN_ALLOW_THREADS PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; - result = Tcl_DoOneEvent(TCL_DONT_WAIT); + result = Tcl_DoOneEvent(0); + printf("Event done\n"); tcl_tstate = NULL; PyThread_release_lock(tcl_lock); - if (result == 0) - Sleep(20); Py_END_ALLOW_THREADS #else result = Tcl_DoOneEvent(0); @@ -2033,12 +2364,10 @@ PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = event_tstate; - result = Tcl_DoOneEvent(TCL_DONT_WAIT); + result = Tcl_DoOneEvent(0); tcl_tstate = NULL; PyThread_release_lock(tcl_lock); - if (result == 0) - Sleep(20); Py_END_ALLOW_THREADS #else result = Tcl_DoOneEvent(0);
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4