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