From: Bruce S. <Bru...@nc...> - 2009-01-20 17:59:10
|
Very impressive analysis, CL. Thanks! Bruce Sherwood CL wrote: > Since I am not familar with the code of GIL, correct me if I am wrong > ..as I make some fundamental guesses in the gil and locking calls. > > I have this problem also on my programs. The problem looks like a > deadlock rather than overflow. Therefore, it can happen in any vpython > programs. > > Here is my observations, : > > The keyboard buffer queue is implemented as a atomic_queue in vpython. > It has a lock object called "barrier" to protect the queue. The > deadlock situation is like this: > > Caller thread: > C1. call getkey() > C2. call py_pop() > C3. == py_pop() lock the barrier object > C4. == call py_pop_wait() > C5. == == py_pop_wait() release the gil_lock > C6. == == wait until there is some keys in the queue (during waiting, > the barrier object seems unlocked) > C7. == == regain gil_lock > C8. == == returning to py_pop() > C9. == pop a key from the queue > C10. == unlock barrier object > > The primary window thread: > P1. In dispatch_messages(): > P2. == gain gil_lock > P3. == for WM_KEYUP, WM_KEYDOWN, WM_CHAR, handle the key messages > P4. == == lock barrier object > P5. == == update the key queue > P6. == == unlock barrier object > P7. == release gil_lock > > If the first thread is in between C5-C7 and the key queue is not > empty, at this moment user press a key, the primary window thread can > gain the gil_lock and performing a dispatching of key events, it will > try to gain the barrier lock (P4). The first thread is locked when it > is going to regain the gil_lock (C7). The primary window thread is > locked by waiting the barreir lock. > > This situation does not happen frequently, because the time spend in > py_pop_wait is very short. > > But I can make it happens easily when I add a delay in py_pop_wait > before it returns: > > void > atomic_queue_impl::py_pop_wait( lock& L) > { > .... > waiting = false; > ::Sleep(100); > } > > If my understanding above is correct, the program can be fixed by > rewritting the function as: > > void > atomic_queue_impl::py_pop_wait( lock& L) > { > using python::gil_release; > using python::gil_lock; > > L.unlock(); > { > gil_release release; > > // I took the code to call Py_MakePendingCalls() out. The internet leads > // me to believe that it is not necessary. For example, Python time.sleep() > // doesn't do it. > if (empty) { > L.lock(); > while (empty) { > waiting = true; > ready.wait(L); > } > L.unlock(); > } > waiting = false; > } > L.lock(); > } > > > CL > >> I have been looking workarounds and found that by including opacity >> during a box definition, with any value Except 1.0 allows opacity to work! >> Also, if you have nested frames then a pause before connecting the main >> frame from the sub frames works! > >> Another problem that has just popped up. >> Any keyboard input that requires holding down a key for long periods >> seems to cause some programs to freeze, but not all! > >> Here are 3 examples, they all use cursor keys to move or spin objects. >> It acts like a keyboard buffer overflow, but that's just a guess. > > ------------------------------------------------------------------------------ > This SF.net email is sponsored by: > SourcForge Community > SourceForge wants to tell your story. > http://p.sf.net/sfu/sf-spreadtheword > _______________________________________________ > Visualpython-users mailing list > Vis...@li... > https://lists.sourceforge.net/lists/listinfo/visualpython-users |