On Fri, Jun 17, 2005 at 11:07:04AM -0400, Chris Lambacher wrote:
> On 6/17/05, Antoon Pardon <[EMAIL PROTECTED]> wrote:
> > > Think of event handlers as being in the context of main, but when main
> > > is not doing anything it does not make any sense to continue to hold
> > > the lock, which would prevent you from doing anything in another
> > > thread.
> > 
> > The question is, why should the lock already be held when main is
> > called. If main needs the lock, why not let it acquire the lock
> > itself. I guess it has something to do with the design decision
> > to invoke the signal callbacks with the lock on. IMO that was
> > a mistake, but that can't be helped now. But I can't agree
> > in calling the consequences of that decision somehow consistent.
> 
> gtk.main is analygus to a condition.  You get signaled when you have
> some processing to do.

I'm sorry I don't see it that way. We will have to agree to disagree
on this one.

> When you get called you expect to be able to
> do the processing that is neccessary.  Some (admittadly rather poor)
> argument can be made that event handlers being called with the lock
> enabled is an attempt to ensure responsiveness.  It would suck to have
> to aquire the lock for every little event handler.

I found it sucked even harder that my application deadlocked because
a specific event handler didn't need the lock but had acquired it
any way.

> What is the use case for releasing the lock in a callback?  Callbacks
> should be short or cause the responsivness of the whole application to
> suffer.  If a call back is long enough that you are considering
> releasing the lock (and you are already using multiple threads) you
> should probably be doing the task asyncronously.

It has nothing to do with short or long but with interactivity with
other threads. Like a thread that can be canceled by clicking a
button.

Take the following kind of code:

  class Buzy(Threading):

    def run(self):
      while not self.is_canceled:
        calculate_step()
        gtk.gdk.threads_enter()
        show_incremental_result()
        gtk.gdk.threads_leave()

    def cancel(self):
      self.is_canceled = True

  buzy = Buzy()

  def On_Click():
    buzy.cancel()
    buzy.join()


Not look at the following scenario. buzy is calculating a step.
The user cancels the thread, so gtk acquires the lock and calls
On_Click which calls buzy.cancel. buzy wants to acquire the lock
but is blocked. gtk wants to join buzy and is blocked too: Deadlock.

In order to solve this I have to write On_Click as follows:

  def On_Click():
    gtk.gdk.threads_leave()
    buzy.cancel()
    buzy.join()
    gtk.gdk.threads_enter()


So here we have a litle event handler that doesn't the lock, but
that gets in anyway and not releasing the lock will cause a deadlock.

-- 
Antoon Pardon
_______________________________________________
pygtk mailing list   [email protected]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/

Reply via email to