Friday, 2 December 2016

cups-browsed uses GMainLoop and global variables, how to introduce locks against race conditions?


cups-browsed is a daemon which automatically creates local print queues
when it discovers remote printers on the network.

For this it has to observe different sources for appropriate events:

- Bonjour: For IPP network printers and for remote CUPS queues of CUPS
1.6.x or newer
- Legacy CUPS broadcasts: For remote CUPS queues of CUPS 1.5.x or older
- D-Bus notifications: For load-balancing and maintenance of the local

In addition, timeouts are used to repeat failed attempts of creating and
taking down queues, to wait until all jobs are printed before
auto-shutdown, for expiring legacy CUPS queues, ...

All this is managed via a GLib GMainLoop and the list of discovered
printers is held in a global variable.

Now there come error reports from time to time, reporting crashes of
cups-browsed and as I did not find any problem with memory allocation
and freeing for the data structure I am assuming that the problem is
missing locking.

Probably (I am not sure how it works exactly) events like appearing or
disappearing printers, legacy CUPS broadcasts, ... make the main loop
starting threads to treat the events appropriately, as for example
adding and removing printers in the list of discovered printers.

Here probably race conditions come up when events happen close to each
other and the printer list gets manipulated by various threads at the
same time.

The solution would be to acquire a lock when starting to manipulate the
printer list and releasing the lock when done.

Now my qestion is, which functions I have to use for acquiring and
releasing locks when using GLib and GMainLoop? Probably it is not
correct to use the locks of pthread. Also it is probably best to use
Read/Write locks where only writing is exclusive but reading is allowed
to more than one thread at a time.

Any kind of help is welcome.


ubuntu-devel mailing list
Modify settings or unsubscribe at: