|
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
|