From: CL <clc...@gm...> - 2009-01-19 03:33:01
|
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. |