On Sun, Feb 08, 2004 at 05:13:06PM -0500, Dave Aitel wrote:
> Jeff Bowden wrote:
> 
> >Antoon Pardon wrote:
> >
> >>On Wed, Feb 04, 2004 at 09:54:11PM -0800, Jeff Bowden wrote:
> >> 
> >>
> >>>Jeff Bowden wrote:
> >>>
> >>>  
> >>>
> >>>>The basic idea is this:  You have some need in your pygtk app for 
> >>>>some code to run asynchronously in a seperate thread (the 
> >>>>"background task").   In order for it to be useful, you need two 
> >>>>way communication between the background task and your main thread 
> >>>>which handles all the GUI stuff.  e.g.
> >>>>
> >>>>class BackgroundTask(threading.Thread):
> >>>> def __init__(self):
> >>>>     threading.Thread.__init__(self)
> >>>>     self.in_q = Queue.Queue()
> >>>>     self.out_q = Queue.Queue()
> >>>>     self.die = False
> >>>>     # ...
> >>>>
> >>>> def run(self):
> >>>>     while not self.die:
> >>>>         args = self.in_q.get()
> >>>>         result = self.do_stuff(*args)
> >>>>         self.out_q.put(result)
> >>>>
> >>>>
> >>>>And then in your gtk idle function a fragment like this:
> >>>>
> >>>> if not background_task.out_q.empty():
> >>>>     result = background_task.out_q.get()
> >>>>
> >>>>     # do stuff with the result...
> >>>>
> >>>>And then in whatever part of your program that initiates background 
> >>>>tasks something like
> >>>>
> >>>> background_task.in_q.put(args)
> >>>>    
> >>>
> >>>
> >>>Oops.  I went back and looked at some of my code and realized I left 
> >>>out an important detail.  The problem with what I wrote above is 
> >>>that I said to put the out_q processing code in a gtk idle function 
> >>>and that implies _polling_ which is sooo wrong.
> >>>
> >>>What I end up doing in my code is creating a pipe with os.pipe,  
> >>>passing the write_end to the background task and passing the 
> >>>read_end to gtk.input_add.  When the background task wants to wake 
> >>>up with GUI thread, it writes a single char to the pipe using os.write.
> >>>
> >>>Unfortunately, I don't know if this will work on Microsoft Windows.  
> >>>I know that Windows python has os.pipe, but I have no idea if 
> >>>gtk.input_add on Windows will accept and work with a pipe endpoint.  
> >>>I don't have a windows machine here to test it out on.  Does anyone 
> >>>know about this?
> >>>

It should work, the os.pipe just returns MS CRT file descriptors which
the giochannel stuff is designed to use.
The glib win32 input stuff used blocking MSVCRT I/O calls for everything,
with a thread per iochannel. It seems like a waste to have another
thread just to block on I/O, especially given the alternative below.
> 
> I'm not sure, but it feels wrong to me to try to develop a portable 
> system based on signals...I'm planning on opening a local socket, and 
> then trapping any action on that socket with gtk.input_add() and having 
> it clear a queue full of actions in the GUI thread. I'll probably be 
> releasing this code sometime next week and, if there are no major 
> objectsion, adding it to the faq. I'd also like to track down the thread 
> synchronization issue in the destructor of gtk.glade and/or the 
> add_signals_dict call that is expressing itself on Windows. I'd like to 
> be able to recompile a dropline, if at all possible.
>

The socket idea is basically good, but undesirable I think
because there are no "Windows domain" sockets on Windows; you have
to use an AF_INET socket. This can cause problems with people that are
using personal firewall programs. 

Why don't you try the following:
http://www.luebsphoto.com/gsourcemodule.c

This small module allows you to add PollFDs directly to the mainloop. On
Windows, a PollFD is a HANDLE and the poll function is
MsgWaitForMultipleObjectsEx. This module is more desirable than using
input_add on Windows because 1) input_add uses a thread per file IIRC
and 2) input_add only works with sockets and MSVCRT file handles.

Using this module you could just wait on a Windows EVENT directly.
The EVENT could be one that you'll set explictly with SetEvent or from
an async I/O operation.

gsource.add works just like gtk.input_add, except it takes a PollFD,
which is just an fd on POSIX like environments and is a HANDLE on Win32.
A HANDLE, as you may know, can be a Mutex, Semaphore, Event, Process,
Thread, Timer, and a whole bunch of other crap. On Windows the
events/revents value is irrelevant, just set it to something non-zero.

--jkl
_______________________________________________
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