From: Steven Luo Date: Mon, 15 Feb 2010 01:58:53 +0000 (-0800) Subject: Avoid a race between MicroB startup and establishing D-Bus watch for it X-Git-Tag: fremantle-package-3.1-2fremantle4~2 X-Git-Url: http://git.maemo.org/git/?p=browser-switch;a=commitdiff_plain;h=807b507a9f6cc3be8f12d68f7849da970652a9a6 Avoid a race between MicroB startup and establishing D-Bus watch for it As it stands, the establishment of the D-Bus match and filter for the acquisition of com.nokia.osso_browser happens in parallel with MicroB startup; as a result, it's possible that MicroB could acquire the name before we're ready to look for the event, which results in us waiting forever for MicroB to start (even though it's already started). Avoid this by establishing the watch before we fork a child process. Possibly fixes a rare failure mode reported by Faheem Pervez (qwerty12). --- diff --git a/launcher.c b/launcher.c index 10ff41b..09428a9 100644 --- a/launcher.c +++ b/launcher.c @@ -228,6 +228,41 @@ void launch_microb(struct swb_context *ctx, char *uri) { } free(microb_profile_dir); + /* Set up the D-Bus eavesdropping we'll use to watch for MicroB + acquiring the com.nokia.osso_browser D-Bus name. Again, this needs + to happen before the browser is launched, so that there's no race + between establishing the watch and browser startup. + + Ideas for how to do this monitoring derived from the dbus-monitor + code (tools/dbus-monitor.c in the D-Bus codebase). */ + dbus_error_init(&dbus_error); + + raw_connection = dbus_bus_get_private(DBUS_BUS_SESSION, &dbus_error); + if (!raw_connection) { + fprintf(stderr, + "Failed to open connection to session bus: %s\n", + dbus_error.message); + dbus_error_free(&dbus_error); + exit(1); + } + + dbus_bus_add_match(raw_connection, + "type='signal',interface='org.freedesktop.DBus',member='NameOwnerChanged',arg0='com.nokia.osso_browser'", + &dbus_error); + if (dbus_error_is_set(&dbus_error)) { + fprintf(stderr, + "Failed to set up watch for browser UI start: %s\n", + dbus_error.message); + dbus_error_free(&dbus_error); + exit(1); + } + filter_func = check_microb_started; + if (!dbus_connection_add_filter(raw_connection, + filter_func, NULL, NULL)) { + fprintf(stderr, "Failed to set up watch filter!\n"); + exit(1); + } + if ((pid = fork()) == -1) { perror("fork"); exit(1); @@ -238,40 +273,8 @@ void launch_microb(struct swb_context *ctx, char *uri) { /* Wait for our child to start the browser UI process and for it to acquire the com.nokia.osso_browser D-Bus name, then make the appropriate method call to open the browser - window. - - Ideas for how to do this monitoring derived from the - dbus-monitor code (tools/dbus-monitor.c in the D-Bus - codebase). */ + window. */ microb_started = 0; - dbus_error_init(&dbus_error); - - raw_connection = dbus_bus_get_private(DBUS_BUS_SESSION, - &dbus_error); - if (!raw_connection) { - fprintf(stderr, - "Failed to open connection to session bus: %s\n", - dbus_error.message); - dbus_error_free(&dbus_error); - exit(1); - } - - dbus_bus_add_match(raw_connection, - "type='signal',interface='org.freedesktop.DBus',member='NameOwnerChanged',arg0='com.nokia.osso_browser'", - &dbus_error); - if (dbus_error_is_set(&dbus_error)) { - fprintf(stderr, - "Failed to set up watch for browser UI start: %s\n", - dbus_error.message); - dbus_error_free(&dbus_error); - exit(1); - } - filter_func = check_microb_started; - if (!dbus_connection_add_filter(raw_connection, - filter_func, NULL, NULL)) { - fprintf(stderr, "Failed to set up watch filter!\n"); - exit(1); - } printf("Waiting for MicroB to start\n"); while (!microb_started && dbus_connection_read_write_dispatch(raw_connection, @@ -455,6 +458,8 @@ void launch_microb(struct swb_context *ctx, char *uri) { } } else { /* Child process */ + dbus_connection_close(raw_connection); + dbus_connection_unref(raw_connection); close(fd); close_stdio();