On 12/02/2016 02:28 PM, Ted Gould wrote:
On Fri, 2016-12-02 at 12:58 -0200, Till Kamppeter wrote:
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.

Generally speaking the best way to do this is to use the mainloop itself
as the lock. The mainloop is always on a single thread, so you should
have the other threads put events into the main loop context and have
them operate there on the data structure. So you'd, for instance, get
all the information together on your Bonjour thread and when you're
ready to add it put an action on the main loop with all that information.

The functions you're probably looking for are (as starting points):

g_main_context_get_thread_default()
g_idle_source_new()
g_source_attach()


The way how cups-browsed works is the following:

First, a GMainLoop is created:

gmainloop = g_main_loop_new (NULL, FALSE);

Browsing for legacy CUPS broadcasts is attached to the mail loop via

    GIOChannel *browse_channel = g_io_channel_unix_new (browsesocket);
    g_io_channel_set_close_on_unref (browse_channel, FALSE);
    g_io_add_watch (browse_channel, G_IO_IN, process_browse_data, NULL);

Many other things are added via

g_idle_add ()

and

g_timeout_add_seconds ()

Reaction to D-Bus notifications is added via the

g_signal_connect()

function.

Avahi browsing is set up with these calls

    /* Allocate main loop object */
    if (!glib_poll)
      if (!(glib_poll = avahi_glib_poll_new(NULL, G_PRIORITY_DEFAULT)))
      {
        debug_printf("ERROR: Failed to create glib poll object.\n");
        goto avahi_init_fail;
      }

    /* Allocate a new client */
    if (!client)
      client = avahi_client_new(avahi_glib_poll_get(glib_poll),
                                AVAHI_CLIENT_NO_FAIL,
                                client_callback, NULL, &error);

    /* Check wether creating the client object succeeded */
    if (!client) {
      debug_printf("ERROR: Failed to create client: %s\n",
                   avahi_strerror(error));
      goto avahi_init_fail;
    }

Strange is that this Avahi browsing setup is done before creation of the main loop. Also some g_timeout_add_seconds () calls are done before creating the main loop.

After that, the main loop gets started via

g_main_loop_run (gmainloop);

My questions are now:

- Is this way everything attached to the main loop?

- Do I have to do function calls in the beginning and in the end of each callback function to acquire and release a lock? Which ones?

- If something of this is not attached to the main loop, how do I attach it?

I do not explicitly start any new threads.

   Till


--
ubuntu-devel mailing list
[email protected]
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/ubuntu-devel

Reply via email to