/** * g_cancellable_make_pollfd: * @cancellable: (allow-none): a #GCancellable or %NULL * @pollfd: a pointer to a #GPollFD * * Creates a #GPollFD corresponding to @cancellable; this can be passed * to g_poll() and used to poll for cancellation. This is useful both * for unix systems without a native poll and for portability to * windows. * * When this function returns %TRUE, you should use * g_cancellable_release_fd() to free up resources allocated for the * @pollfd. After a %FALSE return, do not call g_cancellable_release_fd(). * * If this function returns %FALSE, either no @cancellable was given or * resource limits prevent this function from allocating the necessary * structures for polling. (On Linux, you will likely have reached * the maximum number of file descriptors.) The suggested way to handle * these cases is to ignore the @cancellable. * * You are not supposed to read from the fd yourself, just check for * readable status. Reading to unset the readable status is done * with g_cancellable_reset(). * * Returns: %TRUE if @pollfd was successfully initialized, %FALSE on * failure to prepare the cancellable. * * Since: 2.22 **/ gboolean g_cancellable_make_pollfd (GCancellable *cancellable, GPollFD *pollfd) { g_return_val_if_fail (pollfd != NULL, FALSE); if (cancellable == NULL) return FALSE; g_return_val_if_fail (G_IS_CANCELLABLE (cancellable), FALSE); g_mutex_lock (&cancellable_mutex); cancellable->priv->fd_refcount++; if (cancellable->priv->wakeup == NULL) { cancellable->priv->wakeup = GLIB_PRIVATE_CALL (g_wakeup_new) (); if (cancellable->priv->cancelled) GLIB_PRIVATE_CALL (g_wakeup_signal) (cancellable->priv->wakeup); } GLIB_PRIVATE_CALL (g_wakeup_get_pollfd) (cancellable->priv->wakeup, pollfd); g_mutex_unlock (&cancellable_mutex); return TRUE; }
/** * g_cancellable_reset: * @cancellable: a #GCancellable object. * * Resets @cancellable to its uncancelled state. * * If cancellable is currently in use by any cancellable operation * then the behavior of this function is undefined. **/ void g_cancellable_reset (GCancellable *cancellable) { GCancellablePrivate *priv; g_return_if_fail (G_IS_CANCELLABLE (cancellable)); g_mutex_lock (&cancellable_mutex); priv = cancellable->priv; while (priv->cancelled_running) { priv->cancelled_running_waiting = TRUE; g_cond_wait (&cancellable_cond, &cancellable_mutex); } if (priv->cancelled) { if (priv->wakeup) GLIB_PRIVATE_CALL (g_wakeup_acknowledge) (priv->wakeup); priv->cancelled = FALSE; } g_mutex_unlock (&cancellable_mutex); }
static gboolean g_fam_file_monitor_is_supported (void) { g_mutex_lock (&fam_lock); if (!fam_initialised) { fam_initialised = FAMOpen2 (&fam_connection, "GLib GIO") == 0; if (fam_initialised) { #ifdef HAVE_FAM_NO_EXISTS /* This is a gamin extension that avoids sending all the * Exists event for dir monitors */ FAMNoExists (&fam_connection); #endif fam_source = g_unix_fd_source_new (FAMCONNECTION_GETFD (&fam_connection), G_IO_IN); g_source_set_callback (fam_source, (GSourceFunc) g_fam_file_monitor_callback, NULL, NULL); g_source_attach (fam_source, GLIB_PRIVATE_CALL(g_get_worker_context) ()); } } g_mutex_unlock (&fam_lock); g_print ("II %d\n", fam_initialised); return fam_initialised; }
static void g_cancellable_finalize (GObject *object) { GCancellable *cancellable = G_CANCELLABLE (object); if (cancellable->priv->wakeup) GLIB_PRIVATE_CALL (g_wakeup_free) (cancellable->priv->wakeup); G_OBJECT_CLASS (g_cancellable_parent_class)->finalize (object); }
/** * g_cancellable_cancel: * @cancellable: a #GCancellable object. * * Will set @cancellable to cancelled, and will emit the * #GCancellable::cancelled signal. (However, see the warning about * race conditions in the documentation for that signal if you are * planning to connect to it.) * * This function is thread-safe. In other words, you can safely call * it from a thread other than the one running the operation that was * passed the @cancellable. * * The convention within gio is that cancelling an asynchronous * operation causes it to complete asynchronously. That is, if you * cancel the operation from the same thread in which it is running, * then the operation's #GAsyncReadyCallback will not be invoked until * the application returns to the main loop. **/ void g_cancellable_cancel (GCancellable *cancellable) { GCancellablePrivate *priv; if (cancellable == NULL || cancellable->priv->cancelled) return; priv = cancellable->priv; g_mutex_lock (&cancellable_mutex); if (priv->cancelled) { g_mutex_unlock (&cancellable_mutex); return; } priv->cancelled = TRUE; priv->cancelled_running = TRUE; if (priv->wakeup) GLIB_PRIVATE_CALL (g_wakeup_signal) (priv->wakeup); g_mutex_unlock (&cancellable_mutex); g_object_ref (cancellable); g_signal_emit (cancellable, signals[CANCELLED], 0); g_mutex_lock (&cancellable_mutex); priv->cancelled_running = FALSE; if (priv->cancelled_running_waiting) g_cond_broadcast (&cancellable_cond); priv->cancelled_running_waiting = FALSE; g_mutex_unlock (&cancellable_mutex); g_object_unref (cancellable); }
/** * g_cancellable_release_fd: * @cancellable: a #GCancellable * * Releases a resources previously allocated by g_cancellable_get_fd() * or g_cancellable_make_pollfd(). * * For compatibility reasons with older releases, calling this function * is not strictly required, the resources will be automatically freed * when the @cancellable is finalized. However, the @cancellable will * block scarce file descriptors until it is finalized if this function * is not called. This can cause the application to run out of file * descriptors when many #GCancellables are used at the same time. * * Since: 2.22 **/ void g_cancellable_release_fd (GCancellable *cancellable) { GCancellablePrivate *priv; if (cancellable == NULL) return; g_return_if_fail (G_IS_CANCELLABLE (cancellable)); g_return_if_fail (cancellable->priv->fd_refcount > 0); priv = cancellable->priv; g_mutex_lock (&cancellable_mutex); priv->fd_refcount--; if (priv->fd_refcount == 0) { GLIB_PRIVATE_CALL (g_wakeup_free) (priv->wakeup); priv->wakeup = NULL; } g_mutex_unlock (&cancellable_mutex); }
/* inotify_lock must be held before calling */ void _im_add (inotify_sub *sub) { if (g_list_find (missing_sub_list, sub)) { IM_W ("asked to add %s to missing list but it's already on the list!\n", sub->dirname); return; } IM_W ("adding %s to missing list\n", sub->dirname); missing_sub_list = g_list_prepend (missing_sub_list, sub); /* If the timeout is turned off, we turn it back on */ if (!scan_missing_running) { GSource *source; scan_missing_running = TRUE; source = g_timeout_source_new_seconds (SCAN_MISSING_TIME); g_source_set_callback (source, im_scan_missing, NULL, NULL); g_source_attach (source, GLIB_PRIVATE_CALL (g_get_worker_context) ()); g_source_unref (source); } }
static gchar * get_session_address_dbus_launch (GError **error) { gchar *ret; gchar *machine_id; gchar *command_line; gchar *launch_stdout; gchar *launch_stderr; gint exit_status; gchar *old_dbus_verbose; gboolean restore_dbus_verbose; ret = NULL; machine_id = NULL; command_line = NULL; launch_stdout = NULL; launch_stderr = NULL; restore_dbus_verbose = FALSE; old_dbus_verbose = NULL; /* Don't run binaries as root if we're setuid. */ if (GLIB_PRIVATE_CALL (g_check_setuid) ()) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Cannot spawn a message bus when setuid")); goto out; } machine_id = _g_dbus_get_machine_id (error); if (machine_id == NULL) { g_prefix_error (error, _("Cannot spawn a message bus without a machine-id: ")); goto out; } /* We're using private libdbus facilities here. When everything * (X11, Mac OS X, Windows) is spec'ed out correctly (not even the * X11 property is correctly documented right now) we should * consider using the spec instead of dbus-launch. * * --autolaunch=MACHINEID * This option implies that dbus-launch should scan for a previ‐ * ously-started session and reuse the values found there. If no * session is found, it will start a new session. The --exit-with- * session option is implied if --autolaunch is given. This option * is for the exclusive use of libdbus, you do not want to use it * manually. It may change in the future. */ /* TODO: maybe provide a variable for where to look for the dbus-launch binary? */ command_line = g_strdup_printf ("dbus-launch --autolaunch=%s --binary-syntax --close-stderr", machine_id); if (G_UNLIKELY (_g_dbus_debug_address ())) { _g_dbus_debug_print_lock (); g_print ("GDBus-debug:Address: Running '%s' to get bus address (possibly autolaunching)\n", command_line); old_dbus_verbose = g_strdup (g_getenv ("DBUS_VERBOSE")); restore_dbus_verbose = TRUE; g_setenv ("DBUS_VERBOSE", "1", TRUE); _g_dbus_debug_print_unlock (); } if (!g_spawn_command_line_sync (command_line, &launch_stdout, &launch_stderr, &exit_status, error)) { goto out; } if (!g_spawn_check_exit_status (exit_status, error)) { g_prefix_error (error, _("Error spawning command line '%s': "), command_line); goto out; } /* From the dbus-launch(1) man page: * * --binary-syntax Write to stdout a nul-terminated bus address, * then the bus PID as a binary integer of size sizeof(pid_t), * then the bus X window ID as a binary integer of size * sizeof(long). Integers are in the machine's byte order, not * network byte order or any other canonical byte order. */ ret = g_strdup (launch_stdout); out: if (G_UNLIKELY (_g_dbus_debug_address ())) { gchar *s; _g_dbus_debug_print_lock (); g_print ("GDBus-debug:Address: dbus-launch output:"); if (launch_stdout != NULL) { s = _g_dbus_hexdump (launch_stdout, strlen (launch_stdout) + 1 + sizeof (pid_t) + sizeof (long), 2); g_print ("\n%s", s); g_free (s); } else { g_print (" (none)\n"); } g_print ("GDBus-debug:Address: dbus-launch stderr output:"); if (launch_stderr != NULL) g_print ("\n%s", launch_stderr); else g_print (" (none)\n"); _g_dbus_debug_print_unlock (); } g_free (machine_id); g_free (command_line); g_free (launch_stdout); g_free (launch_stderr); if (G_UNLIKELY (restore_dbus_verbose)) { if (old_dbus_verbose != NULL) g_setenv ("DBUS_VERBOSE", old_dbus_verbose, TRUE); else g_unsetenv ("DBUS_VERBOSE"); } g_free (old_dbus_verbose); return ret; }