Thanks a lot for the help.! I have now solved the problem by
introducing a GCond,called C below, into the flow. For posterity, here
is the modified flow, which is actually a general model of a
client-server interaction between a worker thread and the gui thread.
* W locks j->M through g_mutex_lock(j->M) so that G will not send
the condition signal until we are ready for it.
* W fills in j with various info to display.
* W calls g_idle_add(GSourceFunc(cb_update_job), j) to indicate to
G that there is info to display.
* W waits on C through g_cond_wait(j->C, j->M). This will unblock
j->M and allow G to continue.
* G is called in cb_update_job().
* G updates the gui, also possibly updates j based on GUI interaction.
* G does g_mutex_lock(j->M) which causes it to wait until W has
reached g_cond_wait().
* G sends a condition signal through g_cond_signal(j->C)
* G does g_mutex_unlock(j->M). This will allow W to take the lock
in g_cond_wait().
* W wakes up and does a g_mutex_unlock(j->M) as it no longer needs
the lock on the mutex.
* W examines the return info that G filled in into j and contiues
or aborts its operation.
Quite complex I have to admit. Is there a simpler way to solve the
same problem (query/response)?
Regards,
Dov
2009/7/7 Chris Vine <
chris cvine freeserve co uk>
>
> On Mon, 6 Jul 2009 17:13:07 +0300
> Dov Grobgeld <
dov grobgeld gmail com> wrote:
>
> > I'm having a problem with GMutex under Windows that don't lock. The
> > behaviour is definitely different from that under Linux.
> >
> > The system is composed of to threads. A gui thread G and a worker
> > thread W. The ping pong between the threads via a mutex j->M should
> > work as follows. j is a job data structure that carries info between
> > the worker thread and the gui thread.
> >
> > 1. W locks j->M through g_mutex_lock(j->M) so that a subsequent
> > lock will block.
> > 2. W fills in j with various info to display.
> > 3. W calls g_idle_add(GSourceFunc(cb_update_job), j) to indicate
> > to G that there is info to display.
> > 4. W blocks on M through a second call to g_mutex_lock(j->M)
> > 5. G is called in cb_update_job() and updates the gui, also
> > possibly updates j, and then does g_mutex_unlock(j->M)
> > 6. W wakes up and does a g_mutex_unlock(j->M) as it no longer
> > needs the lock on the mutex.
> > 7. W examines the return info that G filled in into j and contiues
> > or aborts its operation.
> >
> > The problem on Win32 is that g_mutex_lock in 4 doesn't block and the
> > thread continues, which eventually will cause the system to crash.
> >
> > Is something supposed to be different under Windows, or should I file
> > a bug?
>
> This won't work. Mutexes have ownership once locked. An unlock
> operation on a mutex must be carried out by the same thread that locked
> it.
>
> You could use condition variables to achieve what you want. It would
> also be wise to read up a little more on threading, and in particular
> pthreads (which GThreads mimic).
>
> Chris
>