Re: [pygtk] Problem with GtkExtra and input_add

1999-09-18 Thread Andreas Degert

claude [EMAIL PROTECTED] writes:

 With  pygtk-0.6.2 the following script  freezes  pygtk
[...]
 def input_funct1(fp,condition):
 global inputf

  threads_enter()

 lut = fp.readline()
 fp.close
 input_remove(inputf)
 message(['Message',"Message Hello"])

  threads_leave()

Does your program work when you add those 2 statements? We had a
discussion about (i think) a similar problem on this list some time
ago.

In my understanding, the problem seems to be the strange way gtk is
made thread-safe, and the way pygtk is handling this. I'll try to
explain how i understand it.

In a multithreaded gtk-program, one step is to initialize the
threading-support of gtk (g_thread_init()). Then, when calling gtk
code, it has to be braced with gdk_threads_enter/leave:

gdk_threads_enter();
gtk_main();
gdk_threads_leave();

..._enter() grabs a semaphore, and ..._leave() releases it. In
gtk_main(), the semaphore is released for most of the event handling,
and sometimes grabbed in the widged code to secure critical sections.

Normally, you only call g_thread_init() when you have a threaded
program, so in a single-threaded program you don't have this coding-
(and runtime-) overhead. In a multi-threaded program, you have to work 
to make it thread-safe anyhow, so these extra calls are not a big
deal.

In pygtk, g_thread_init() is called always when thread support is
compiled in, which is what most distributions are doing now. Now,
semaphores are used by gtk, but in a single-threaded python program
the calls won't normally be braced by enter/leave like shown
above. This seems to work most times, though in gtk_main() the
semaphore is released without being held, and on exit its held (though
it was not on entry).

When you use a modal window in a callback function triggered by
input_add, gtk_main() is called (recursively) and holds the semaphore
on exit (when you click on the cancel button of the message window),
but we are still in the event loop of the outer gtk_main, where the
semaphore shouldn't be held. Now on the next occasion when someone
tries to grab the semaphore, the program freezes.

I hope James is listening... I think the gtk threading shouldn't be
initialized unconditionally in pygtk. One possibility would be to wrap
it in a python function, so threading would have to be initialized
explicitely when needed. Maybe this solution is a problem for existing
code. Another idea would be to initialize it on the first call to
threads_enter().

Another idea would be to brace calls to gtk_main with enter/leave in
gtkmodule.c (I think there are 2 other gtk functions which should be
handled similarly). The pygtk-program would then still be responsible
to call enter/leave for direct calls into gtk from other threads, and
maybe its not as obvious then because one didn't use the semaphore
explicitly in the main thread.

IMHO either way would be better than to fiddle with locking functions
in a single-threaded program to prevent a deadlock.

ciao
Andreas
To unsubscribe: echo "unsubscribe" | mail [EMAIL PROTECTED]



Re: [pygtk] Problem with GtkExtra and input_add

1999-09-18 Thread James Henstridge

I will send in a bug report to the GTK guys about this, so they can fix
it.  I would expect that the bug falls under the same category as the
other threading related ones found earlier on the list.

James.

--
Email: [EMAIL PROTECTED]
WWW:   http://www.daa.com.au/~james/


On 19 Sep 1999, Andreas Degert wrote:

 claude [EMAIL PROTECTED] writes:
 
  With  pygtk-0.6.2 the following script  freezes  pygtk
 [...]
  def input_funct1(fp,condition):
  global inputf
 
   threads_enter()
 
  lut = fp.readline()
  fp.close
  input_remove(inputf)
  message(['Message',"Message Hello"])
 
   threads_leave()
 
 Does your program work when you add those 2 statements? We had a
 discussion about (i think) a similar problem on this list some time
 ago.
 
 In my understanding, the problem seems to be the strange way gtk is
 made thread-safe, and the way pygtk is handling this. I'll try to
 explain how i understand it.
 
 In a multithreaded gtk-program, one step is to initialize the
 threading-support of gtk (g_thread_init()). Then, when calling gtk
 code, it has to be braced with gdk_threads_enter/leave:
 
 gdk_threads_enter();
 gtk_main();
 gdk_threads_leave();
 
 ..._enter() grabs a semaphore, and ..._leave() releases it. In
 gtk_main(), the semaphore is released for most of the event handling,
 and sometimes grabbed in the widged code to secure critical sections.
 
 Normally, you only call g_thread_init() when you have a threaded
 program, so in a single-threaded program you don't have this coding-
 (and runtime-) overhead. In a multi-threaded program, you have to work 
 to make it thread-safe anyhow, so these extra calls are not a big
 deal.
 
 In pygtk, g_thread_init() is called always when thread support is
 compiled in, which is what most distributions are doing now. Now,
 semaphores are used by gtk, but in a single-threaded python program
 the calls won't normally be braced by enter/leave like shown
 above. This seems to work most times, though in gtk_main() the
 semaphore is released without being held, and on exit its held (though
 it was not on entry).
 
 When you use a modal window in a callback function triggered by
 input_add, gtk_main() is called (recursively) and holds the semaphore
 on exit (when you click on the cancel button of the message window),
 but we are still in the event loop of the outer gtk_main, where the
 semaphore shouldn't be held. Now on the next occasion when someone
 tries to grab the semaphore, the program freezes.
 
 I hope James is listening... I think the gtk threading shouldn't be
 initialized unconditionally in pygtk. One possibility would be to wrap
 it in a python function, so threading would have to be initialized
 explicitely when needed. Maybe this solution is a problem for existing
 code. Another idea would be to initialize it on the first call to
 threads_enter().
 
 Another idea would be to brace calls to gtk_main with enter/leave in
 gtkmodule.c (I think there are 2 other gtk functions which should be
 handled similarly). The pygtk-program would then still be responsible
 to call enter/leave for direct calls into gtk from other threads, and
 maybe its not as obvious then because one didn't use the semaphore
 explicitly in the main thread.
 
 IMHO either way would be better than to fiddle with locking functions
 in a single-threaded program to prevent a deadlock.
 
 ciao
 Andreas
 To unsubscribe: echo "unsubscribe" | mail [EMAIL PROTECTED]
 

To unsubscribe: echo "unsubscribe" | mail [EMAIL PROTECTED]