g_main_loop () seems stuck



Hello,

I have multi-threaded GTK+ app which acts as a frontend to a backend
volume management system library. I'm having a hang type problem. Sorry,
this post will be somewhat lengthy.

For reasons I won't go into here, I actually have my gtk_main() running
on a separate thread. This allows me to "inject" events from the other
threads as necessary. I use gdk_threads_enter/gdk_threads_leave on other
threads and in idle and timeout functions to keep synchronization as the
GTK+ FAQ indicates and everything works well.

I have one condition though that is a bug somewhere but I have yet to
pinpoint it. The scenario is as follows:

1. Start application
2. g_thread_init (NULL) and gtk_init () are called in main()
3. main() does a pthread_create () to start main_event_loop_thread ()
which becomes thread 3
4. main() calls evms_open_engine () to discover volumes and partitions.
5. evms_open_engine() running on thread 1 invokes a UI callback
(registered by my app) because it needs to get a user to respond to a
critical question.
6. My callback code does a gdk_threads_enter(), creates the user window,
does a gdk_threads_leave() and blocks with g_cond_wait (). The GCond was
created while the window was being created and passed as user_data for
the destroy event to see when the window is destroyed.
7. As soon as I call the gdk_threads_leave () you see the window show
up. As soon as the user selects one of the choices, the choice is set
and the window is destroyed.
8. The signal handler for the destroy event then issues a g_cond_signal
to signal that a response from the user was received.
9. Thread 1 then unblocks and returns to the evms_open_engine () code.
10. Once evms_open_engine completes successfully, thread 1 creates and
displays the main window.

The above works 100% of the time when it is only one critical response
dialog that is handled. If after I return to the engine code in the
above scenario it is followed in rapid succession with another UI
callback I go through all the motions and end up blocking in the
g_cond_wait() and no window shows up. This happens 80% of the time.

Trying to debug this under gdb, I found that if I simply interrupted the
app and typed cont, it would show the expected user dialog window. I
will explain why this happens in just a moment.

Switching between the threads and displaying the call stack, I see that
the main event loop thread (thread 3) looks like this:

#0  0x403fdc97 in __poll (fds=0x80b26a8, nfds=2, timeout=-1) at
../sysdeps/unix/sysv/linux/poll.c:63
#1  0x401acd0f in g_main_poll (timeout=-1, use_priority=0, priority=0)
at gmain.c:1034
#2  0x401ac6e5 in g_main_iterate (block=1, dispatch=1) at gmain.c:808
#3  0x401aca68 in g_main_run (loop=0x80b4b48) at gmain.c:935
#4  0x400c7363 in gtk_main () at gtkmain.c:524
#5  0x08054cae in main_event_loop_thread (not_used=0x0) at main.c:178
#6  0x401c4c6f in pthread_start_thread (arg=0x40d05be0) at manager.c:284
#7  0x401c4d5f in pthread_start_thread_event (arg=0x40d05be0) at
manager.c:308

Thread 1 looks like this:

0  0x40346b85 in __sigsuspend (set=0xbffff610) at
../sysdeps/unix/sysv/linux/sigsuspend.c:45
#1  0x401c71c9 in __pthread_wait_for_restart_signal (self=0x401cff40) at
pthread.c:969
#2  0x401c3bdc in pthread_cond_wait (cond=0x81057a0, mutex=0x810d5e0) at
restart.h:34
.
<snip>
.

Apperently the reason that the window pops up after I break in and
continue is that the poll() function returns a -1 and sets errno to
EINTR (system call interrupted) rather than continuing to block
indefinitely.

I am not sure what the poll() descriptors are waiting for that cause it
to stay blocked.

I sure hope some has seen this before and can tell me if this is either
a glib, gtk or a bug in what I am doing.

-- 
regards,

Luciano Chavez

lnx1138 us ibm com          
http://sf.net/projects/evms




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]