Possible to run multiple main loops?
Asked Answered
S

2

7

I'm working with both libfuse and the glib event interface and I've run into an issue where I need to run multiple main loops concurrently (glib's g_main_loop_run and fuse_loop_mt).

I've already attempted to created a detached thread for glib's event loop under a secondary context, e.g.:

static void *
event_loop(void *arg)
{
  GMainLoop *event_loop;
  GMainContext *context;    

  context = g_main_context_new();
  g_main_context_push_thread_default(context);
  event_loop = g_main_loop_new(context, FALSE);
  g_main_loop_run(event_loop);

  return NULL;
}

...

pthread_t event_thread;
pthread_attr_t thread_attr;
pthread_attr_init(&thread_attr);
pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
event_thread = pthread_create(&event_thread, &thread_attr,
    event_loop, NULL);

However the glib event loop doesn't pick up on any of the fired events. Am I totally off-base here? What's the proper way to tackle multiple main loops?

Seasonseasonable answered 16/12, 2011 at 3:37 Comment(2)
Best way I guess would be to avoid multiple main loops altogether if possible. Alternatively integrate the event loops so that you can use only one to receive and process events.Hengist
Unfortunately, that's not possible. I need the glib (libevent, etc..) interface to utilize the curl hiper interface. Fuse, for obvious reasons also needs a main loop.Seasonseasonable
T
4

The GLib main loop supports custom event sources. I don't know much about FUSE, but you might be able to run FUSE's main loop within another thread, and integrate its events into the GLib loop.

A quick search suggests that you might be able to use a lower-level FUSE API to write your own main loop, which could presumably be integrated more readily into GLib's by simply skipping the "loop" part.

In general, though, multiple main loops are just bad news; that's why they're called main loops. :) The best way to handle them is to eliminate them by hooking events directly into whatever loop works best for you. Unfortunately, not all APIs provide the sufficient hooks to make that possible.

Toweling answered 16/12, 2011 at 4:6 Comment(3)
+1 This is probably the best sensible way of doing it, but I would like to add some that if you are using linux eventfd or pipe would probably be good ways to send messages to the Glib main loop, as they return file descriptors that can be used almost directly with glib.Accuracy
Good point; it might even be preferable to fork() and run the FUSE (or GLib) main loop from there, without worrying about any problems with multi-threading.Toweling
Thanks, Ethan. I was afraid I might have to move to the low-level interface. Looks like it'll be a long day :)Seasonseasonable
H
5

Apart from setting up main loops in a separate thread or a process (from the little bit of experience I have had, separate process has worked better for me but then again thread might work well in your case), you can consider integrating fuse main loop in GLib's main loop (Unfortunately I have no prior experience with this). You can check this thread discussion about the same (in case you have not seen it already). As suggested at the end of the thread " Register the fuse device file descriptor (fuse_chan_fd()) with the glib event loop. Then call fuse_chan_recv() and fuse_session_process() when the event trigger". To track the fd you will need to use GIO(More info on Nokia developer page).
Hopefully this can provide some hints!

Hengist answered 16/12, 2011 at 13:26 Comment(1)
Thanks, this is also helpful.Seasonseasonable
T
4

The GLib main loop supports custom event sources. I don't know much about FUSE, but you might be able to run FUSE's main loop within another thread, and integrate its events into the GLib loop.

A quick search suggests that you might be able to use a lower-level FUSE API to write your own main loop, which could presumably be integrated more readily into GLib's by simply skipping the "loop" part.

In general, though, multiple main loops are just bad news; that's why they're called main loops. :) The best way to handle them is to eliminate them by hooking events directly into whatever loop works best for you. Unfortunately, not all APIs provide the sufficient hooks to make that possible.

Toweling answered 16/12, 2011 at 4:6 Comment(3)
+1 This is probably the best sensible way of doing it, but I would like to add some that if you are using linux eventfd or pipe would probably be good ways to send messages to the Glib main loop, as they return file descriptors that can be used almost directly with glib.Accuracy
Good point; it might even be preferable to fork() and run the FUSE (or GLib) main loop from there, without worrying about any problems with multi-threading.Toweling
Thanks, Ethan. I was afraid I might have to move to the low-level interface. Looks like it'll be a long day :)Seasonseasonable

© 2022 - 2024 — McMap. All rights reserved.