Wed 1 Mar 2006
In the course of writing various bits of EggPrintOperation I have have had to learn how various bits of GLib work that I would have never needed to know as an applications developer. One such crash course was in the magic and mystery of a GSource. These little buggers are integration points into the GMainLoop. Whenever you create a timeout or an idle handler you are creating a source.
Well I needed to create my very own source to step through the states of talking to the cups server without blocking. Hooking everything up wasn’t too hard. You fill in a structure with your prepare, check, dispatch and finalize functions, “subclass” the source stuct so you can keep state information and attach the source to your mainloop. The functions get called in a particular order each time mainloop is run. That is the simplified explanation.
Doing that I was able to successfully get printer information and print to a selected printer. Of course for a 3 meg postscript file being written in 8k chunks it was taking 9 seconds to send to the local cups queue over an http socket.
Alex then pointed me to the g_source_add_poll method which allows you to add a file descriptor and some flags that will cause the check function to be called whenever the fd can be written to or read from depending on what flags you set. Adding a poll for the http connection’s file descriptor when we are writing took that 9 seconds down to about 1/3 of a second.
w/o polling:
write #0: 1141230805.220s
write #366: 1141230814.228s
delta: 9.008s
w/ polling:
write #0: 1141230516.298s
write #366: 1141230516.609s
delta: 0.311s
Nothing all that spectacular but it is pretty fun starting to get a lower level view of how things work.
[read this post in: ar de es fr it ja ko pt ru zh-CN ]
March 2nd, 2006 at 3:59 am
Just wondering why you aren’t using a GIOChannel and g_io_create_watch(). But I don’t know the CUPS server/client protocol good enough to judge if that would work at all and if it would be more elegant or not.
March 2nd, 2006 at 10:23 am
Partially because I didn’t know about GIOChannels but mostly because Matthias Clausen told me to use a GSource. GIOChannel looks just like a simplification of the GSource API and most likely is not flexable enough for what I needed it for. For instance I only attach to the socket at the data stage of both the GET and the POST methods. Using a GSource just gives me more flexability.