OK.  Without going into details (will later), the fault lies with
pygtk 0.6.9.

I grabbed pygnome-1.4.4 (pygtk 0.6.11) and built it, etcc...

Some very minor tweakage and it works perfectly!
I had to use gtk._disable_gdk_threading() before I called mainloop,
but that wasn't necessary.  For my testing, I had disabled *all*
threading hooha, slowly adding everything back as I encounterd success
after success (after installing pygtk 0.6.11.)

Yay!

Thanks to everyone, esp. Christian.

John K Leubs - thanks for trying to help.  However, your test app (and
even ones a bit more complex) don't appear to trigger the bug.  Part of
me is inclined to determine what the bug actually is, the other part of
me wants to write it off and forget it.  I am *convinced* the bug is in
pygtk (or rather, was in 0.6.9).

Gotta run!

On Thu, 13 Mar 2003, John K Luebs wrote:

> On Wed, Mar 12, 2003 at 07:58:58AM -0600, Jon Nelson wrote:
> > On Wed, 12 Mar 2003, John K Luebs wrote:
> >
> > > On Tue, Mar 11, 2003 at 09:15:06AM -0600, Jon Nelson wrote:
> > > > Did anybody come up with anything better than this?
> > > >
> > > > In the callback which was used in input_add:
> > > >
> > > >     old = gtk.events_pending
> > > >     def duh(*args):
> > > >       return 0
> > > >     gtk.events_pending = duh
> > > >     self.do_real_work_with_data_read_from_file(data_read_from_file)
> > > >     gtk.events_pending = old
> > > >
> > > > for this problem?
> > > >
> > > > The reason this appears necessary is explained below.
> > > > *Somebody* has a better solution, I'm sure of it!
> > >
> > > This seems really silly.
> > > If you're gonna f up events_pending in this way, then that means you are
> > > not going to ever pump the gtk event queue. If you really don't need to
> > > call mainiteration, then why don't you just remove the whole
> > > while gtk.events_pending(): gtk.mainiteration nonsense.
> >
> > Actually, it means that gtk.events_pending() will always return 0 while
> > the function self.do_real_work_with_data_read_from_file is being run.
>
> My point being that if you're going to nullify the gtk.events_pending
> test, then that will reduce to :
>
> while 0: gtk.mainiteration()
>
> which of course is a no-op.
>
> >
> > > Now the problem that you are running into is that select()/poll() and
> > > the glib FD polling mechanism are all level sensitive. When you
> > > input_add your fd, you are going to be notified whenever a read will not
> > > block. This means that if the OS had buffered 200 bytes, you were
> > > notified and only read 100 bytes, you will get the event again. Realize,
> > > that this is basically a good design, don't fight it.
> >
> > I am quite aware of how select looping works.  If you had read the whole
> > thread (which it's clear you haven't) you would know that there is a
> > fundamental problem with timeout, I/O, and idle event functions -- they
> > can't do this:
>
> Well, I did read the whole thread, but I forgot the details of what you
> had tried. That doesn't necessarily mean I am wrong. I don't believe
> there is the problem you allude to. This view comes from experience. In
> the past, I have had very little trouble with these parts of GTK+. I
> have had a lot more trouble with my own code. Based on the evidence you
> have provided I still suspect the problem is in your code, not GTK+.
>
> Of course, it is entirely possible there is a problem in your particular
> versions of GTK+/pyGTK. Let's see.
>
> >
> > while events.pending():
> >   gtk.mainiteration()
> >
> > And the reason is that timeout, I/O, and idle events will get called,
> > again, in the nested mainiteration (if appropriate).  Additionally,
> > using the gtk I/O monitoring functions to remove the callback *in* the
> > callback doesn't appear to work, because it's entirely possible that
> > data arrives for the file *after* the read operation.
>
> Unfortunately, I can't reproduce your problem. Try this script, and see
> what happens. If it works as I describe, then you have a bug in your
> code. If it doesn't, then there is some change between 0.6.11 (highly
> unlikely because this stuff is handled in GTK+) and 0.6.9 or between
> GTK+ 1.2.10 and whatever you're using. This is again very unlikely. I
> feel it's unlikely, because I looked around at the old GTK+ 1.2.7-1.2.10
> revs in CVS and I could find no "interesting" changes to the mainloop
> implementation.
>
> Here is the script to try:
>
> <<CUT HERE>>
>
> import gtk
> import os
>
> def in_avail(cond, fd):
>     print "in_avail"
>     #gtk.input_remove(ia)
>     while gtk.events_pending(): gtk.mainiteration()
>
> p = os.popen('yes', 'r')
> ia = gtk.input_add(p.fileno(), gtk.GDK.INPUT_READ, in_avail)
>
> gtk.mainloop()
>
> <<CUT HERE>>
>
>
> I open a pipe to yes which will give me the input condition. When I
> have the input_remove line commented, in_avail will be reentered with
> each mainiteration, and it is only a few milliseconds before I get
> screenfulls of Maximum Recursion exceptions. Unbounded reentrancy, that
> is.
>
> Now, uncomment the input_remove line. What that will do is disconnect
> the "connection" between the read condition (which will still exist if
> it is poll/selected) and the callback in_avail. Doing that, you should
> get "in_avail" printed, and the program should stop dead, because there
> are no pending events and there never will be in this cruddy little
> program.
>
> I tested this with pygtk 0.6.11, GTK+ 1.2.10, and it works as I
> described, which how it should according to the docs.
>
> --jkl
>

--
"Never try to write to ROM - it wastes your time and annoys the ROM."

Jon Nelson <[EMAIL PROTECTED]>
C and Python Code Gardener
_______________________________________________
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