QEventDispatcherGlibPrivate::QEventDispatcherGlibPrivate(GMainContext *context) : mainContext(context) { if (qgetenv("QT_NO_THREADED_GLIB").isEmpty()) { #if GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION < 32 static int dummyValue = 0; // only used for its address QMutexLocker locker(QMutexPool::instance()->get(&dummyValue)); if (!g_thread_supported()) g_thread_init(NULL); #else } else { qWarning("QEventDispatcherGlib: it is not possible to disable GLib threading"); #endif } if (mainContext) { g_main_context_ref(mainContext); } else { QCoreApplication *app = QCoreApplication::instance(); if (app && QThread::currentThread() == app->thread()) { mainContext = g_main_context_default(); g_main_context_ref(mainContext); } else { mainContext = g_main_context_new(); } } #if GLIB_CHECK_VERSION (2, 22, 0) g_main_context_push_thread_default (mainContext); #endif // setup post event source postEventSource = reinterpret_cast<GPostEventSource *>(g_source_new(&postEventSourceFuncs, sizeof(GPostEventSource))); postEventSource->serialNumber = 1; postEventSource->d = this; g_source_set_can_recurse(&postEventSource->source, true); g_source_attach(&postEventSource->source, mainContext); // setup socketNotifierSource socketNotifierSource = reinterpret_cast<GSocketNotifierSource *>(g_source_new(&socketNotifierSourceFuncs, sizeof(GSocketNotifierSource))); (void) new (&socketNotifierSource->pollfds) QList<GPollFDWithQSocketNotifier *>(); g_source_set_can_recurse(&socketNotifierSource->source, true); g_source_attach(&socketNotifierSource->source, mainContext); // setup normal and idle timer sources timerSource = reinterpret_cast<GTimerSource *>(g_source_new(&timerSourceFuncs, sizeof(GTimerSource))); (void) new (&timerSource->timerList) QTimerInfoList(); timerSource->processEventsFlags = QEventLoop::AllEvents; timerSource->runWithIdlePriority = false; g_source_set_can_recurse(&timerSource->source, true); g_source_attach(&timerSource->source, mainContext); idleTimerSource = reinterpret_cast<GIdleTimerSource *>(g_source_new(&idleTimerSourceFuncs, sizeof(GIdleTimerSource))); idleTimerSource->timerSource = timerSource; g_source_set_can_recurse(&idleTimerSource->source, true); g_source_set_priority(&idleTimerSource->source, G_PRIORITY_DEFAULT_IDLE); g_source_attach(&idleTimerSource->source, mainContext); }
void gvfs_udisks2_utils_spawn (guint timeout_seconds, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data, const gchar *command_line_format, ...) { va_list var_args; SpawnData *data; GError *error; gint child_argc; gchar **child_argv = NULL; data = g_slice_new0 (SpawnData); data->simple = g_simple_async_result_new (NULL, callback, user_data, gvfs_udisks2_utils_spawn); data->main_context = g_main_context_get_thread_default (); if (data->main_context != NULL) g_main_context_ref (data->main_context); data->cancellable = cancellable != NULL ? g_object_ref (cancellable) : NULL; va_start (var_args, command_line_format); data->command_line = g_strdup_vprintf (command_line_format, var_args); va_end (var_args); data->child_stdout = g_string_new (NULL); data->child_stderr = g_string_new (NULL); data->child_stdout_fd = -1; data->child_stderr_fd = -1; /* the life-cycle of SpawnData is tied to its GSimpleAsyncResult */ g_simple_async_result_set_op_res_gpointer (data->simple, data, (GDestroyNotify) spawn_data_free); error = NULL; if (data->cancellable != NULL) { /* could already be cancelled */ error = NULL; if (g_cancellable_set_error_if_cancelled (data->cancellable, &error)) { g_simple_async_result_take_error (data->simple, error); g_simple_async_result_complete_in_idle (data->simple); g_object_unref (data->simple); goto out; } data->cancellable_handler_id = g_cancellable_connect (data->cancellable, G_CALLBACK (on_cancelled), data, NULL); } error = NULL; if (!g_shell_parse_argv (data->command_line, &child_argc, &child_argv, &error)) { g_prefix_error (&error, "Error parsing command-line `%s': ", data->command_line); g_simple_async_result_take_error (data->simple, error); g_simple_async_result_complete_in_idle (data->simple); g_object_unref (data->simple); goto out; } error = NULL; if (!g_spawn_async_with_pipes (NULL, /* working directory */ child_argv, NULL, /* envp */ G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, NULL, /* child_setup */ NULL, /* child_setup's user_data */ &(data->child_pid), NULL, /* gint *stdin_fd */ &(data->child_stdout_fd), &(data->child_stderr_fd), &error)) { g_prefix_error (&error, "Error spawning command-line `%s': ", data->command_line); g_simple_async_result_take_error (data->simple, error); g_simple_async_result_complete_in_idle (data->simple); g_object_unref (data->simple); goto out; } if (timeout_seconds > 0) { data->timeout_source = g_timeout_source_new_seconds (timeout_seconds); g_source_set_priority (data->timeout_source, G_PRIORITY_DEFAULT); g_source_set_callback (data->timeout_source, timeout_cb, data, NULL); g_source_attach (data->timeout_source, data->main_context); g_source_unref (data->timeout_source); } data->child_watch_source = g_child_watch_source_new (data->child_pid); g_source_set_callback (data->child_watch_source, (GSourceFunc) child_watch_cb, data, NULL); g_source_attach (data->child_watch_source, data->main_context); g_source_unref (data->child_watch_source); data->child_stdout_channel = g_io_channel_unix_new (data->child_stdout_fd); g_io_channel_set_flags (data->child_stdout_channel, G_IO_FLAG_NONBLOCK, NULL); data->child_stdout_source = g_io_create_watch (data->child_stdout_channel, G_IO_IN); g_source_set_callback (data->child_stdout_source, (GSourceFunc) read_child_stdout, data, NULL); g_source_attach (data->child_stdout_source, data->main_context); g_source_unref (data->child_stdout_source); data->child_stderr_channel = g_io_channel_unix_new (data->child_stderr_fd); g_io_channel_set_flags (data->child_stderr_channel, G_IO_FLAG_NONBLOCK, NULL); data->child_stderr_source = g_io_create_watch (data->child_stderr_channel, G_IO_IN); g_source_set_callback (data->child_stderr_source, (GSourceFunc) read_child_stderr, data, NULL); g_source_attach (data->child_stderr_source, data->main_context); g_source_unref (data->child_stderr_source); out: g_strfreev (child_argv); }