/** * mate_bg_crossfade_start: * @fade: a #MateBGCrossfade * @window: The #GdkWindow to draw crossfade on * * This function initiates a quick crossfade between two surfaces on * the background of @window. Before initiating the crossfade both * mate_bg_crossfade_set_start_surface() and * mate_bg_crossfade_set_end_surface() need to be called. If animations * are disabled, the crossfade is skipped, and the window background is * set immediately to the end surface. **/ void mate_bg_crossfade_start (MateBGCrossfade *fade, GdkWindow *window) { GSource *source; GMainContext *context; g_return_if_fail (MATE_IS_BG_CROSSFADE (fade)); g_return_if_fail (window != NULL); g_return_if_fail (fade->priv->start_surface != NULL); g_return_if_fail (fade->priv->end_surface != NULL); g_return_if_fail (!mate_bg_crossfade_is_started (fade)); g_return_if_fail (gdk_window_get_window_type (window) != GDK_WINDOW_FOREIGN); /* If drawing is done on the root window, * it is essential to have the root pixmap. */ if (gdk_window_get_window_type (window) == GDK_WINDOW_ROOT) { GdkDisplay *display = gdk_window_get_display (window); cairo_surface_t *surface = get_root_pixmap_id_surface (display); g_return_if_fail (surface != NULL); cairo_surface_destroy (surface); } if (fade->priv->fading_surface != NULL) { cairo_surface_destroy (fade->priv->fading_surface); fade->priv->fading_surface = NULL; } fade->priv->window = window; if (gdk_window_get_window_type (fade->priv->window) != GDK_WINDOW_ROOT) { fade->priv->fading_surface = tile_surface (fade->priv->start_surface, fade->priv->width, fade->priv->height); if (fade->priv->widget != NULL) { g_signal_connect (fade->priv->widget, "draw", (GCallback) on_widget_draw, fade); } } else { cairo_t *cr; GdkDisplay *display = gdk_window_get_display (fade->priv->window); fade->priv->fading_surface = get_root_pixmap_id_surface (display); cr = cairo_create (fade->priv->fading_surface); cairo_set_source_surface (cr, fade->priv->start_surface, 0, 0); cairo_paint (cr); cairo_destroy (cr); } draw_background (fade); source = g_timeout_source_new (1000 / 60.0); g_source_set_callback (source, (GSourceFunc) on_tick, fade, (GDestroyNotify) on_finished); context = g_main_context_default (); fade->priv->timeout_id = g_source_attach (source, context); g_source_unref (source); fade->priv->is_first_frame = TRUE; fade->priv->total_duration = .75; fade->priv->start_time = get_current_time (); }
/** * gda_worker_do_job: (skip) * @worker: a #GdaWorker object * @context: (allow-none): a #GMainContext to execute a main loop in (while waiting), or %NULL * @timeout_ms: the maximum number of milisecons to wait before returning, or %0 for unlimited wait * @out_result: (allow-none): a place to store the result, if any, of @func's execution, or %NULL * @out_job_id: (allow-none): a place to store the ID of the job having been submitted, or %NULL * @func: the function to call from the worker thread * @data: (allow-none): the data to pass to @func, or %NULL * @data_destroy_func: (allow-none): a function to destroy @data, or %NULL * @result_destroy_func: (allow-none): a function to destroy the result, if any, of @func's execution, or %NULL * @error: (allow-none): a place to store errors, or %NULL. * * Request that the worker thread call @func with the @data argument, much like gda_worker_submit_job(), * but waits (starting a #GMainLoop) for a maximum of @timeout_ms miliseconds for @func to be executed. * * If this function is called from within @worker's worker thread, then this function simply calls @func with @data and does not * use @context. * * The following cases are possible if this function is not called from within @worker's worker thread: * <itemizedlist> * <listitem><para>the call to @func took less than @timeout_ms miliseconds: the return value is %TRUE and * @out_result contains the result of the @func's execution, and @out_job_id contains %NULL. Note in this * case that @error may still contain an error code if @func's execution produced an error. Also note that in this case * any setting defined by gda_worker_set_callback() is not applied (as the result is immediately returned)</para></listitem> * <listitem><para>The call to @func takes more then @timeout_ms miliseconds: the return value is %TRUE and * @out_result is %NULL and @out_job_id contains the ID of the job as if it had been submitted using gda_worker_submit_job(). * If @out_job_id is %NULL, and if no setting has been defined using gda_worker_set_callback(), then the job will be discarded * (as if gda_worker_forget_job() had been called). * </para></listitem> * <listitem><para>The call to @func could not be done (some kind of plumbing error for instance): the returned value is %FALSE * and @out_result and @out_job_id are set to %NULL (if they are not %NULL)</para></listitem> * </itemizedlist> * * Notes: * <itemizedlist> * <listitem><para>@result_destroy_func is needed in case @out_result is %NULL (to avoid memory leaks)</para></listitem> * <listitem><para>passing %NULL for @context is similar to passing the result of g_main_context_ref_thread_default()</para></listitem> * </itemizedlist> * * Returns: %TRUE if no error occurred * * Since: 6.0 */ gboolean gda_worker_do_job (GdaWorker *worker, GMainContext *context, gint timeout_ms, gpointer *out_result, guint *out_job_id, GdaWorkerFunc func, gpointer data, GDestroyNotify data_destroy_func, GDestroyNotify result_destroy_func, GError **error) { if (out_result) *out_result = NULL; if (out_job_id) *out_job_id = 0; g_return_val_if_fail (worker, FALSE); g_return_val_if_fail (func, FALSE); if (!worker->callbacks_hash || !worker->jobs_hash) { g_warning ("GdaWorker has been destroyed\n"); return FALSE; } if (gda_worker_thread_is_worker (worker)) { /* we are called from within the worker thread => call the function directly */ gpointer result; result = func (data, error); if (data_destroy_func) data_destroy_func (data); if (out_result) *out_result = result; else if (result && result_destroy_func) result_destroy_func (result); return TRUE; } guint jid, itsid, timer = 0; /* determine which GMainContext to use */ GMainContext *co; gboolean unref_co = FALSE; co = context; if (!co) { co = g_main_context_ref_thread_default (); unref_co = TRUE; } /* prepare main loop */ GMainLoop *loop; loop = g_main_loop_new (co, FALSE); /* prepare ITSignaler to be notified */ ITSignaler *its; its = itsignaler_new (); itsid = itsignaler_add (its, co, (ITSignalerFunc) do_itsignaler_cb, g_main_loop_ref (loop), (GDestroyNotify) g_main_loop_unref); /* push job */ g_rec_mutex_lock (& worker->rmutex); /* required to call _gda_worker_submit_job_with_its() */ jid = _gda_worker_submit_job_with_its (worker, its, func, data, data_destroy_func, result_destroy_func, error); g_rec_mutex_unlock (& worker->rmutex); if (jid == 0) { /* an error occurred */ g_assert (itsignaler_remove (its, co, itsid)); itsignaler_unref (its); g_main_loop_unref (loop); if (unref_co) g_main_context_unref (co); return FALSE; } /* check if result is already here */ WorkerJob *job; job = itsignaler_pop_notification (its, 0); if (!job) { if (timeout_ms > 0) { /* start timer to limit waiting time */ GSource *timer_src; timer_src = g_timeout_source_new (timeout_ms); g_source_set_callback (timer_src, (GSourceFunc) do_timer_cb, loop, NULL); timer = g_source_attach (timer_src, co); g_source_unref (timer_src); } g_main_loop_run (loop); /* either timer has arrived or job has been done */ job = itsignaler_pop_notification (its, 0); } g_main_loop_unref (loop); g_assert (itsignaler_remove (its, co, itsid)); itsignaler_unref (its); if (job) { /* job done before the timer, if any, elapsed */ if (timer > 0) g_assert (g_source_remove (timer)); g_assert (gda_worker_fetch_job_result (worker, jid, out_result, error)); } else { /* timer came first, job is not yet finished */ /* apply settings from gda_worker_set_callback(), if any */ g_rec_mutex_lock (&worker->rmutex); DeclaredCallback *dc; dc = g_hash_table_lookup (worker->callbacks_hash, co); if (dc) { job = g_hash_table_lookup (worker->jobs_hash, &jid); g_assert (job); g_assert (!job->reply_its); job->reply_its = itsignaler_ref (dc->its); } g_rec_mutex_unlock (& worker->rmutex); /* cleanups */ if (out_job_id) *out_job_id = jid; else if (!dc) /* forget all about the job */ gda_worker_forget_job (worker, jid); } if (unref_co) g_main_context_unref (co); return TRUE; }
/* called when we're done running the command line */ static void udisks_spawned_job_release_resources (UlSpawnedJob *self) { /* Nuke the child, if necessary */ if (self->child_watch_source != NULL) { g_source_destroy (self->child_watch_source); self->child_watch_source = NULL; } if (self->child_pid != 0) { GSource *source; g_debug ("ugh, need to kill %d", (gint) self->child_pid); kill (self->child_pid, SIGTERM); /* OK, we need to reap for the child ourselves - we don't want * to use waitpid() because that might block the calling * thread (the child might handle SIGTERM and use several * seconds for cleanup/rollback). * * So we use GChildWatch instead. * * Note that we might be called from the finalizer so avoid * taking references to ourselves. We do need to pass the * GSource so we can nuke it once handled. */ source = g_child_watch_source_new (self->child_pid); g_source_set_callback (source, (GSourceFunc) child_watch_from_release_cb, source, (GDestroyNotify) g_source_destroy); g_source_attach (source, self->main_context); g_source_unref (source); self->child_pid = 0; } if (self->child_stdout != NULL) { g_string_free (self->child_stdout, TRUE); self->child_stdout = NULL; } if (self->child_stderr != NULL) { g_string_free (self->child_stderr, TRUE); self->child_stderr = NULL; } if (self->child_stdin_channel != NULL) { g_io_channel_unref (self->child_stdin_channel); self->child_stdin_channel = NULL; } if (self->child_stdout_channel != NULL) { g_io_channel_unref (self->child_stdout_channel); self->child_stdout_channel = NULL; } if (self->child_stderr_channel != NULL) { g_io_channel_unref (self->child_stderr_channel); self->child_stderr_channel = NULL; } if (self->child_stdin_source != NULL) { g_source_destroy (self->child_stdin_source); self->child_stdin_source = NULL; } if (self->child_stdout_source != NULL) { g_source_destroy (self->child_stdout_source); self->child_stdout_source = NULL; } if (self->child_stderr_source != NULL) { g_source_destroy (self->child_stderr_source); self->child_stderr_source = NULL; } if (self->child_stdin_fd != -1) { g_warn_if_fail (close (self->child_stdin_fd) == 0); self->child_stdin_fd = -1; } if (self->child_stdout_fd != -1) { g_warn_if_fail (close (self->child_stdout_fd) == 0); self->child_stdout_fd = -1; } if (self->child_stderr_fd != -1) { g_warn_if_fail (close (self->child_stderr_fd) == 0); self->child_stderr_fd = -1; } if (self->cancellable_handler_id > 0) { g_cancellable_disconnect (ul_job_get_cancellable (UL_JOB (self)), self->cancellable_handler_id); self->cancellable_handler_id = 0; } }
guint egg_spawn_async_with_callbacks (const gchar *working_directory, gchar **argv, gchar **envp, GSpawnFlags flags, GPid *child_pid, EggSpawnCallbacks *cbs, gpointer user_data, GMainContext *context, GError **error) { gint in_fd, out_fd, err_fd; CallbackSource *cb_source; GSource *source; guint tag; g_return_val_if_fail (argv != NULL, FALSE); g_return_val_if_fail ((cbs && cbs->standard_input == NULL) || !(flags & G_SPAWN_CHILD_INHERITS_STDIN), 0); g_return_val_if_fail ((cbs && cbs->standard_output == NULL) || !(flags & G_SPAWN_STDOUT_TO_DEV_NULL), 0); g_return_val_if_fail ((cbs && cbs->standard_error == NULL) || !(flags & G_SPAWN_STDERR_TO_DEV_NULL), 0); in_fd = out_fd = err_fd = -1; if (!g_spawn_async_with_pipes (working_directory, argv, envp, flags, cbs ? cbs->child_setup : NULL, user_data, child_pid, cbs && cbs->standard_input ? &in_fd : NULL, cbs && cbs->standard_output ? &out_fd : NULL, cbs && cbs->standard_error ? &err_fd : NULL, error)) return 0; source = g_source_new (&cb_source_funcs, sizeof (CallbackSource)); cb_source = (CallbackSource*)source; if (cbs != NULL) memcpy (&cb_source->callbacks, cbs, sizeof (EggSpawnCallbacks)); cb_source->polls[0].fd = in_fd; if (in_fd >= 0) { g_assert (cb_source->callbacks.standard_input); cb_source->polls[0].events = G_IO_ERR | G_IO_OUT; g_source_add_poll (source, &cb_source->polls[0]); } cb_source->polls[1].fd = out_fd; if (out_fd >= 0) { g_assert (cb_source->callbacks.standard_output); cb_source->polls[1].events = G_IO_ERR | G_IO_HUP | G_IO_IN; g_source_add_poll (source, &cb_source->polls[1]); } cb_source->polls[2].fd = err_fd; if (err_fd >= 0) { g_assert (cb_source->callbacks.standard_error); cb_source->polls[2].events = G_IO_ERR | G_IO_HUP | G_IO_IN; g_source_add_poll (source, &cb_source->polls[2]); } if (context == NULL) context = g_main_context_default (); g_source_set_callback (source, unused_callback, user_data, cbs ? cbs->finalize_func : NULL); tag = g_source_attach (source, context); g_source_unref (source); return tag; }
void glibcurl_set_callback(GlibcurlCallback function, void* data) { g_source_set_callback(&curlSrc->source, (GSourceFunc)function, data, NULL); }
/** * _gcr_gnupg_process_run_async: * @self: The process * @argv: (array zero-terminated=1): The arguments for the process, not including executable, terminated with %NULL. * @envp: (allow-none) (array zero-terminated=1): The environment for new process, terminated with %NULL. * @flags: Flags for starting the process. * @cancellable: (allow-none): Cancellation object * @callback: Will be called when operation completes. * @user_data: (closure): Data passed to callback. * * Run the gpg process. Only one 'run' operation can run per GcrGnupgProcess * object. The GcrGnupgProcess:output_data and GcrGnupgProcess:error_line * signals will be emitted when data is received from the gpg process. * * Unless the %GCR_GNUPG_PROCESS_RESPECT_LOCALE flag is specified, the process * will be run in the 'C' locale. If the %GCR_GNUPG_PROCESS_WITH_STATUS or * %GCR_GNUPG_PROCESS_WITH_ATTRIBUTES flags are set, then the gpg process * will be status and attribute output respectively. The * GcrGnupgProcess:status_record and GcrGnupgProcess:attribute_data signals * will provide this data. */ void _gcr_gnupg_process_run_async (GcrGnupgProcess *self, const gchar **argv, const gchar **envp, GcrGnupgProcessFlags flags, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { GError *error = NULL; GPtrArray *args; GPtrArray *envs; int child_fds[NUM_FDS]; int status_fds[2] = { -1, -1 }; int attribute_fds[2] = { -1, -1 }; int output_fd = -1; int error_fd = -1; int input_fd = -1; GnupgSource *gnupg_source; GSource *source; GPid pid; guint i; g_return_if_fail (GCR_IS_GNUPG_PROCESS (self)); g_return_if_fail (argv); g_return_if_fail (callback); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); g_return_if_fail (self->pv->running == FALSE); g_return_if_fail (self->pv->complete == FALSE); g_return_if_fail (self->pv->executable); self->pv->async_callback = callback; self->pv->user_data = user_data; for (i = 0; i < NUM_FDS; i++) child_fds[i] = -1; /* The command needs to be updated with these status and attribute fds */ args = g_ptr_array_new_with_free_func (g_free); g_ptr_array_add (args, g_strdup (self->pv->executable)); /* Spawn/child will close all other attributes, besides thesthose in child_fds */ child_fds[FD_INPUT] = 0; child_fds[FD_OUTPUT] = 1; child_fds[FD_ERROR] = 2; if (flags & GCR_GNUPG_PROCESS_WITH_STATUS) { if (pipe (status_fds) < 0) g_return_if_reached (); child_fds[FD_STATUS] = status_fds[1]; g_ptr_array_add (args, g_strdup ("--status-fd")); g_ptr_array_add (args, g_strdup_printf ("%d", child_fds[FD_STATUS])); } if (flags & GCR_GNUPG_PROCESS_WITH_ATTRIBUTES) { if (pipe (attribute_fds) < 0) g_return_if_reached (); child_fds[FD_ATTRIBUTE] = attribute_fds[1]; g_ptr_array_add (args, g_strdup ("--attribute-fd")); g_ptr_array_add (args, g_strdup_printf ("%d", child_fds[FD_ATTRIBUTE])); } if (self->pv->directory) { g_ptr_array_add (args, g_strdup ("--homedir")); g_ptr_array_add (args, g_strdup (self->pv->directory)); } /* All the remaining arguments */ for (i = 0; argv[i] != NULL; i++) g_ptr_array_add (args, g_strdup (argv[i])); g_ptr_array_add (args, NULL); envs = g_ptr_array_new (); for (i = 0; envp && envp[i] != NULL; i++) { if (flags & GCR_GNUPG_PROCESS_RESPECT_LOCALE || !g_str_has_prefix (envp[i], "LOCALE=")) g_ptr_array_add (envs, (gpointer)envp[i]); } if (!(flags & GCR_GNUPG_PROCESS_RESPECT_LOCALE)) g_ptr_array_add (envs, (gpointer)"LOCALE=C"); g_ptr_array_add (envs, NULL); gchar *command = g_strjoinv (" ", (gchar**)args->pdata); gchar *environ = g_strjoinv (", ", (gchar**)envs->pdata); g_debug ("running command: %s", command); g_debug ("process environment: %s", environ); g_free (command); g_free (environ); g_spawn_async_with_pipes (self->pv->directory, (gchar**)args->pdata, (gchar**)envs->pdata, G_SPAWN_DO_NOT_REAP_CHILD, on_gnupg_process_child_setup, child_fds, &pid, &input_fd, &output_fd, &error_fd, &error); g_ptr_array_free (args, TRUE); g_ptr_array_free (envs, TRUE); /* Close 'wrong' ends of extra file descriptors */ close_fd (&(status_fds[1])); close_fd (&(attribute_fds[1])); self->pv->complete = FALSE; self->pv->running = TRUE; if (error) { close_fd (&(status_fds[0])); close_fd (&(attribute_fds[0])); g_assert (!self->pv->error); self->pv->error = error; complete_run_process (self); run_async_ready_callback_later (self); return; } g_debug ("process started: %d", (int)pid); source = g_source_new (&gnupg_source_funcs, sizeof (GnupgSource)); /* Initialize the source */ gnupg_source = (GnupgSource*)source; for (i = 0; i < NUM_FDS; i++) gnupg_source->polls[i].fd = -1; gnupg_source->error_buf = g_string_sized_new (128); gnupg_source->status_buf = g_string_sized_new (128); gnupg_source->process = g_object_ref (self); gnupg_source->child_pid = pid; gnupg_source->polls[FD_INPUT].fd = input_fd; if (input_fd >= 0) { gnupg_source->polls[FD_INPUT].events = G_IO_HUP | G_IO_OUT; g_source_add_poll (source, &gnupg_source->polls[FD_INPUT]); } gnupg_source->polls[FD_OUTPUT].fd = output_fd; if (output_fd >= 0) { gnupg_source->polls[FD_OUTPUT].events = G_IO_HUP | G_IO_IN; g_source_add_poll (source, &gnupg_source->polls[FD_OUTPUT]); } gnupg_source->polls[FD_ERROR].fd = error_fd; if (error_fd >= 0) { gnupg_source->polls[FD_ERROR].events = G_IO_HUP | G_IO_IN; g_source_add_poll (source, &gnupg_source->polls[FD_ERROR]); } gnupg_source->polls[FD_STATUS].fd = status_fds[0]; if (status_fds[0] >= 0) { gnupg_source->polls[FD_STATUS].events = G_IO_HUP | G_IO_IN; g_source_add_poll (source, &gnupg_source->polls[FD_STATUS]); } gnupg_source->polls[FD_ATTRIBUTE].fd = attribute_fds[0]; if (attribute_fds[0] >= 0) { gnupg_source->polls[FD_ATTRIBUTE].events = G_IO_HUP | G_IO_IN; g_source_add_poll (source, &gnupg_source->polls[FD_ATTRIBUTE]); } if (cancellable) { gnupg_source->cancellable = g_object_ref (cancellable); gnupg_source->cancel_sig = g_cancellable_connect (cancellable, G_CALLBACK (on_cancellable_cancelled), g_source_ref (source), (GDestroyNotify)g_source_unref); } g_assert (self->pv->source_sig == 0); g_source_set_callback (source, unused_callback, NULL, NULL); self->pv->source_sig = g_source_attach (source, g_main_context_default ()); /* This assumes the outstanding reference to source */ g_assert (gnupg_source->child_sig == 0); gnupg_source->child_sig = g_child_watch_add_full (G_PRIORITY_DEFAULT, pid, on_gnupg_process_child_exited, g_source_ref (source), (GDestroyNotify)g_source_unref); /* source is unreffed in complete_if_source_is_done() */ }
/* * owr_local_media_source_get_pad * * The beginning of a media source chain in the pipeline looks like this: * +------------+ * /---+ inter*sink | * +--------+ +--------+ +------------+ +-----+ / +------------+ * | source +----+ scale? +---+ capsfilter +---+ tee +---/ * +--------+ +--------+ +------------+ +-----+ \ * \ +------------+ * \---+ inter*sink | * +------------+ * * For each newly requested pad a new inter*sink is added to the tee. * Note that this is a completely independent pipeline, and the complete * pipeline is only created once for a specific media source. * * Then for each newly requested pad another bin with a inter*src is * created, which is then going to be part of the transport agent * pipeline. The ghostpad of it is what we return here. * * +-----------+ +-------------------------------+ +----------+ * | inter*src +---+ converters/queues/capsfilters +---+ ghostpad | * +-----------+ +-------------------------------+ +----------+ * */ static GstElement *owr_local_media_source_request_source(OwrMediaSource *media_source, GstCaps *caps) { OwrLocalMediaSource *local_source; OwrLocalMediaSourcePrivate *priv; GstElement *source_element = NULL; GstElement *source_pipeline; GHashTable *event_data; GValue *value; #if defined(__linux__) && !defined(__ANDROID__) gchar *tmp; #endif g_assert(media_source); local_source = OWR_LOCAL_MEDIA_SOURCE(media_source); priv = local_source->priv; /* only create the source bin for this media source once */ if ((source_pipeline = _owr_media_source_get_source_bin(media_source))) GST_DEBUG_OBJECT(media_source, "Re-using existing source element/bin"); else { OwrMediaType media_type = OWR_MEDIA_TYPE_UNKNOWN; OwrSourceType source_type = OWR_SOURCE_TYPE_UNKNOWN; GstElement *source, *source_process = NULL, *capsfilter = NULL, *tee; GstPad *sinkpad, *source_pad; GEnumClass *media_enum_class, *source_enum_class; GEnumValue *media_enum_value, *source_enum_value; gchar *bin_name; GstCaps *source_caps; GstBus *bus; GSource *bus_source; event_data = _owr_value_table_new(); value = _owr_value_table_add(event_data, "start_time", G_TYPE_INT64); g_value_set_int64(value, g_get_monotonic_time()); g_object_get(media_source, "media-type", &media_type, "type", &source_type, NULL); media_enum_class = G_ENUM_CLASS(g_type_class_ref(OWR_TYPE_MEDIA_TYPE)); source_enum_class = G_ENUM_CLASS(g_type_class_ref(OWR_TYPE_SOURCE_TYPE)); media_enum_value = g_enum_get_value(media_enum_class, media_type); source_enum_value = g_enum_get_value(source_enum_class, source_type); bin_name = g_strdup_printf("local-%s-%s-source-bin-%u", media_enum_value ? media_enum_value->value_nick : "unknown", source_enum_value ? source_enum_value->value_nick : "unknown", g_atomic_int_add(&unique_bin_id, 1)); g_type_class_unref(media_enum_class); g_type_class_unref(source_enum_class); source_pipeline = gst_pipeline_new(bin_name); gst_pipeline_use_clock(GST_PIPELINE(source_pipeline), gst_system_clock_obtain()); gst_element_set_base_time(source_pipeline, _owr_get_base_time()); gst_element_set_start_time(source_pipeline, GST_CLOCK_TIME_NONE); g_free(bin_name); bin_name = NULL; #ifdef OWR_DEBUG g_signal_connect(source_pipeline, "deep-notify", G_CALLBACK(_owr_deep_notify), NULL); #endif bus = gst_pipeline_get_bus(GST_PIPELINE(source_pipeline)); bus_source = gst_bus_create_watch(bus); g_source_set_callback(bus_source, (GSourceFunc) bus_call, media_source, NULL); g_source_attach(bus_source, _owr_get_main_context()); g_source_unref(bus_source); GST_DEBUG_OBJECT(local_source, "media_type: %d, type: %d", media_type, source_type); if (media_type == OWR_MEDIA_TYPE_UNKNOWN || source_type == OWR_SOURCE_TYPE_UNKNOWN) { GST_ERROR_OBJECT(local_source, "Cannot connect source with unknown type or media type to other component"); goto done; } switch (media_type) { case OWR_MEDIA_TYPE_AUDIO: { switch (source_type) { case OWR_SOURCE_TYPE_CAPTURE: CREATE_ELEMENT(source, AUDIO_SRC, "audio-source"); #if !defined(__APPLE__) || !TARGET_IPHONE_SIMULATOR /* Default values for buffer-time and latency-time on android are 200ms and 20ms. The minimum latency-time that can be used on Android is 20ms, and using a 40ms buffer-time with a 20ms latency-time causes crackling audio. So let's just stick with the defaults. */ #if !defined(__ANDROID__) g_object_set(source, "buffer-time", G_GINT64_CONSTANT(40000), "latency-time", G_GINT64_CONSTANT(10000), NULL); #endif if (priv->device_index > -1) { #ifdef __APPLE__ g_object_set(source, "device", priv->device_index, NULL); #elif defined(__linux__) && !defined(__ANDROID__) tmp = g_strdup_printf("%d", priv->device_index); g_object_set(source, "device", tmp, NULL); g_free(tmp); #endif } #endif break; case OWR_SOURCE_TYPE_TEST: CREATE_ELEMENT(source, "audiotestsrc", "audio-source"); g_object_set(source, "is-live", TRUE, NULL); break; case OWR_SOURCE_TYPE_UNKNOWN: default: g_assert_not_reached(); goto done; } break; } case OWR_MEDIA_TYPE_VIDEO: { GstPad *srcpad; GstCaps *device_caps; switch (source_type) { case OWR_SOURCE_TYPE_CAPTURE: CREATE_ELEMENT(source, VIDEO_SRC, "video-source"); if (priv->device_index > -1) { #if defined(__APPLE__) && !TARGET_IPHONE_SIMULATOR g_object_set(source, "device-index", priv->device_index, NULL); #elif defined(__ANDROID__) g_object_set(source, "cam-index", priv->device_index, NULL); #elif defined(__linux__) tmp = g_strdup_printf("/dev/video%d", priv->device_index); g_object_set(source, "device", tmp, NULL); g_free(tmp); #endif } break; case OWR_SOURCE_TYPE_TEST: { GstElement *src, *time; GstPad *srcpad; source = gst_bin_new("video-source"); CREATE_ELEMENT(src, "videotestsrc", "videotestsrc"); g_object_set(src, "is-live", TRUE, NULL); gst_bin_add(GST_BIN(source), src); time = gst_element_factory_make("timeoverlay", "timeoverlay"); if (time) { g_object_set(time, "font-desc", "Sans 60", NULL); gst_bin_add(GST_BIN(source), time); gst_element_link(src, time); srcpad = gst_element_get_static_pad(time, "src"); } else srcpad = gst_element_get_static_pad(src, "src"); gst_element_add_pad(source, gst_ghost_pad_new("src", srcpad)); gst_object_unref(srcpad); break; } case OWR_SOURCE_TYPE_UNKNOWN: default: g_assert_not_reached(); goto done; } /* First try to see if we can just get the format we want directly */ source_caps = gst_caps_new_empty(); #if GST_CHECK_VERSION(1, 5, 0) gst_caps_foreach(caps, fix_video_caps_framerate, source_caps); #else _owr_gst_caps_foreach(caps, fix_video_caps_framerate, source_caps); #endif /* Now see what the device can really produce */ srcpad = gst_element_get_static_pad(source, "src"); gst_element_set_state(source, GST_STATE_READY); device_caps = gst_pad_query_caps(srcpad, source_caps); if (gst_caps_is_empty(device_caps)) { /* Let's see if it works when we drop format constraints (which can be dealt with downsteram) */ GstCaps *tmp = source_caps; source_caps = gst_caps_new_empty(); #if GST_CHECK_VERSION(1, 5, 0) gst_caps_foreach(tmp, fix_video_caps_format, source_caps); #else _owr_gst_caps_foreach(tmp, fix_video_caps_format, source_caps); #endif gst_caps_unref(tmp); gst_caps_unref(device_caps); device_caps = gst_pad_query_caps(srcpad, source_caps); if (gst_caps_is_empty(device_caps)) { /* Accepting any format didn't work, we're going to hope that scaling fixes it */ CREATE_ELEMENT(source_process, "videoscale", "video-source-scale"); gst_bin_add(GST_BIN(source_pipeline), source_process); } } gst_caps_unref(device_caps); gst_object_unref(srcpad); #if defined(__APPLE__) && TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR /* Force NV12 on iOS else the source can negotiate BGRA * ercolorspace can do NV12 -> BGRA and NV12 -> I420 which is what * is needed for Bowser */ gst_caps_set_simple(source_caps, "format", G_TYPE_STRING, "NV12", NULL); #endif CREATE_ELEMENT(capsfilter, "capsfilter", "video-source-capsfilter"); g_object_set(capsfilter, "caps", source_caps, NULL); gst_caps_unref(source_caps); gst_bin_add(GST_BIN(source_pipeline), capsfilter); break; } case OWR_MEDIA_TYPE_UNKNOWN: default: g_assert_not_reached(); goto done; } g_assert(source); source_pad = gst_element_get_static_pad(source, "src"); g_signal_connect(source_pad, "notify::caps", G_CALLBACK(on_caps), media_source); gst_object_unref(source_pad); CREATE_ELEMENT(tee, "tee", "source-tee"); g_object_set(tee, "allow-not-linked", TRUE, NULL); gst_bin_add_many(GST_BIN(source_pipeline), source, tee, NULL); /* Many sources don't like reconfiguration and it's pointless * here anyway right now. No need to reconfigure whenever something * is added to the tee or removed. * We will have to implement reconfiguration differently later by * selecting the best caps based on all consumers. */ sinkpad = gst_element_get_static_pad(tee, "sink"); gst_pad_add_probe(sinkpad, GST_PAD_PROBE_TYPE_EVENT_UPSTREAM, drop_reconfigure_event, NULL, NULL); gst_object_unref(sinkpad); if (!source) GST_ERROR_OBJECT(media_source, "Failed to create source element!"); if (capsfilter) { LINK_ELEMENTS(capsfilter, tee); if (source_process) { LINK_ELEMENTS(source_process, capsfilter); LINK_ELEMENTS(source, source_process); } else LINK_ELEMENTS(source, capsfilter); } else if (source_process) { LINK_ELEMENTS(source_process, tee); LINK_ELEMENTS(source, source_process); } else LINK_ELEMENTS(source, tee); gst_element_sync_state_with_parent(tee); if (capsfilter) gst_element_sync_state_with_parent(capsfilter); if (source_process) gst_element_sync_state_with_parent(source_process); gst_element_sync_state_with_parent(source); _owr_media_source_set_source_bin(media_source, source_pipeline); _owr_media_source_set_source_tee(media_source, tee); if (gst_element_set_state(source_pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) { GST_ERROR("Failed to set local source pipeline %s to playing", GST_OBJECT_NAME(source_pipeline)); /* FIXME: We should handle this and don't expose the source */ } value = _owr_value_table_add(event_data, "end_time", G_TYPE_INT64); g_value_set_int64(value, g_get_monotonic_time()); OWR_POST_EVENT(media_source, LOCAL_SOURCE_STARTED, event_data); g_signal_connect(tee, "pad-removed", G_CALLBACK(tee_pad_removed_cb), media_source); } gst_object_unref(source_pipeline); source_element = OWR_MEDIA_SOURCE_CLASS(owr_local_media_source_parent_class)->request_source(media_source, caps); done: return source_element; }
static gboolean gst_soup_http_client_sink_start (GstBaseSink * sink) { GstSoupHttpClientSink *souphttpsink = GST_SOUP_HTTP_CLIENT_SINK (sink); if (souphttpsink->prop_session) { souphttpsink->session = souphttpsink->prop_session; } else { GSource *source; GError *error = NULL; souphttpsink->context = g_main_context_new (); /* set up idle source to signal when the main loop is running and * it's safe for ::stop() to call g_main_loop_quit() */ source = g_idle_source_new (); g_source_set_callback (source, thread_ready_idle_cb, sink, NULL); g_source_attach (source, souphttpsink->context); g_source_unref (source); souphttpsink->loop = g_main_loop_new (souphttpsink->context, TRUE); g_mutex_lock (&souphttpsink->mutex); souphttpsink->thread = g_thread_try_new ("souphttpclientsink-thread", thread_func, souphttpsink, &error); if (error != NULL) { GST_DEBUG_OBJECT (souphttpsink, "failed to start thread, %s", error->message); g_error_free (error); g_mutex_unlock (&souphttpsink->mutex); return FALSE; } GST_LOG_OBJECT (souphttpsink, "waiting for main loop thread to start up"); g_cond_wait (&souphttpsink->cond, &souphttpsink->mutex); g_mutex_unlock (&souphttpsink->mutex); GST_LOG_OBJECT (souphttpsink, "main loop thread running"); if (souphttpsink->proxy == NULL) { souphttpsink->session = soup_session_async_new_with_options (SOUP_SESSION_ASYNC_CONTEXT, souphttpsink->context, SOUP_SESSION_USER_AGENT, souphttpsink->user_agent, SOUP_SESSION_TIMEOUT, souphttpsink->timeout, SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_PROXY_RESOLVER_DEFAULT, NULL); } else { souphttpsink->session = soup_session_async_new_with_options (SOUP_SESSION_ASYNC_CONTEXT, souphttpsink->context, SOUP_SESSION_USER_AGENT, souphttpsink->user_agent, SOUP_SESSION_TIMEOUT, souphttpsink->timeout, SOUP_SESSION_PROXY_URI, souphttpsink->proxy, NULL); } g_signal_connect (souphttpsink->session, "authenticate", G_CALLBACK (authenticate), souphttpsink); } /* Set up logging */ gst_soup_util_log_setup (souphttpsink->session, souphttpsink->log_level, GST_ELEMENT (souphttpsink)); return TRUE; }
static void auth_fn (SMBCCTX *smb_context, const char *server, const char *share, char *workgroup, int wgmaxlen, char *username, int unmaxlen, char *password, int pwmaxlen) { PpSamba *samba; GSource *source; SMBData *data; data = (SMBData *) smbc_getOptionUserData (smb_context); samba = data->samba; if (!data->cancelled) { samba->priv->server = g_strdup (server); samba->priv->share = g_strdup (share); samba->priv->workgroup = g_strdup (workgroup); samba->priv->username = g_strdup (username); samba->priv->password = g_strdup (password); source = g_idle_source_new (); g_source_set_callback (source, get_auth_info, data, NULL); g_source_attach (source, data->context); g_source_unref (source); samba->priv->waiting = TRUE; /* * smbclient needs to get authentication data * from this synchronous callback so we are blocking * until we get them */ while (samba->priv->waiting) { g_usleep (POLL_DELAY); } /* Samba tries to call the auth_fn again if we just set the values * to NULL when we want to cancel the authentication */ if (samba->priv->username == NULL && samba->priv->password == NULL) data->cancelled = TRUE; if (samba->priv->username != NULL) { if (g_strcmp0 (username, samba->priv->username) != 0) g_strlcpy (username, samba->priv->username, unmaxlen); } else { username[0] = '\0'; } if (samba->priv->password != NULL) { if (g_strcmp0 (password, samba->priv->password) != 0) g_strlcpy (password, samba->priv->password, pwmaxlen); } else { password[0] = '\0'; } } }
static gint nm_openconnect_start_openconnect_binary (NMOPENCONNECTPlugin *plugin, NMSettingVPN *s_vpn, GError **error) { NMOPENCONNECTPluginPrivate *priv = NM_OPENCONNECT_PLUGIN_GET_PRIVATE (plugin); GPid pid; const char **openconnect_binary = NULL; GPtrArray *openconnect_argv; GSource *openconnect_watch; gint stdin_fd; const char *props_vpn_gw, *props_cookie, *props_cacert, *props_mtu, *props_gwcert, *props_proxy; /* Find openconnect */ openconnect_binary = openconnect_binary_paths; while (*openconnect_binary != NULL) { if (g_file_test (*openconnect_binary, G_FILE_TEST_EXISTS)) break; openconnect_binary++; } if (!*openconnect_binary) { g_set_error (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED, "%s", _("Could not find openconnect binary.")); return -1; } /* The actual gateway to use (after redirection) comes from the auth dialog, so it's in the secrets hash not the properties */ props_vpn_gw = nm_setting_vpn_get_secret (s_vpn, NM_OPENCONNECT_KEY_GATEWAY); if (!props_vpn_gw || !strlen (props_vpn_gw) ) { g_set_error (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED, "%s", _("No VPN gateway specified.")); return -1; } props_cookie = nm_setting_vpn_get_secret (s_vpn, NM_OPENCONNECT_KEY_COOKIE); if (!props_cookie || !strlen (props_cookie)) { g_set_error (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED, "%s", _("No WebVPN cookie provided.")); return -1; } props_gwcert = nm_setting_vpn_get_secret (s_vpn, NM_OPENCONNECT_KEY_GWCERT); props_cacert = nm_setting_vpn_get_data_item (s_vpn, NM_OPENCONNECT_KEY_CACERT); props_mtu = nm_setting_vpn_get_data_item (s_vpn, NM_OPENCONNECT_KEY_MTU); props_proxy = nm_setting_vpn_get_data_item (s_vpn, NM_OPENCONNECT_KEY_PROXY); openconnect_argv = g_ptr_array_new (); g_ptr_array_add (openconnect_argv, (gpointer) (*openconnect_binary)); if (props_gwcert && strlen(props_gwcert)) { g_ptr_array_add (openconnect_argv, (gpointer) "--servercert"); g_ptr_array_add (openconnect_argv, (gpointer) props_gwcert); } else if (props_cacert && strlen(props_cacert)) { g_ptr_array_add (openconnect_argv, (gpointer) "--cafile"); g_ptr_array_add (openconnect_argv, (gpointer) props_cacert); } if (props_mtu && strlen(props_mtu)) { g_ptr_array_add (openconnect_argv, (gpointer) "--mtu"); g_ptr_array_add (openconnect_argv, (gpointer) props_mtu); } if (props_proxy && strlen(props_proxy)) { g_ptr_array_add (openconnect_argv, (gpointer) "--proxy"); g_ptr_array_add (openconnect_argv, (gpointer) props_proxy); } g_ptr_array_add (openconnect_argv, (gpointer) "--syslog"); g_ptr_array_add (openconnect_argv, (gpointer) "--cookie-on-stdin"); g_ptr_array_add (openconnect_argv, (gpointer) "--script"); g_ptr_array_add (openconnect_argv, (gpointer) NM_OPENCONNECT_HELPER_PATH); priv->tun_name = create_persistent_tundev (); if (priv->tun_name) { g_ptr_array_add (openconnect_argv, (gpointer) "--interface"); g_ptr_array_add (openconnect_argv, (gpointer) priv->tun_name); } g_ptr_array_add (openconnect_argv, (gpointer) props_vpn_gw); if (debug) g_ptr_array_add (openconnect_argv, (gpointer) "--verbose"); g_ptr_array_add (openconnect_argv, NULL); if (!g_spawn_async_with_pipes (NULL, (char **) openconnect_argv->pdata, NULL, G_SPAWN_DO_NOT_REAP_CHILD, openconnect_drop_child_privs, priv->tun_name, &pid, &stdin_fd, NULL, NULL, error)) { g_ptr_array_free (openconnect_argv, TRUE); g_warning ("openconnect failed to start. error: '%s'", (*error)->message); return -1; } g_ptr_array_free (openconnect_argv, TRUE); g_message ("openconnect started with pid %d", pid); if (write(stdin_fd, props_cookie, strlen(props_cookie)) != strlen(props_cookie) || write(stdin_fd, "\n", 1) != 1) { g_warning ("openconnect didn't eat the cookie we fed it"); return -1; } close(stdin_fd); NM_OPENCONNECT_PLUGIN_GET_PRIVATE (plugin)->pid = pid; openconnect_watch = g_child_watch_source_new (pid); g_source_set_callback (openconnect_watch, (GSourceFunc) openconnect_watch_cb, plugin, NULL); g_source_attach (openconnect_watch, NULL); g_source_unref (openconnect_watch); return 0; }
static gboolean update_clock (gpointer data) { GnomeWallClock *self = data; CDesktopClockFormat clock_format; const char *format_string; gboolean show_full_date; gboolean show_weekday; gboolean show_seconds; GSource *source; GDateTime *now; GDateTime *expiry; clock_format = g_settings_get_enum (self->priv->desktop_settings, "clock-format"); show_weekday = !self->priv->time_only; show_full_date = show_weekday && g_settings_get_boolean (self->priv->desktop_settings, "clock-show-date"); show_seconds = g_settings_get_boolean (self->priv->desktop_settings, "clock-show-seconds"); now = g_date_time_new_now_local (); if (show_seconds) expiry = g_date_time_add_seconds (now, 1); else expiry = g_date_time_add_seconds (now, 60 - g_date_time_get_second (now)); if (self->priv->clock_update_id) g_source_remove (self->priv->clock_update_id); source = _gnome_datetime_source_new (now, expiry, TRUE); g_source_set_priority (source, G_PRIORITY_HIGH); g_source_set_callback (source, update_clock, self, NULL); self->priv->clock_update_id = g_source_attach (source, NULL); g_source_unref (source); if (clock_format == C_DESKTOP_CLOCK_FORMAT_24H) { if (show_full_date) { /* Translators: This is the time format with full date used in 24-hour mode. */ format_string = show_seconds ? _("%a %b %e, %R:%S") : _("%a %b %e, %R"); } else if (show_weekday) { /* Translators: This is the time format with day used in 24-hour mode. */ format_string = show_seconds ? _("%a %R:%S") : _("%a %R"); } else { /* Translators: This is the time format without date used in 24-hour mode. */ format_string = show_seconds ? _("%R:%S") : _("%R"); } } else { if (show_full_date) { /* Translators: This is a time format with full date used for AM/PM. */ format_string = show_seconds ? _("%a %b %e, %l:%M:%S %p") : _("%a %b %e, %l:%M %p"); } else if (show_weekday) { /* Translators: This is a time format with day used for AM/PM. */ format_string = show_seconds ? _("%a %l:%M:%S %p") : _("%a %l:%M %p"); } else { /* Translators: This is a time format without date used for AM/PM. */ format_string = show_seconds ? _("%l:%M:%S %p") : _("%l:%M %p"); } } g_free (self->priv->clock_string); self->priv->clock_string = g_date_time_format (now, format_string); g_date_time_unref (now); g_date_time_unref (expiry); g_object_notify ((GObject*)self, "clock"); return FALSE; }
/* * Forks a ssh to the host listed in rc->hostname * Returns negative on error, with an errmsg in rc->errmsg. */ static int runssh( struct tcp_conn * rc, const char * amandad_path, const char * client_username, const char * ssh_keys, const char * client_port) { int rpipe[2], wpipe[2]; char *xamandad_path = (char *)amandad_path; char *xclient_username = (char *)client_username; char *xssh_keys = (char *)ssh_keys; char *xclient_port = (char *)client_port; GPtrArray *myargs; gchar *ssh_options[100] = {SSH_OPTIONS, NULL}; gchar **ssh_option; gchar *cmd; memset(rpipe, -1, sizeof(rpipe)); memset(wpipe, -1, sizeof(wpipe)); if (pipe(rpipe) < 0 || pipe(wpipe) < 0) { g_free(rc->errmsg); rc->errmsg = g_strdup_printf(_("pipe: %s"), strerror(errno)); return (-1); } if(!xamandad_path || strlen(xamandad_path) <= 1) xamandad_path = g_strjoin(NULL, amlibexecdir, "/", "amandad", NULL); if(!xclient_username || strlen(xclient_username) <= 1) xclient_username = CLIENT_LOGIN; if(!xclient_port || strlen(xclient_port) <= 1) xclient_port = NULL; myargs = g_ptr_array_sized_new(20); g_ptr_array_add(myargs, SSH); for (ssh_option = ssh_options; *ssh_option != NULL; ssh_option++) { g_ptr_array_add(myargs, *ssh_option); } g_ptr_array_add(myargs, "-l"); g_ptr_array_add(myargs, xclient_username); if (xclient_port) { g_ptr_array_add(myargs, "-p"); g_ptr_array_add(myargs, xclient_port); } if (ssh_keys && strlen(ssh_keys) > 1) { g_ptr_array_add(myargs, "-i"); g_ptr_array_add(myargs, xssh_keys); } g_ptr_array_add(myargs, rc->hostname); g_ptr_array_add(myargs, xamandad_path); g_ptr_array_add(myargs, "-auth=ssh"); g_ptr_array_add(myargs, NULL); cmd = g_strjoinv(" ", (gchar **)myargs->pdata); g_debug("exec: %s", cmd); g_free(cmd); switch (rc->pid = fork()) { case -1: g_free(rc->errmsg); rc->errmsg = g_strdup_printf(_("fork: %s"), strerror(errno)); aclose(rpipe[0]); aclose(rpipe[1]); aclose(wpipe[0]); aclose(wpipe[1]); return (-1); case 0: dup2(wpipe[0], 0); dup2(rpipe[1], 1); break; default: rc->read = rpipe[0]; aclose(rpipe[1]); rc->write = wpipe[1]; aclose(wpipe[0]); rc->child_watch = new_child_watch_source(rc->pid); g_source_set_callback(rc->child_watch, (GSourceFunc)ssh_child_watch_callback, rc, NULL); g_source_attach(rc->child_watch, NULL); g_source_unref(rc->child_watch); return (0); } /* drop root privs for good */ set_root_privs(-1); safe_fd(-1, 0); execvp(SSH, (gchar **)myargs->pdata); error("error: couldn't exec %s: %s", SSH, strerror(errno)); /* should never go here, shut up compiler warning */ return(-1); }
gboolean fs_rawudp_component_gather_local_candidates (FsRawUdpComponent *self, GError **error) { if (self->priv->gathered) { g_set_error (error, FS_ERROR, FS_ERROR_INVALID_ARGUMENTS, "Call gather local candidates twice on the same component"); return FALSE; } if (!self->priv->udpport) { g_set_error (error, FS_ERROR, FS_ERROR_INVALID_ARGUMENTS, "You can not call gather_local_candidate() after the stream has" " been stopped"); return FALSE; } #ifdef HAVE_GUPNP if (self->priv->upnp_igd && (self->priv->upnp_mapping || self->priv->upnp_discovery)) { guint port; GList *ips; port = fs_rawudp_transmitter_udpport_get_port (self->priv->udpport); ips = nice_interfaces_get_local_ips (FALSE); ips = filter_ips (ips, TRUE, FALSE); if (ips) { gchar *ip = g_list_first (ips)->data; GMainContext *ctx; if (self->priv->upnp_discovery) { FS_RAWUDP_COMPONENT_LOCK (self); self->priv->upnp_signal_id = g_signal_connect (self->priv->upnp_igd, "mapped-external-port", G_CALLBACK (_upnp_mapped_external_port), self); FS_RAWUDP_COMPONENT_UNLOCK (self); } GST_DEBUG ("Doing UPnP Discovery for local ip:%s port:%u", ip, port); gupnp_simple_igd_add_port (GUPNP_SIMPLE_IGD (self->priv->upnp_igd), "UDP", port, ip, port, self->priv->upnp_mapping_timeout, "Farstream Raw UDP transmitter " PACKAGE_VERSION); if (self->priv->upnp_discovery) { FS_RAWUDP_COMPONENT_LOCK (self); self->priv->upnp_discovery_timeout_src = g_timeout_source_new_seconds ( self->priv->upnp_discovery_timeout); g_source_set_callback (self->priv->upnp_discovery_timeout_src, _upnp_discovery_timeout, self, NULL); g_object_get (self->priv->upnp_igd, "main-context", &ctx, NULL); g_source_attach (self->priv->upnp_discovery_timeout_src, ctx); FS_RAWUDP_COMPONENT_UNLOCK (self); } } else { FS_RAWUDP_COMPONENT_LOCK (self); fs_rawudp_component_stop_upnp_discovery_locked (self); FS_RAWUDP_COMPONENT_UNLOCK (self); } /* free list of ips */ g_list_foreach (ips, (GFunc) g_free, NULL); g_list_free (ips); } #endif if (self->priv->stun_ip) return fs_rawudp_component_start_stun (self, error); #ifdef HAVE_GUPNP else if (!self->priv->upnp_signal_id) return fs_rawudp_component_emit_local_candidates (self, error); else return TRUE; #else else return fs_rawudp_component_emit_local_candidates (self, error);
static void* plain_sockets_thread_func (void *data) { GMainContext *context; ClientData cd; int fd; struct sockaddr_un addr; GIOChannel *channel; GSource *gsource; g_printerr ("Starting client thread %p\n", g_thread_self()); fd = socket (PF_UNIX, SOCK_STREAM, 0); if (fd < 0) { g_printerr ("Failed to create socket: %s", strerror (errno)); exit (1); } _DBUS_ZERO (addr); addr.sun_family = AF_UNIX; #ifdef HAVE_ABSTRACT_SOCKETS /* remember that abstract names aren't nul-terminated so we rely * on sun_path being filled in with zeroes above. */ addr.sun_path[0] = '\0'; /* this is what says "use abstract" */ strncpy (&addr.sun_path[1], plain_sockets_address, _DBUS_MAX_SUN_PATH_LENGTH - 2); /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */ #else /* HAVE_ABSTRACT_SOCKETS */ strncpy (addr.sun_path, plain_sockets_address, _DBUS_MAX_SUN_PATH_LENGTH - 1); #endif /* ! HAVE_ABSTRACT_SOCKETS */ if (connect (fd, (struct sockaddr*) &addr, sizeof (addr)) < 0) { g_printerr ("Failed to connect to socket %s: %s", plain_sockets_address, strerror (errno)); exit (1); } context = g_main_context_new (); cd.iterations = 1; cd.loop = g_main_loop_new (context, FALSE); cd.vtable = data; channel = g_io_channel_unix_new (fd); gsource = g_io_create_watch (channel, G_IO_IN | G_IO_OUT | G_IO_ERR | G_IO_HUP | G_IO_NVAL | G_IO_PRI); g_source_set_callback (gsource, (GSourceFunc)plain_sockets_client_side_watch, &cd, NULL); g_source_attach (gsource, context); g_io_channel_unref (channel); g_printerr ("Client thread writing to prime pingpong\n"); write_junk (fd, echo_call_size, cd.vtable->fake_malloc_overhead); g_printerr ("Client thread done writing primer\n"); g_printerr ("Client thread entering main loop\n"); g_main_loop_run (cd.loop); g_printerr ("Client thread %p exiting main loop\n", g_thread_self()); g_source_destroy (gsource); close (fd); g_main_loop_unref (cd.loop); g_main_context_unref (context); return NULL; }
/* program main */ int main() { char* tmsg = NULL; int main_tmo = 5; int loop1_tmo = 2 * main_tmo; int loop2_tmo = 3; twmsg(__func__, "STARTING"); /* setup the main loop structure */ tmsg=g_strdup_printf("creating main context, TMO=%d", main_tmo); twmsg(__func__, tmsg); g_free(tmsg); loop_main.name = g_strdup("MAIN"); loop_main.tmo = main_tmo; /* seconds for callback */ loop_main.main_context = NULL; /* use default */ loop_main.main_loop = g_main_loop_new (loop_main.main_context, FALSE); loop_main.idle = g_idle_source_new(); g_source_set_callback(loop_main.idle, idle_func, &loop_main, NULL); g_source_attach(loop_main.idle, loop_main.main_context); loop_main.main_context = NULL; /* use default */ loop_main.Q = NULL; /* no queue, for now */ loop_main.TH = NULL; /* this is the main thread so no thread info */ /* interval, function callback, userdata * - internally creates source and attaches to main context */ g_timeout_add_seconds(loop_main.tmo, tmo_callback, "tmo_callback"); /* create info for the worker thread and set up its context, then run it */ tmsg=g_strdup_printf("creating loop1 context, TMO=%d", loop1_tmo); twmsg(__func__, tmsg); g_free(tmsg); loop_main.name = g_strdup("LOOP_1"); loop_1.tmo = loop1_tmo; loop_1.main_context = g_main_context_new(); loop_1.main_loop = g_main_loop_new(loop_1.main_context, FALSE); loop_1.idle = g_idle_source_new(); g_source_set_callback(loop_1.idle, idle_func, &loop_1, NULL); g_source_attach(loop_1.idle, loop_1.main_context); loop_1.Q = g_async_queue_new(); /* manually create new timeout source and attach to main context of nth Loop * - timeout is in ms so multiply seconds by 1000 * - set priority to 1 or 2 * - optionally set name */ GSource *source1 = g_timeout_source_new (loop_1.tmo*1000); g_source_set_priority (source1, 1); g_source_set_callback (source1, tmo_callback, "tmo_loop1_callback", NULL); g_source_set_name (source1, "LOOP1_TMO"); g_source_attach (source1, loop_1.main_context); /* run the thread which will run the main context */ loop_1.TH = g_thread_new("LOOP1_TH", loop_thread, &loop_1); /* create info for the second worker thread and set up its context, then run it */ tmsg=g_strdup_printf("creating loop2 context, TMO=%d", loop2_tmo); twmsg(__func__, tmsg); g_free(tmsg); /* init the data for the context */ loop_2.name = g_strdup("LOOP_2"); loop_2.tmo = loop2_tmo; loop_2.main_context = g_main_context_new(); loop_2.main_loop = g_main_loop_new(loop_2.main_context, FALSE); loop_2.idle = g_idle_source_new(); g_source_set_callback(loop_2.idle, idle_func, &loop_2, NULL); g_source_attach(loop_2.idle, loop_2.main_context); loop_2.Q = g_async_queue_new(); /* manually create new timeout source and attach to main context of nth Loop * - timeout is in ms so multiply seconds by 1000 * - set priority to 1 or 2 * - optionally set name */ GSource *source2 = g_timeout_source_new (loop_2.tmo*1000); g_source_set_priority (source2, 1); g_source_set_callback (source2, tmo_callback, "tmo_loop2_callback", NULL); g_source_set_name (source2, "LOOP2_TMO"); g_source_attach (source2, loop_2.main_context); /* run the second thread */ loop_2.TH = g_thread_new("LOOP2_TH", loop_thread, &loop_2); /* run the main loop */ g_main_loop_run(loop_main.main_loop); return 0; }
int main(){ int usbErr = 0; int iface_num[NUM_IFACES]; iface_num[0]= 1; // bulk interface libusb_context *imu_host = NULL; libusb_device_handle *imu_handle = NULL; libusbSource * usb_source = NULL; struct libusb_transfer * bulkIO[2]; //todo: have something like endpoint[numendpoints] and place each transfer at the ep they correspond to? struct libusb_transfer * bulk_in = NULL;//bulkIO[0]; struct libusb_transfer * bulk_out = NULL;//bulkIO[1]; unsigned char * bulk_in_buffer = NULL; unsigned char * bulk_out_buffer = NULL; GMainContext * edfc_context = NULL; GIOChannel * g_stdin = NULL; GSource * gs_stdin = NULL; sfd = open_port(); usbErr = libusb_init(&imu_host); if(usbErr){ print_libusb_error(usbErr, "libusb_init"); exit(EXIT_FAILURE); } libusb_set_debug(imu_host, 3); imu_handle = open_usb_device_handle(imu_host, is_imu_device, iface_num, NUM_IFACES); if(!imu_handle){ printf("**imu_handle acquisition error\n"); libusb_exit(imu_host); exit(EXIT_FAILURE); } usb_source = libusb_source_new(imu_host); // g_source_set_callback((GSource*) usb_source, (GSourceFunc)libusb_mainloop_error_cb, &edfc_main, NULL); bulk_in = libusb_alloc_transfer(0); bulk_out = libusb_alloc_transfer(0); bulk_in_buffer = calloc(MAX_PACKET_SIZE, sizeof(unsigned char)); //todo: slice allocate? bulk_out_buffer = calloc(MAX_PACKET_SIZE, sizeof(unsigned char)); //todo: slice allocate? libusb_fill_bulk_transfer(bulk_in, imu_handle, BULK_IN_EP, bulk_in_buffer, MAX_PACKET_SIZE, bulk_in_cb, NULL, 0); libusb_fill_bulk_transfer(bulk_out, imu_handle, BULK_OUT_EP, bulk_out_buffer, MAX_PACKET_SIZE, bulk_out_cb, NULL, 0); bulkIO[0] = bulk_in; bulkIO[1] = bulk_out; edfc_context = g_main_context_new(); //edfc == event driven flight computer edfc_main = g_main_loop_new(edfc_context, FALSE); g_stdin = g_io_channel_unix_new(fileno(stdin)); if(!g_stdin){ printf("error creating g_stdin\n"); } g_source_attach((GSource*) usb_source, edfc_context); gs_stdin = g_io_create_watch(g_stdin, G_IO_IN | G_IO_ERR | G_IO_HUP); g_source_set_callback(gs_stdin, (GSourceFunc)read_g_stdin, bulkIO, NULL); g_source_attach(gs_stdin, edfc_context); printf("beginning main loop\n"); g_main_loop_run(edfc_main); printf("main loop finished\n"); //cleanup g_source_destroy(gs_stdin); g_io_channel_shutdown(g_stdin, TRUE, NULL); //todo: fix null free(bulk_in_buffer); free(bulk_out_buffer); libusb_free_transfer(bulk_in); libusb_free_transfer(bulk_out); g_source_destroy((GSource*) usb_source); g_main_loop_unref(edfc_main); g_main_context_unref(edfc_context); usbErr = libusb_release_interface(imu_handle, iface_num[0]); if(usbErr) print_libusb_error(usbErr, "exit libusb_release_interface"); usbErr = libusb_attach_kernel_driver(imu_handle, iface_num[0]); if(usbErr) print_libusb_error(usbErr, "exit libusb_attach_kernel_driver"); libusb_close(imu_handle); libusb_exit(imu_host); exit(EXIT_SUCCESS); }
int main(int argc, char **argv) { setlocale(LC_ALL, ""); // Early logging goes to stderr stderrlog = stderr; // parse commandline options GOptionContext *optx = g_option_context_new("- NCurses Direct Connect"); g_option_context_add_main_entries(optx, cli_options, NULL); GError *err = NULL; if(!g_option_context_parse(optx, &argc, &argv, &err)) { puts(err->message); exit(1); } g_option_context_free(optx); // check that the current locale is UTF-8. Things aren't going to work otherwise if(!g_get_charset(NULL)) { puts("WARNING: Your current locale is not set to UTF-8."); puts("Non-ASCII characters may not display correctly."); puts("Hit Ctrl+c to abort ncdc, or the return key to continue anyway."); getchar(); } // init stuff init_crypt(); g_thread_init(NULL); // Create main loop main_loop = g_main_loop_new(NULL, FALSE); // setup logging g_log_set_handler(NULL, G_LOG_FATAL_MASK | G_LOG_FLAG_FATAL | G_LOG_LEVEL_ERROR, log_fatal, NULL); g_log_set_default_handler(log_redirect, NULL); // Init database & variables db_init(); vars_init(); // open log file char *errlog = g_build_filename(db_dir, "stderr.log", NULL); if(!(stderrlog = fopen(errlog, "w"))) { fprintf(stderr, "ERROR: Couldn't open %s for writing: %s\n", errlog, strerror(errno)); exit(1); } g_free(errlog); // Init more stuff hub_init_global(); net_init_global(); listen_global_init(); cc_global_init(); dl_init_global(); ui_cmdhist_init("history"); ui_init(bracketed_paste); geoip_reinit(4); geoip_reinit(6); // setup SIGWINCH struct sigaction act; sigemptyset(&act.sa_mask); act.sa_flags = SA_RESTART; act.sa_handler = catch_sigwinch; if(sigaction(SIGWINCH, &act, NULL) < 0) g_error("Can't setup SIGWINCH: %s", g_strerror(errno)); // setup SIGTERM act.sa_handler = catch_sigterm; if(sigaction(SIGTERM, &act, NULL) < 0) g_error("Can't setup SIGTERM: %s", g_strerror(errno)); // setup SIGHUP act.sa_handler = catch_sighup; if(sigaction(SIGHUP, &act, NULL) < 0) g_error("Can't setup SIGHUP: %s", g_strerror(errno)); // setup SIGUSR1 act.sa_handler = catch_sigusr1; if(sigaction(SIGUSR1, &act, NULL) < 0) g_error("Can't setup SIGUSR1: %s", g_strerror(errno)); // setup SIGPIPE act.sa_handler = catch_sigpipe; if(sigaction(SIGPIPE, &act, NULL) < 0) g_error("Can't setup SIGPIPE: %s", g_strerror(errno)); fl_init(); if(auto_open) open_autoconnect(); // add some watches and start the main loop GIOChannel *in = g_io_channel_unix_new(STDIN_FILENO); g_io_add_watch(in, G_IO_IN, stdin_read, NULL); GSource *sighandle = g_source_new(&sighandle_funcs, sizeof(GSource)); g_source_set_priority(sighandle, G_PRIORITY_HIGH); g_source_set_callback(sighandle, sighandle_sourcefunc, NULL, NULL); g_source_attach(sighandle, NULL); g_source_unref(sighandle); g_timeout_add_seconds_full(G_PRIORITY_HIGH, 1, one_second_timer, NULL, NULL); g_timeout_add(100, screen_update_check, NULL); int maxage = var_get_int(0, VAR_filelist_maxage); g_timeout_add_seconds_full(G_PRIORITY_LOW, CLAMP(maxage, 3600, 24*3600), dl_fl_clean, NULL, NULL); g_main_loop_run(main_loop); // cleanup if(!main_noterm) { erase(); refresh(); endwin(); if(bracketed_paste) ui_set_bracketed_paste(0); printf("Flushing unsaved data to disk..."); fflush(stdout); } ui_cmdhist_close(); cc_global_close(); fl_flush(NULL); dl_close_global(); db_close(); gnutls_global_deinit(); if(!main_noterm) printf(" Done!\n"); g_debug("Clean shutdown."); return 0; }
/** * CommandIfaceStartNB(): _non-blocking_ start request * * @param pMgr Pointer to the parent test command manager (e.g., * for stopping test execution) * @param pMgrRd Command Manager's RuntimeDispatcher instance; * the command handler may use it for running its * own logic, if needed. */ void CommandIfaceStartNB(TestCmdMgr* pMgr, wsf::RuntimeDispatcher* pMgrRd) { UTIL_PRINT_LINE("%s: Starting...", args_[0]); class StartRaii { public: StartRaii() : pThreadCtx(NULL) { } ~StartRaii() { if (pThreadCtx) { PmSockThreadCtxUnref(pThreadCtx); } } public: PmSockThreadContext* pThreadCtx; };//class StartRaii StartRaii raii; GMainLoop* const gmainloop = (GMainLoop*)wsf::RuntimeDispatcher::GetInternalLoop(*pMgrRd); assert(gmainloop); GMainContext* const gmainctx = ::g_main_loop_get_context(gmainloop); assert(gmainctx); /// Create a palmsocket thread context PslError pslErr = ::PmSockThreadCtxNewFromGMain( gmainctx, args_[0], &raii.pThreadCtx); if (pslErr) { const std::string errorMsg = std::string("PmSockThreadCtxNewFromGMain failed: ") + ::PmSockErrStringFromError(pslErr); UTIL_THROW_FATAL(args_[0], errorMsg.c_str()); } pslErr = ::PmSockCreateChannel( raii.pThreadCtx, (PmSockOptionFlags)0/*options*/, args_[0], &pChan_); if (!pslErr) { assert(pChan_); } else { const std::string errorMsg( std::string("PmSockCreateChannel failed: ") + ::PmSockErrStringFromError(pslErr)); UTIL_THROW_FATAL(args_[0], errorMsg.c_str()); } GSource* pTimeout = g_timeout_source_new(0/*interval*/); g_source_set_priority(pTimeout, G_PRIORITY_LOW); g_source_set_callback(pTimeout, &TimeoutGSourceFunc, this, NULL/*GDestroyNotify*/); g_source_attach(pTimeout, gmainctx); g_source_unref(pTimeout); }//CommandIfaceStartNB
/* Called in new thread */ static gboolean on_run (GSocketService *service, GSocketConnection *socket_connection, GObject *source_object, gpointer user_data) { GDBusServer *server = G_DBUS_SERVER (user_data); GDBusConnection *connection; GDBusConnectionFlags connection_flags; if (server->nonce != NULL) { gchar buf[16]; gsize bytes_read; if (!g_input_stream_read_all (g_io_stream_get_input_stream (G_IO_STREAM (socket_connection)), buf, 16, &bytes_read, NULL, /* GCancellable */ NULL)) /* GError */ goto out; if (bytes_read != 16) goto out; if (memcmp (buf, server->nonce, 16) != 0) goto out; } connection_flags = G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER | G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING; if (server->flags & G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS) connection_flags |= G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS; connection = g_dbus_connection_new_sync (G_IO_STREAM (socket_connection), server->guid, connection_flags, server->authentication_observer, NULL, /* GCancellable */ NULL); /* GError */ if (connection == NULL) goto out; if (server->flags & G_DBUS_SERVER_FLAGS_RUN_IN_THREAD) { gboolean claimed; claimed = FALSE; g_signal_emit (server, _signals[NEW_CONNECTION_SIGNAL], 0, connection, &claimed); if (claimed) g_dbus_connection_start_message_processing (connection); g_object_unref (connection); } else { GSource *idle_source; EmitIdleData *data; data = g_new0 (EmitIdleData, 1); data->server = g_object_ref (server); data->connection = g_object_ref (connection); idle_source = g_idle_source_new (); g_source_set_priority (idle_source, G_PRIORITY_DEFAULT); g_source_set_callback (idle_source, emit_new_connection_in_idle, data, (GDestroyNotify) emit_idle_data_free); g_source_attach (idle_source, server->main_context_at_construction); g_source_unref (idle_source); } out: return TRUE; }
static void * glib_ctx_add(void *ctx, const verto_ev *ev, verto_ev_flag *flags) { glib_ev *gev = NULL; GIOCondition cond = 0; verto_ev_type type = verto_get_type(ev); gev = g_new0(glib_ev, 1); if (!gev) return NULL; switch (type) { case VERTO_EV_TYPE_IO: #ifdef WIN32 gev->chan = g_io_channel_win32_new_socket(verto_get_fd(ev)); #else gev->chan = g_io_channel_unix_new(verto_get_fd(ev)); #endif if (!gev->chan) goto error; g_io_channel_set_close_on_unref(gev->chan, FALSE); if (*flags & VERTO_EV_FLAG_IO_READ) cond |= G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP | G_IO_NVAL; if (*flags & VERTO_EV_FLAG_IO_WRITE) cond |= G_IO_OUT | G_IO_ERR | G_IO_HUP | G_IO_NVAL; gev->src = g_io_create_watch(gev->chan, cond); break; case VERTO_EV_TYPE_TIMEOUT: gev->src = g_timeout_source_new(verto_get_interval(ev)); break; case VERTO_EV_TYPE_IDLE: gev->src = g_idle_source_new(); break; case VERTO_EV_TYPE_CHILD: gev->src = g_child_watch_source_new(verto_get_proc(ev)); *flags &= ~VERTO_EV_FLAG_PERSIST; /* Child events don't persist */ break; case VERTO_EV_TYPE_SIGNAL: #if GLIB_MAJOR_VERSION >= 2 #if GLIB_MINOR_VERSION >= 29 #ifdef G_OS_UNIX /* Not supported on Windows */ gev->src = g_unix_signal_source_new(verto_get_signal(ev)); break; #endif #endif /* GLIB_MINOR_VERSION >= 29 */ #endif /* GLIB_MAJOR_VERSION >= 2 */ default: return NULL; /* Not supported */ } if (!gev->src) goto error; if (type == VERTO_EV_TYPE_IO) g_source_set_callback(gev->src, (GSourceFunc) glib_callback_io, (void *) ev, NULL); else if (type == VERTO_EV_TYPE_CHILD) g_source_set_callback(gev->src, (GSourceFunc) glib_callback_child, (void *) ev, NULL); else g_source_set_callback(gev->src, glib_callback, (void *) ev, NULL); if (*flags & VERTO_EV_FLAG_PRIORITY_HIGH) g_source_set_priority(gev->src, G_PRIORITY_HIGH); else if (*flags & VERTO_EV_FLAG_PRIORITY_MEDIUM) g_source_set_priority(gev->src, G_PRIORITY_DEFAULT_IDLE); else if (*flags & VERTO_EV_FLAG_PRIORITY_LOW) g_source_set_priority(gev->src, G_PRIORITY_LOW); g_source_set_can_recurse(gev->src, FALSE); if (g_source_attach(gev->src, ((glib_ev_ctx*) ctx)->context) == 0) goto error; return gev; error: if (gev) { if (gev->chan) g_io_channel_unref(gev->chan); if (gev->src) { g_source_destroy(gev->src); g_source_unref(gev->src); } g_free(gev); } return NULL; }
gboolean gimp_plug_in_open (GimpPlugIn *plug_in, GimpPlugInCallMode call_mode, gboolean synchronous) { gchar *progname; gint my_read[2]; gint my_write[2]; gchar **envp; const gchar *args[9]; gchar **argv; gint argc; gchar *interp, *interp_arg; gchar *read_fd, *write_fd; const gchar *mode; gchar *stm; GError *error = NULL; gboolean debug; guint debug_flag; guint spawn_flags; g_return_val_if_fail (GIMP_IS_PLUG_IN (plug_in), FALSE); g_return_val_if_fail (plug_in->call_mode == GIMP_PLUG_IN_CALL_NONE, FALSE); /* Open two pipes. (Bidirectional communication). */ if ((pipe (my_read) == -1) || (pipe (my_write) == -1)) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "Unable to run plug-in \"%s\"\n(%s)\n\npipe() failed: %s", gimp_object_get_name (plug_in), gimp_file_get_utf8_name (plug_in->file), g_strerror (errno)); return FALSE; } #if defined(G_WITH_CYGWIN) /* Set to binary mode */ setmode (my_read[0], _O_BINARY); setmode (my_write[0], _O_BINARY); setmode (my_read[1], _O_BINARY); setmode (my_write[1], _O_BINARY); #endif #ifdef G_OS_WIN32 /* Prevent the plug-in from inheriting our ends of the pipes */ SetHandleInformation ((HANDLE) _get_osfhandle (my_read[0]), HANDLE_FLAG_INHERIT, 0); SetHandleInformation ((HANDLE) _get_osfhandle (my_write[1]), HANDLE_FLAG_INHERIT, 0); #endif plug_in->my_read = g_io_channel_unix_new (my_read[0]); plug_in->my_write = g_io_channel_unix_new (my_write[1]); plug_in->his_read = g_io_channel_unix_new (my_write[0]); plug_in->his_write = g_io_channel_unix_new (my_read[1]); g_io_channel_set_encoding (plug_in->my_read, NULL, NULL); g_io_channel_set_encoding (plug_in->my_write, NULL, NULL); g_io_channel_set_encoding (plug_in->his_read, NULL, NULL); g_io_channel_set_encoding (plug_in->his_write, NULL, NULL); g_io_channel_set_buffered (plug_in->my_read, FALSE); g_io_channel_set_buffered (plug_in->my_write, FALSE); g_io_channel_set_buffered (plug_in->his_read, FALSE); g_io_channel_set_buffered (plug_in->his_write, FALSE); g_io_channel_set_close_on_unref (plug_in->my_read, TRUE); g_io_channel_set_close_on_unref (plug_in->my_write, TRUE); g_io_channel_set_close_on_unref (plug_in->his_read, TRUE); g_io_channel_set_close_on_unref (plug_in->his_write, TRUE); /* Remember the file descriptors for the pipes. */ read_fd = g_strdup_printf ("%d", g_io_channel_unix_get_fd (plug_in->his_read)); write_fd = g_strdup_printf ("%d", g_io_channel_unix_get_fd (plug_in->his_write)); switch (call_mode) { case GIMP_PLUG_IN_CALL_QUERY: mode = "-query"; debug_flag = GIMP_DEBUG_WRAP_QUERY; break; case GIMP_PLUG_IN_CALL_INIT: mode = "-init"; debug_flag = GIMP_DEBUG_WRAP_INIT; break; case GIMP_PLUG_IN_CALL_RUN: mode = "-run"; debug_flag = GIMP_DEBUG_WRAP_RUN; break; default: g_assert_not_reached (); } stm = g_strdup_printf ("%d", plug_in->manager->gimp->stack_trace_mode); progname = g_file_get_path (plug_in->file); interp = gimp_interpreter_db_resolve (plug_in->manager->interpreter_db, progname, &interp_arg); argc = 0; if (interp) args[argc++] = interp; if (interp_arg) args[argc++] = interp_arg; args[argc++] = progname; args[argc++] = "-gimp"; args[argc++] = read_fd; args[argc++] = write_fd; args[argc++] = mode; args[argc++] = stm; args[argc++] = NULL; argv = (gchar **) args; envp = gimp_environ_table_get_envp (plug_in->manager->environ_table); spawn_flags = (G_SPAWN_LEAVE_DESCRIPTORS_OPEN | G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_CHILD_INHERITS_STDIN); debug = FALSE; if (plug_in->manager->debug) { gchar **debug_argv = gimp_plug_in_debug_argv (plug_in->manager->debug, progname, debug_flag, args); if (debug_argv) { debug = TRUE; argv = debug_argv; spawn_flags |= G_SPAWN_SEARCH_PATH; } } /* Fork another process. We'll remember the process id so that we * can later use it to kill the filter if necessary. */ if (! g_spawn_async (NULL, argv, envp, spawn_flags, gimp_plug_in_prep_for_exec, plug_in, &plug_in->pid, &error)) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "Unable to run plug-in \"%s\"\n(%s)\n\n%s", gimp_object_get_name (plug_in), gimp_file_get_utf8_name (plug_in->file), error->message); g_clear_error (&error); g_free (progname); goto cleanup; } g_io_channel_unref (plug_in->his_read); plug_in->his_read = NULL; g_io_channel_unref (plug_in->his_write); plug_in->his_write = NULL; if (! synchronous) { GSource *source; source = g_io_create_watch (plug_in->my_read, G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP); g_source_set_callback (source, (GSourceFunc) gimp_plug_in_recv_message, plug_in, NULL); g_source_set_can_recurse (source, TRUE); plug_in->input_id = g_source_attach (source, NULL); g_source_unref (source); } plug_in->open = TRUE; plug_in->call_mode = call_mode; gimp_plug_in_manager_add_open_plug_in (plug_in->manager, plug_in); cleanup: if (debug) g_free (argv); g_free (read_fd); g_free (write_fd); g_free (stm); g_free (interp); g_free (interp_arg); g_free (progname); return plug_in->open; }
osync_bool osync_queue_connect(OSyncQueue *queue, OSyncQueueType type, OSyncError **error) { #ifdef _WIN32 return FALSE; #else //_WIN32 OSyncQueue **queueptr = NULL; osync_trace(TRACE_ENTRY, "%s(%p, %i, %p)", __func__, queue, type, error); osync_assert(queue); osync_assert(queue->connected == FALSE); queue->type = type; if (queue->fd == -1) { /* First, open the queue with the flags provided by the user */ int fd = open(queue->name, type == OSYNC_QUEUE_SENDER ? O_WRONLY : O_RDONLY); if (fd == -1) { osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to open fifo"); goto error; } queue->fd = fd; } int oldflags = fcntl(queue->fd, F_GETFD); if (oldflags == -1) { osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to get fifo flags"); goto error_close; } if (fcntl(queue->fd, F_SETFD, oldflags|FD_CLOEXEC) == -1) { osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to set fifo flags"); goto error_close; } queue->connected = TRUE; signal(SIGPIPE, SIG_IGN); /* now we start a thread which handles reading/writing of the queue */ queue->thread = osync_thread_new(queue->context, error); if (!queue->thread) goto error; queue->write_functions = g_malloc0(sizeof(GSourceFuncs)); queue->write_functions->prepare = _queue_prepare; queue->write_functions->check = _queue_check; queue->write_functions->dispatch = _queue_dispatch; queue->write_functions->finalize = NULL; queue->write_source = g_source_new(queue->write_functions, sizeof(GSource) + sizeof(OSyncQueue *)); queueptr = (OSyncQueue **)(queue->write_source + 1); *queueptr = queue; g_source_set_callback(queue->write_source, NULL, queue, NULL); g_source_attach(queue->write_source, queue->context); if (queue->context) g_main_context_ref(queue->context); queue->read_functions = g_malloc0(sizeof(GSourceFuncs)); queue->read_functions->prepare = _source_prepare; queue->read_functions->check = _source_check; queue->read_functions->dispatch = _source_dispatch; queue->read_functions->finalize = NULL; queue->read_source = g_source_new(queue->read_functions, sizeof(GSource) + sizeof(OSyncQueue *)); queueptr = (OSyncQueue **)(queue->read_source + 1); *queueptr = queue; g_source_set_callback(queue->read_source, NULL, queue, NULL); g_source_attach(queue->read_source, queue->context); if (queue->context) g_main_context_ref(queue->context); queue->timeout_functions = g_malloc0(sizeof(GSourceFuncs)); queue->timeout_functions->prepare = _timeout_prepare; queue->timeout_functions->check = _timeout_check; queue->timeout_functions->dispatch = _timeout_dispatch; queue->timeout_functions->finalize = NULL; queue->timeout_source = g_source_new(queue->timeout_functions, sizeof(GSource) + sizeof(OSyncQueue *)); queueptr = (OSyncQueue **)(queue->timeout_source + 1); *queueptr = queue; g_source_set_callback(queue->timeout_source, NULL, queue, NULL); g_source_attach(queue->timeout_source, queue->context); if (queue->context) g_main_context_ref(queue->context); osync_thread_start(queue->thread); osync_trace(TRACE_EXIT, "%s", __func__); return TRUE; error_close: close(queue->fd); error: osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); return FALSE; #endif //_WIN32 }
void event_activate( event_handle_t *handle) { GIOCondition cond; assert(handle != NULL); g_static_mutex_lock(&event_mutex); /* add to the list of events */ all_events = g_slist_prepend(all_events, (gpointer)handle); /* and set up the GSource for this event */ switch (handle->type) { case EV_READFD: case EV_WRITEFD: /* create a new source */ if (handle->type == EV_READFD) { cond = G_IO_IN | G_IO_HUP | G_IO_ERR; } else { cond = G_IO_OUT | G_IO_ERR; } handle->source = new_fdsource(handle->data, cond); /* attach it to the default GMainLoop */ g_source_attach(handle->source, NULL); handle->source_id = g_source_get_id(handle->source); /* And set its callbacks */ g_source_set_callback(handle->source, event_handle_callback, (gpointer)handle, NULL); /* drop our reference to it, so when it's detached, it will be * destroyed. */ g_source_unref(handle->source); break; case EV_TIME: /* Glib provides a nice shortcut for timeouts. The *1000 converts * seconds to milliseconds. */ handle->source_id = g_timeout_add(handle->data * 1000, event_handle_callback, (gpointer)handle); /* But it doesn't give us the source directly.. */ handle->source = g_main_context_find_source_by_id(NULL, handle->source_id); /* EV_TIME must always be handled after EV_READ */ g_source_set_priority(handle->source, 10); break; case EV_WAIT: /* nothing to do -- these are handled independently of GMainLoop */ break; default: error(_("Unknown event type %s"), event_type2str(handle->type)); } g_static_mutex_unlock(&event_mutex); return; }
static void swfdec_playback_stream_open (SwfdecPlayback *sound, SwfdecAudio *audio) { GIOChannel *channel; Stream *stream; guint rate; int dsp_fd, ret, format, channels, fragsize; dsp_fd = open("/dev/dsp", O_WRONLY); if (dsp_fd == -1) { g_printerr ("Failed to open /dev/dsp\n"); return; } format = AFMT_S16_LE; ret = ioctl(dsp_fd, SNDCTL_DSP_SETFMT, &format); if (ret == -1) { g_printerr ("Failed to set sound format\n"); close(dsp_fd); return; } channels = 2; ret = ioctl(dsp_fd, SNDCTL_DSP_CHANNELS, &channels); if (ret == -1) { g_printerr ("Failed to set stereo\n"); close(dsp_fd); return; } rate = 44100; ret = ioctl(dsp_fd, SNDCTL_DSP_SPEED, &rate); if (ret == -1) { g_printerr ("Failed to set rate\n"); close(dsp_fd); return; } ret = ioctl(dsp_fd, SNDCTL_DSP_GETBLKSIZE, &fragsize); if (ret == -1) { g_printerr ("Failed to get fragment size\n"); close(dsp_fd); return; } stream = g_new0 (Stream, 1); stream->sound = sound; stream->audio = g_object_ref (audio); stream->dsp_fd = dsp_fd; stream->fragsize = fragsize; sound->streams = g_list_prepend (sound->streams, stream); channel = g_io_channel_unix_new (stream->dsp_fd); stream->source = g_io_create_watch (channel, G_IO_OUT); g_source_set_priority (stream->source, G_PRIORITY_HIGH); g_source_set_callback (stream->source, (GSourceFunc) handle_stream, stream, NULL); g_io_channel_unref (channel); g_source_attach (stream->source, stream->sound->context); return; }
phStatus_t phOsal_GLib_Timer_Start( phOsal_GLib_DataParams_t *pDataParams, uint32_t dwTimerId, uint32_t dwRegTimeCnt, uint16_t wOption, ppCallBck_t pApplicationCallback, void *pContext ) { //g_debug("Starting timer %d...\r\n", dwTimerId); if( (dwTimerId > OSAL_GLIB_MAX_TIMERS) || (pDataParams->gTimers[dwTimerId].bTimerFree == TIMER_FREE) ) { /* Can't use a non existent timer */ /* Can't start a free timer, first create the timer */ return PH_ADD_COMPCODE(PH_ERR_INTERNAL_ERROR, PH_COMP_OSAL); } if( pDataParams->gTimers[dwTimerId].pGTimeoutSource != NULL ) { //Cannot start at timer which is already running g_error("Timer %d already running\n", dwTimerId); return PH_ADD_COMPCODE(PH_ERR_INTERNAL_ERROR, PH_COMP_OSAL); } //Convert usecs to millisecs if needed if( wOption == 0 ) // { //g_debug("%d us", dwRegTimeCnt); //We're running in user-mode on a (probably) non realtime kernel, so even millisecs are very approximate if( dwRegTimeCnt < 1000 ) { pDataParams->gTimers[dwTimerId].dwMillisecs = 1; } else { pDataParams->gTimers[dwTimerId].dwMillisecs = dwRegTimeCnt / 1000; } } else //These are already millisecs { //g_debug("%d ms", dwRegTimeCnt); pDataParams->gTimers[dwTimerId].dwMillisecs = dwRegTimeCnt; } //Remember callback pDataParams->gTimers[dwTimerId].pApplicationCallback = pApplicationCallback; pDataParams->gTimers[dwTimerId].pContext = pContext; //Create source pDataParams->gTimers[dwTimerId].pGTimeoutSource = g_timeout_source_new(pDataParams->gTimers[dwTimerId].dwMillisecs); if( pDataParams->gTimers[dwTimerId].pGTimeoutSource == NULL) { return PH_ADD_COMPCODE(PH_ERR_INSUFFICIENT_RESOURCES, PH_COMP_OSAL); } //Set callback g_source_set_callback(pDataParams->gTimers[dwTimerId].pGTimeoutSource, phOsal_Int_Timer_Callback, &pDataParams->gTimers[dwTimerId], NULL); //Attach source to context g_source_attach(pDataParams->gTimers[dwTimerId].pGTimeoutSource, pDataParams->pgGLibMainContext); return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_OSAL); }
/* * Received a message */ static void message_received_cb (G_GNUC_UNUSED GSSDPClient *client, const char *from_ip, gushort from_port, _GSSDPMessageType type, SoupMessageHeaders *headers, gpointer user_data) { GSSDPResourceGroup *resource_group; GSSDPResourceGroupPrivate *priv; const char *target, *mx_str, *version_str, *man; gboolean want_all; int mx, version; GList *l; resource_group = GSSDP_RESOURCE_GROUP (user_data); priv = gssdp_resource_group_get_instance_private (resource_group); /* Only process if we are available */ if (!priv->available) return; /* We only handle discovery requests */ if (type != _GSSDP_DISCOVERY_REQUEST) return; /* Extract target */ target = soup_message_headers_get_one (headers, "ST"); if (target == NULL) { g_warning ("Discovery request did not have an ST header"); return; } /* Is this the "ssdp:all" target? */ want_all = (strcmp (target, GSSDP_ALL_RESOURCES) == 0); /* Extract MX */ mx_str = soup_message_headers_get_one (headers, "MX"); if (mx_str == NULL || atoi (mx_str) <= 0) { g_warning ("Discovery request did not have a valid MX header"); return; } man = soup_message_headers_get_one (headers, "MAN"); if (man == NULL || strcmp (man, DEFAULT_MAN_HEADER) != 0) { g_warning ("Discovery request did not have a valid MAN header"); return; } mx = atoi (mx_str); /* Extract version */ version_str = get_version_for_target ((char *) target); if (version_str != NULL) version = atoi (version_str); else version = 0; /* Find matching resource */ for (l = priv->resources; l != NULL; l = l->next) { Resource *resource; resource = l->data; if (want_all || (g_regex_match (resource->target_regex, target, 0, NULL) && (guint) version <= resource->version)) { /* Match. */ guint timeout; DiscoveryResponse *response; /* Get a random timeout from the interval [0, mx] */ timeout = g_random_int_range (0, mx * 1000); /* Prepare response */ response = g_slice_new (DiscoveryResponse); response->dest_ip = g_strdup (from_ip); response->dest_port = from_port; response->resource = resource; if (want_all) response->target = g_strdup (resource->target); else response->target = g_strdup (target); /* Add timeout */ response->timeout_src = g_timeout_source_new (timeout); g_source_set_callback (response->timeout_src, discovery_response_timeout, response, NULL); g_source_attach (response->timeout_src, g_main_context_get_thread_default ()); g_source_unref (response->timeout_src); /* Add to resource */ resource->responses = g_list_prepend (resource->responses, response); } } }
static void ul_spawned_job_constructed (GObject *object) { UlSpawnedJob *self = UL_SPAWNED_JOB (object); GError *error; gchar *cmd; G_OBJECT_CLASS (ul_spawned_job_parent_class)->constructed (object); cmd = g_strjoinv (" ", self->argv); g_debug ("spawned job: %s", cmd); self->main_context = g_main_context_get_thread_default (); if (self->main_context != NULL) g_main_context_ref (self->main_context); /* could already be cancelled */ error = NULL; if (g_cancellable_set_error_if_cancelled (ul_job_get_cancellable (UL_JOB (self)), &error)) { emit_completed_with_error_in_idle (self, error); g_error_free (error); goto out; } self->cancellable_handler_id = g_cancellable_connect (ul_job_get_cancellable (UL_JOB (self)), G_CALLBACK (on_cancelled), self, NULL); error = NULL; if (!g_spawn_async_with_pipes (NULL, /* working directory */ self->argv, NULL, /* envp */ G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, child_setup, /* child_setup */ self, /* child_setup's user_data */ &(self->child_pid), self->input_string != NULL ? &(self->child_stdin_fd) : NULL, &(self->child_stdout_fd), &(self->child_stderr_fd), &error)) { g_prefix_error (&error, "Error spawning command-line `%s': ", cmd); emit_completed_with_error_in_idle (self, error); g_error_free (error); goto out; } self->child_watch_source = g_child_watch_source_new (self->child_pid); g_source_set_callback (self->child_watch_source, (GSourceFunc) child_watch_cb, self, NULL); g_source_attach (self->child_watch_source, self->main_context); g_source_unref (self->child_watch_source); if (self->child_stdin_fd != -1) { self->input_string_cursor = self->input_string; self->child_stdin_channel = g_io_channel_unix_new (self->child_stdin_fd); g_io_channel_set_flags (self->child_stdin_channel, G_IO_FLAG_NONBLOCK, NULL); self->child_stdin_source = g_io_create_watch (self->child_stdin_channel, G_IO_OUT); g_source_set_callback (self->child_stdin_source, (GSourceFunc) write_child_stdin, self, NULL); g_source_attach (self->child_stdin_source, self->main_context); g_source_unref (self->child_stdin_source); } self->child_stdout_channel = g_io_channel_unix_new (self->child_stdout_fd); g_io_channel_set_flags (self->child_stdout_channel, G_IO_FLAG_NONBLOCK, NULL); self->child_stdout_source = g_io_create_watch (self->child_stdout_channel, G_IO_IN); g_source_set_callback (self->child_stdout_source, (GSourceFunc) read_child_stdout, self, NULL); g_source_attach (self->child_stdout_source, self->main_context); g_source_unref (self->child_stdout_source); self->child_stderr_channel = g_io_channel_unix_new (self->child_stderr_fd); g_io_channel_set_flags (self->child_stderr_channel, G_IO_FLAG_NONBLOCK, NULL); self->child_stderr_source = g_io_create_watch (self->child_stderr_channel, G_IO_IN); g_source_set_callback (self->child_stderr_source, (GSourceFunc) read_child_stderr, self, NULL); g_source_attach (self->child_stderr_source, self->main_context); g_source_unref (self->child_stderr_source); out: g_free (cmd); }
/** * gst_video_convert_sample_async: * @sample: a #GstSample * @to_caps: the #GstCaps to convert to * @timeout: the maximum amount of time allowed for the processing. * @callback: %GstVideoConvertSampleCallback that will be called after conversion. * @user_data: extra data that will be passed to the @callback * @destroy_notify: %GDestroyNotify to be called after @user_data is not needed anymore * * Converts a raw video buffer into the specified output caps. * * The output caps can be any raw video formats or any image formats (jpeg, png, ...). * * The width, height and pixel-aspect-ratio can also be specified in the output caps. * * @callback will be called after conversion, when an error occured or if conversion didn't * finish after @timeout. @callback will always be called from the thread default * %GMainContext, see g_main_context_get_thread_default(). If GLib before 2.22 is used, * this will always be the global default main context. * * @destroy_notify will be called after the callback was called and @user_data is not needed * anymore. */ void gst_video_convert_sample_async (GstSample * sample, const GstCaps * to_caps, GstClockTime timeout, GstVideoConvertSampleCallback callback, gpointer user_data, GDestroyNotify destroy_notify) { GMainContext *context = NULL; GError *error = NULL; GstBus *bus; GstBuffer *buf; GstCaps *from_caps, *to_caps_copy = NULL; GstElement *pipeline, *src, *sink; guint i, n; GSource *source; GstVideoConvertSampleContext *ctx; g_return_if_fail (sample != NULL); buf = gst_sample_get_buffer (sample); g_return_if_fail (buf != NULL); g_return_if_fail (to_caps != NULL); from_caps = gst_sample_get_caps (sample); g_return_if_fail (from_caps != NULL); g_return_if_fail (callback != NULL); context = g_main_context_get_thread_default (); if (!context) context = g_main_context_default (); to_caps_copy = gst_caps_new_empty (); n = gst_caps_get_size (to_caps); for (i = 0; i < n; i++) { GstStructure *s = gst_caps_get_structure (to_caps, i); s = gst_structure_copy (s); gst_structure_remove_field (s, "framerate"); gst_caps_append_structure (to_caps_copy, s); } pipeline = build_convert_frame_pipeline (&src, &sink, from_caps, gst_buffer_get_video_crop_meta (buf), to_caps_copy, &error); if (!pipeline) goto no_pipeline; bus = gst_element_get_bus (pipeline); ctx = g_slice_new0 (GstVideoConvertSampleContext); g_mutex_init (&ctx->mutex); //ctx->buffer = gst_buffer_ref (buf); ctx->sample = gst_sample_ref (sample); ctx->callback = callback; ctx->user_data = user_data; ctx->destroy_notify = destroy_notify; ctx->context = g_main_context_ref (context); ctx->finished = FALSE; ctx->pipeline = pipeline; if (timeout != GST_CLOCK_TIME_NONE) { ctx->timeout_source = g_timeout_source_new (timeout / GST_MSECOND); g_source_set_callback (ctx->timeout_source, (GSourceFunc) convert_frame_timeout_callback, ctx, NULL); g_source_attach (ctx->timeout_source, context); } g_signal_connect (src, "need-data", G_CALLBACK (convert_frame_need_data_callback), ctx); g_signal_connect (sink, "new-preroll", G_CALLBACK (convert_frame_new_preroll_callback), ctx); source = gst_bus_create_watch (bus); g_source_set_callback (source, (GSourceFunc) convert_frame_bus_callback, ctx, NULL); g_source_attach (source, context); g_source_unref (source); gst_element_set_state (pipeline, GST_STATE_PLAYING); gst_object_unref (bus); gst_caps_unref (to_caps_copy); return; /* ERRORS */ no_pipeline: { GstVideoConvertSampleCallbackContext *ctx; GSource *source; gst_caps_unref (to_caps_copy); ctx = g_slice_new0 (GstVideoConvertSampleCallbackContext); ctx->callback = callback; ctx->user_data = user_data; ctx->destroy_notify = destroy_notify; ctx->sample = NULL; ctx->error = error; source = g_timeout_source_new (0); g_source_set_callback (source, (GSourceFunc) convert_frame_dispatch_callback, ctx, (GDestroyNotify) gst_video_convert_frame_callback_context_free); g_source_attach (source, context); g_source_unref (source); } }
/* Main method for the native code. This is executed on its own thread. */ static void *app_function (void *userdata) { JavaVMAttachArgs args; GstBus *bus; CustomData *data = (CustomData *)userdata; GSource *timeout_source; GSource *bus_source; GError *error = NULL; guint flags; GST_DEBUG ("Creating pipeline in CustomData at %p", data); /* Create our own GLib Main Context and make it the default one */ data->context = g_main_context_new (); g_main_context_push_thread_default(data->context); /* Build pipeline */ data->pipeline = gst_parse_launch("playbin2", &error); if (error) { gchar *message = g_strdup_printf("Unable to build pipeline: %s", error->message); g_clear_error (&error); set_ui_message(message, data); g_free (message); return NULL; } /* Disable subtitles */ g_object_get (data->pipeline, "flags", &flags, NULL); flags &= ~GST_PLAY_FLAG_TEXT; g_object_set (data->pipeline, "flags", flags, NULL); /* Set the pipeline to READY, so it can already accept a window handle, if we have one */ data->target_state = GST_STATE_READY; gst_element_set_state(data->pipeline, GST_STATE_READY); /* Instruct the bus to emit signals for each received message, and connect to the interesting signals */ bus = gst_element_get_bus (data->pipeline); bus_source = gst_bus_create_watch (bus); g_source_set_callback (bus_source, (GSourceFunc) gst_bus_async_signal_func, NULL, NULL); g_source_attach (bus_source, data->context); g_source_unref (bus_source); g_signal_connect (G_OBJECT (bus), "message::error", (GCallback)error_cb, data); g_signal_connect (G_OBJECT (bus), "message::eos", (GCallback)eos_cb, data); g_signal_connect (G_OBJECT (bus), "message::state-changed", (GCallback)state_changed_cb, data); g_signal_connect (G_OBJECT (bus), "message::duration", (GCallback)duration_cb, data); g_signal_connect (G_OBJECT (bus), "message::buffering", (GCallback)buffering_cb, data); g_signal_connect (G_OBJECT (bus), "message::clock-lost", (GCallback)clock_lost_cb, data); gst_object_unref (bus); /* Register a function that GLib will call 4 times per second */ timeout_source = g_timeout_source_new (250); g_source_set_callback (timeout_source, (GSourceFunc)refresh_ui, data, NULL); g_source_attach (timeout_source, data->context); g_source_unref (timeout_source); /* Create a GLib Main Loop and set it to run */ GST_DEBUG ("Entering main loop... (CustomData:%p)", data); data->main_loop = g_main_loop_new (data->context, FALSE); check_initialization_complete (data); g_main_loop_run (data->main_loop); GST_DEBUG ("Exited main loop"); g_main_loop_unref (data->main_loop); data->main_loop = NULL; /* Free resources */ g_main_context_pop_thread_default(data->context); g_main_context_unref (data->context); data->target_state = GST_STATE_NULL; gst_element_set_state (data->pipeline, GST_STATE_NULL); gst_object_unref (data->pipeline); return NULL; }
static void _channel_accepted (TpChannel *channel, const GValue *addressv, const GError *in_error, gpointer user_data, GObject *obj) { TpStreamTubeChannel *self = (TpStreamTubeChannel *) obj; GSocketAddress *remote_address; GError *error = NULL; if (in_error != NULL) { DEBUG ("Failed to Accept Stream Tube: %s", in_error->message); operation_failed (self, in_error); return; } tp_cli_channel_type_stream_tube_connect_to_new_local_connection ( TP_CHANNEL (self), new_local_connection_cb, NULL, NULL, G_OBJECT (self), &error); if (error != NULL) { DEBUG ("Failed to connect to NewLocalConnection signal"); operation_failed (self, error); g_error_free (error); return; } remote_address = tp_g_socket_address_from_variant (self->priv->socket_type, addressv, &error); if (error != NULL) { DEBUG ("Failed to convert address: %s", error->message); operation_failed (self, error); g_error_free (error); return; } /* Connect to CM */ g_socket_set_blocking (self->priv->client_socket, FALSE); g_socket_connect (self->priv->client_socket, remote_address, NULL, &error); if (error == NULL) { /* Socket is connected */ client_socket_connected (self); goto out; } else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PENDING)) { /* We have to wait that the socket is connected */ GSource *source; source = g_socket_create_source (self->priv->client_socket, G_IO_OUT, NULL); g_source_attach (source, g_main_context_get_thread_default ()); g_source_set_callback (source, (GSourceFunc) client_socket_cb, self, NULL); g_error_free (error); g_source_unref (source); } else { DEBUG ("Failed to connect to CM: %s", error->message); operation_failed (self, error); g_error_free (error); } out: g_object_unref (remote_address); }