static gboolean maildir_check_mail_timeout( gpointer data ) { XfceMailwatchMaildirMailbox *maildir = XFCE_MAILWATCH_MAILDIR_MAILBOX( data ); GThread *th; if( g_atomic_pointer_get( &maildir->thread ) ) { xfce_mailwatch_log_message( maildir->mailwatch, XFCE_MAILWATCH_MAILBOX( maildir ), XFCE_MAILWATCH_LOG_WARNING, _( "Previous thread hasn't exited yet, not checking mail this time." ) ); return TRUE; } th = g_thread_create( maildir_main_thread, maildir, FALSE, NULL ); g_atomic_pointer_set( &maildir->thread, th ); return TRUE; }
/** * gst_mini_object_steal: * @olddata: (inout) (transfer full): pointer to a pointer to a mini-object to * be stolen * * Replace the current #GstMiniObject pointer to by @olddata with NULL and * return the old value. * * Returns: the #GstMiniObject at @oldata */ GstMiniObject * gst_mini_object_steal (GstMiniObject ** olddata) { GstMiniObject *olddata_val; g_return_val_if_fail (olddata != NULL, NULL); GST_CAT_TRACE (GST_CAT_REFCOUNTING, "steal %p (%d)", *olddata, *olddata ? (*olddata)->refcount : 0); do { olddata_val = g_atomic_pointer_get ((gpointer *) olddata); if (olddata_val == NULL) break; } while (G_UNLIKELY (!g_atomic_pointer_compare_and_exchange ((gpointer *) olddata, olddata_val, NULL))); return olddata_val; }
/** * g_static_resource_fini: * @static_resource: pointer to a static #GStaticResource * * Finalized a GResource initialized by g_static_resource_init(). * * This is normally used by code generated by * [glib-compile-resources][glib-compile-resources] * and is not typically used by other code. * * Since: 2.32 **/ void g_static_resource_fini (GStaticResource *static_resource) { GResource *resource; g_rw_lock_writer_lock (&resources_lock); register_lazy_static_resources_unlocked (); resource = g_atomic_pointer_get (&static_resource->resource); if (resource) { g_atomic_pointer_set (&static_resource->resource, NULL); g_resources_unregister_unlocked (resource); g_resource_unref (resource); } g_rw_lock_writer_unlock (&resources_lock); }
/** * ags_soundcard_thread_find_soundcard: * @soundcard_thread: the #AgsSoundcardThread * @soundcard: the #AgsSoundcard to find * * Returns: the matching #AgsSoundcardThread, if not * found %NULL. * * Since: 2.0.0 */ AgsSoundcardThread* ags_soundcard_thread_find_soundcard(AgsSoundcardThread *soundcard_thread, GObject *soundcard) { if(soundcard_thread == NULL || !AGS_IS_SOUNDCARD_THREAD(soundcard_thread)){ return(NULL); } while(soundcard_thread != NULL){ if(AGS_IS_SOUNDCARD_THREAD(soundcard_thread) && soundcard_thread->soundcard == soundcard){ return(soundcard_thread); } soundcard_thread = g_atomic_pointer_get(&(((AgsThread *) soundcard_thread)->next)); } return(NULL); }
void lgi_state_enter (gpointer state_lock) { LgiStateMutex *mutex = state_lock; GRecMutex *wait_on; /* There is a complication with lock switching. During the wait for the lock, someone could call core.registerlock() and thus change the lock protecting the state. Accomodate for this situation. */ for (;;) { wait_on = g_atomic_pointer_get (&mutex->mutex); g_rec_mutex_lock (wait_on); if (wait_on == mutex->mutex) break; /* The lock is changed, unlock this one and wait again. */ g_rec_mutex_unlock (wait_on); } }
/** * g_once_init_enter: * @location: location of a static initializable variable containing 0 * * Function to be called when starting a critical initialization * section. The argument @location must point to a static * 0-initialized variable that will be set to a value other than 0 at * the end of the initialization section. In combination with * g_once_init_leave() and the unique address @value_location, it can * be ensured that an initialization section will be executed only once * during a program's life time, and that concurrent threads are * blocked until initialization completed. To be used in constructs * like this: * * |[ * static gsize initialization_value = 0; * * if (g_once_init_enter (&initialization_value)) * { * gsize setup_value = 42; /** initialization code here **/ * * g_once_init_leave (&initialization_value, setup_value); * } * * /** use initialization_value here **/ * ]| * * Returns: %TRUE if the initialization section should be entered, * %FALSE and blocks otherwise * * Since: 2.14 */ gboolean (g_once_init_enter) (volatile void *location) { volatile gsize *value_location = location; gboolean need_init = FALSE; g_mutex_lock (&g_once_mutex); if (g_atomic_pointer_get (value_location) == NULL) { if (!g_slist_find (g_once_init_list, (void*) value_location)) { need_init = TRUE; g_once_init_list = g_slist_prepend (g_once_init_list, (void*) value_location); } else do g_cond_wait (&g_once_cond, &g_once_mutex); while (g_slist_find (g_once_init_list, (void*) value_location)); } g_mutex_unlock (&g_once_mutex); return need_init; }
static gpointer _my_mem_map (MyMemory * mem, gsize maxsize, GstMapFlags flags) { gpointer res; while (TRUE) { if ((res = g_atomic_pointer_get (&mem->data)) != NULL) break; res = g_malloc (maxsize); if (g_atomic_pointer_compare_and_exchange (&mem->data, NULL, res)) break; g_free (res); } GST_DEBUG ("%p: mapped %p", mem, res); return res; }
static void gst_auto_convert_dispose (GObject * object) { GstAutoConvert *autoconvert = GST_AUTO_CONVERT (object); g_clear_object (&autoconvert->current_subelement); g_clear_object (&autoconvert->current_internal_sinkpad); g_clear_object (&autoconvert->current_internal_srcpad); for (;;) { GList *factories = g_atomic_pointer_get (&autoconvert->factories); if (g_atomic_pointer_compare_and_exchange (&autoconvert->factories, factories, NULL)) { gst_plugin_feature_list_free (factories); break; } } G_OBJECT_CLASS (gst_auto_convert_parent_class)->dispose (object); }
static int core_registerlock (lua_State *L) { void (*set_lock_functions)(GCallback, GCallback); LgiStateMutex *mutex; GRecMutex *wait_on; unsigned i; /* Get registration function. */ luaL_checktype (L, 1, LUA_TLIGHTUSERDATA); set_lock_functions = lua_touserdata (L, 1); luaL_argcheck (L, set_lock_functions != NULL, 1, "NULL function"); /* Check, whether this package was already registered. */ for (i = 0; i < G_N_ELEMENTS (package_lock_register) && package_lock_register[i] != set_lock_functions; i++) { if (package_lock_register[i] == NULL) { /* Register our package lock functions. */ package_lock_register[i] = set_lock_functions; set_lock_functions (package_lock_enter, package_lock_leave); break; } } /* Switch our statelock to actually use packagelock. */ lua_pushlightuserdata (L, &call_mutex); lua_rawget (L, LUA_REGISTRYINDEX); mutex = lua_touserdata (L, -1); wait_on = g_atomic_pointer_get (&mutex->mutex); if (wait_on != &package_mutex) { g_rec_mutex_lock (&package_mutex); g_atomic_pointer_set (&mutex->mutex, &package_mutex); g_rec_mutex_unlock (wait_on); } return 0; }
void * pop_bottom(ws_deque *q) { long int b = q->bottom; circular_array *a = q->active_array; b = b - 1; q->bottom = b; long int t = (long int) g_atomic_pointer_get(&(q->top)); long int size = b - t; long int zero = 0; if(size < zero) { q->bottom = t; return NULL; } void *value = ca_get(a, b); if(size > 0) { return value; } // this is the case for exactly one element, this is now the top so act accordingly long int new_t = t+1; gboolean cas = g_atomic_pointer_compare_and_exchange((void * volatile*)&(q->top), (void*)t, (void*)new_t); if( !cas ) { value = NULL; } q->bottom = t+1; return value; }
/** * log4g_logger_remove_all_appenders: * @self: A #Log4gLogger object. * * Remove all appenders from a logger. * * See: #Log4gAppenderAttachableInterface * * Since: 0.1 */ void log4g_logger_remove_all_appenders(Log4gLogger *self) { struct Private *priv = GET_PRIVATE(self); if (!g_atomic_pointer_get(&priv->aai)) { return; } g_mutex_lock(priv->lock); const GArray *appenders = log4g_appender_attachable_get_all_appenders(priv->aai); if (!appenders) { goto exit; } GArray *mine = g_array_sized_new(FALSE, TRUE, sizeof(Log4gAppender *), appenders->len); if (!mine) { goto exit; } for (guint i = 0; i < appenders->len; ++i) { Log4gAppender *appender = g_array_index(appenders, Log4gAppender *, i); g_object_ref(appender); g_array_append_val(mine, appender); } log4g_appender_attachable_remove_all_appenders(priv->aai); for (guint i = 0; i < mine->len; ++i) { Log4gAppender *appender = g_array_index(mine, Log4gAppender *, i); log4g_logger_repository_emit_remove_appender_signal( priv->repository, self, appender); g_object_unref(appender); } g_array_free(mine, TRUE); g_object_unref(priv->aai); priv->aai = NULL; exit: g_mutex_unlock(priv->lock); }
/** * gst_mini_object_take: * @olddata: (inout) (transfer full): pointer to a pointer to a mini-object to * be replaced * @newdata: pointer to new mini-object * * Modifies a pointer to point to a new mini-object. The modification * is done atomically. This version is similar to gst_mini_object_replace() * except that it does not increase the refcount of @newdata and thus * takes ownership of @newdata. * * Either @newdata and the value pointed to by @olddata may be NULL. * * Returns: TRUE if @newdata was different from @olddata */ gboolean gst_mini_object_take (GstMiniObject ** olddata, GstMiniObject * newdata) { GstMiniObject *olddata_val; g_return_val_if_fail (olddata != NULL, FALSE); GST_CAT_TRACE (GST_CAT_REFCOUNTING, "take %p (%d) with %p (%d)", *olddata, *olddata ? (*olddata)->refcount : 0, newdata, newdata ? newdata->refcount : 0); do { olddata_val = g_atomic_pointer_get ((gpointer *) olddata); if (G_UNLIKELY (olddata_val == newdata)) break; } while (G_UNLIKELY (!g_atomic_pointer_compare_and_exchange ((gpointer *) olddata, olddata_val, newdata))); if (olddata_val) gst_mini_object_unref (olddata_val); return olddata_val != newdata; }
static void maildir_force_update_cb( XfceMailwatchMailbox *mailbox ) { XfceMailwatchMaildirMailbox *maildir = XFCE_MAILWATCH_MAILDIR_MAILBOX( mailbox ); DBG( "-->>" ); if( !g_atomic_pointer_get( &maildir->thread ) ) { gboolean restart = FALSE; if( maildir->check_id ) { g_source_remove( maildir->check_id ); restart = TRUE; } maildir_check_mail_timeout( maildir ); if( restart ) { maildir->check_id = g_timeout_add( maildir->interval * 1000, maildir_check_mail_timeout, maildir ); } } DBG( "<<--" ); }
static void mh_free( XfceMailwatchMailbox *mailbox ) { XfceMailwatchMHMailbox *mh = XFCE_MAILWATCH_MH_MAILBOX( mailbox ); DBG( "-->>" ); mh_set_activated_cb( mailbox, FALSE ); while( g_atomic_pointer_get( &mh->thread ) ) g_thread_yield(); if ( mh->mh_profile_fn ) { g_free( mh->mh_profile_fn ); } if ( mh->mh_sequences_fn ) { g_free( mh->mh_sequences_fn ); } if ( mh->unseen_sequence ) { g_free( mh->unseen_sequence ); } g_free( mh ); }
static void mh_force_update_cb( XfceMailwatchMailbox *mailbox ) { XfceMailwatchMHMailbox *mh = XFCE_MAILWATCH_MH_MAILBOX( mailbox ); DBG( " " ); if( !g_atomic_pointer_get( &mh->thread ) ) { gboolean restart = FALSE; if( mh->check_id ) { g_source_remove( mh->check_id ); restart = TRUE; } mh_check_mail_timeout( mh ); if( restart ) { mh->check_id = g_timeout_add( mh->timeout * 1000, mh_check_mail_timeout, mh ); } } }
int main (int argc, char *argv[]) { gint i; gint atomic = -5; gpointer atomic_pointer = NULL; gpointer biggest_pointer = (gpointer)((gsize)atomic_pointer - 1); #ifdef SYMBIAN g_log_set_handler (NULL, G_LOG_FLAG_FATAL| G_LOG_FLAG_RECURSION | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG, &mrtLogHandler, NULL); g_set_print_handler(mrtPrintHandler); #endif /*SYMBIAN*/ for (i = 0; i < 15; i++) g_atomic_int_inc (&atomic); g_assert (atomic == 10); for (i = 0; i < 9; i++) g_assert (!g_atomic_int_dec_and_test (&atomic)); g_assert (g_atomic_int_dec_and_test (&atomic)); g_assert (atomic == 0); g_assert (g_atomic_int_exchange_and_add (&atomic, 5) == 0); g_assert (atomic == 5); g_assert (g_atomic_int_exchange_and_add (&atomic, -10) == 5); g_assert (atomic == -5); g_atomic_int_add (&atomic, 20); g_assert (atomic == 15); g_atomic_int_add (&atomic, -35); g_assert (atomic == -20); g_assert (atomic == g_atomic_int_get (&atomic)); g_assert (g_atomic_int_compare_and_exchange (&atomic, -20, 20)); g_assert (atomic == 20); g_assert (!g_atomic_int_compare_and_exchange (&atomic, 42, 12)); g_assert (atomic == 20); g_assert (g_atomic_int_compare_and_exchange (&atomic, 20, G_MAXINT)); g_assert (atomic == G_MAXINT); g_assert (g_atomic_int_compare_and_exchange (&atomic, G_MAXINT, G_MININT)); g_assert (atomic == G_MININT); g_assert (g_atomic_pointer_compare_and_exchange (&atomic_pointer, NULL, biggest_pointer)); g_assert (atomic_pointer == biggest_pointer); g_assert (atomic_pointer == g_atomic_pointer_get (&atomic_pointer)); g_assert (g_atomic_pointer_compare_and_exchange (&atomic_pointer, biggest_pointer, NULL)); g_assert (atomic_pointer == NULL); #ifdef SYMBIAN testResultXml("atomic-test"); #endif /* EMULATOR */ return 0; }
void* ags_thread_pool_creation_thread(void *ptr) { AgsThreadPool *thread_pool; AgsThread *thread; GList *tmplist; guint n_threads, max_threads; guint i, i_stop; thread_pool = AGS_THREAD_POOL(ptr); #ifdef AGS_DEBUG g_message("ags_thread_pool_creation_thread\0"); #endif while((AGS_THREAD_POOL_RUNNING & (g_atomic_int_get(&(thread_pool->flags)))) != 0){ #ifdef AGS_DEBUG g_message("ags_thread_pool_creation_thread@loopStart\0"); #endif pthread_mutex_lock(thread_pool->creation_mutex); g_atomic_int_or(&(thread_pool->flags), AGS_THREAD_POOL_READY); while(g_atomic_int_get(&(thread_pool->newly_pulled)) == 0){ pthread_cond_wait(thread_pool->creation_cond, thread_pool->creation_mutex); } n_threads = g_atomic_int_get(&(thread_pool->n_threads)); max_threads = g_atomic_int_get(&(thread_pool->max_threads)); i_stop = g_atomic_int_get(&(thread_pool->newly_pulled)); g_atomic_int_set(&(thread_pool->newly_pulled), 0); #ifdef AGS_DEBUG g_message("ags_thread_pool_creation_thread@loop0\0"); #endif g_atomic_int_and(&(thread_pool->flags), (~AGS_THREAD_POOL_READY)); if(n_threads < max_threads){ for(i = 0; i < i_stop && n_threads < max_threads; i++){ thread = (AgsThread *) ags_returnable_thread_new(thread_pool); tmplist = g_atomic_pointer_get(&(thread_pool->returnable_thread)); g_atomic_pointer_set(&(thread_pool->returnable_thread), g_list_prepend(tmplist, thread)); ags_thread_add_child(AGS_THREAD(thread_pool->parent), thread); ags_connectable_connect(AGS_CONNECTABLE(thread)); g_atomic_int_inc(&(thread_pool->n_threads)); n_threads++; } } pthread_mutex_unlock(thread_pool->creation_mutex); #ifdef AGS_DEBUG g_message("ags_thread_pool_creation_thread@loopEND\0"); #endif } }
/** * ev_job_scheduler_get_running_thread_job: * * Returns: (transfer none): an #EvJob */ EvJob * ev_job_scheduler_get_running_thread_job (void) { return g_atomic_pointer_get (&running_job); }
/** * g_atomic_pointer_get: * @atomic: a pointer to a #gpointer-sized value * * Gets the current value of @atomic. * * This call acts as a full compiler and hardware * memory barrier (before the get). * * Returns: the value of the pointer * * Since: 2.4 **/ gpointer (g_atomic_pointer_get) (const volatile void *atomic) { return g_atomic_pointer_get ((const volatile gpointer *) atomic); }
* being added automatically. * * We don't support shrinking arrays, as if * we then re-grow we may reuse an old pointer * value and confuse the transaction check. */ gpointer _g_atomic_array_copy (GAtomicArray *array, gsize header_size, gsize additional_element_size) { guint8 *new, *old; gsize old_size, new_size; G_LOCK (array); old = g_atomic_pointer_get (&array->data); if (old) { old_size = G_ATOMIC_ARRAY_DATA_SIZE (old); new_size = old_size + additional_element_size; /* Don't reuse if copying to same size, as this may end up reusing the same pointer for the same array thus confusing the transaction check */ new = freelist_alloc (new_size, additional_element_size != 0); memcpy (new, old, old_size); } else if (additional_element_size != 0) { new_size = header_size + additional_element_size; new = freelist_alloc (new_size, TRUE); }
void ags_test_launch(gboolean single_thread) { AgsThread *audio_loop, *polling_thread, *gui_thread, *task_thread; AgsThreadPool *thread_pool; AgsConfig *config; GList *start_queue; g_object_get(ags_application_context, "config", &config, "main-loop", &audio_loop, "task-thread", &task_thread, NULL); g_object_get(task_thread, "thread-pool", &thread_pool, NULL); polling_thread = ags_thread_find_type(audio_loop, AGS_TYPE_POLLING_THREAD); gui_thread = ags_thread_find_type(audio_loop, AGS_TYPE_GUI_THREAD); /* start engine */ pthread_mutex_lock(audio_loop->start_mutex); start_queue = NULL; start_queue = g_list_prepend(start_queue, polling_thread); start_queue = g_list_prepend(start_queue, task_thread); // start_queue = g_list_prepend(start_queue, // gui_thread); g_atomic_pointer_set(&(audio_loop->start_queue), start_queue); pthread_mutex_unlock(audio_loop->start_mutex); /* start audio loop and thread pool*/ ags_thread_start(audio_loop); ags_thread_pool_start(thread_pool); if(!single_thread){ /* wait for audio loop */ pthread_mutex_lock(audio_loop->start_mutex); if(g_atomic_int_get(&(audio_loop->start_wait)) == TRUE){ g_atomic_int_set(&(audio_loop->start_done), FALSE); while(g_atomic_int_get(&(audio_loop->start_wait)) == TRUE && g_atomic_int_get(&(audio_loop->start_done)) == FALSE){ pthread_cond_wait(audio_loop->start_cond, audio_loop->start_mutex); } } pthread_mutex_unlock(audio_loop->start_mutex); /* start gui thread */ ags_thread_start(gui_thread); /* wait for gui thread */ pthread_mutex_lock(gui_thread->start_mutex); if(g_atomic_int_get(&(gui_thread->start_done)) == FALSE){ g_atomic_int_set(&(gui_thread->start_wait), TRUE); while(g_atomic_int_get(&(gui_thread->start_done)) == FALSE){ g_atomic_int_set(&(gui_thread->start_wait), TRUE); pthread_cond_wait(gui_thread->start_cond, gui_thread->start_mutex); } } pthread_mutex_unlock(gui_thread->start_mutex); g_atomic_int_set(&(AGS_XORG_APPLICATION_CONTEXT(ags_application_context)->gui_ready), 1); /* autosave thread */ if(!g_strcmp0(ags_config_get_value(config, AGS_CONFIG_GENERIC, "autosave-thread\0"), "true\0")){ pthread_mutex_lock(audio_loop->start_mutex); start_queue = g_atomic_pointer_get(&(audio_loop->start_queue)); start_queue = g_list_prepend(start_queue, task_thread); g_atomic_pointer_set(&(audio_loop->start_queue), start_queue); pthread_mutex_unlock(audio_loop->start_mutex); } }else{ AgsSingleThread *single_thread; /* single thread */ single_thread = ags_single_thread_new((GObject *) ags_sound_provider_get_soundcard(AGS_SOUND_PROVIDER(ags_application_context))->data); /* add known threads to single_thread */ ags_thread_add_child(AGS_THREAD(single_thread), audio_loop); /* autosave thread */ if(!g_strcmp0(ags_config_get_value(config, AGS_CONFIG_GENERIC, "autosave-thread\0"), "true\0")){ pthread_mutex_lock(audio_loop->start_mutex); start_queue = g_atomic_pointer_get(&(audio_loop->start_queue)); start_queue = g_list_prepend(start_queue, task_thread); g_atomic_pointer_set(&(audio_loop->start_queue), start_queue); pthread_mutex_unlock(audio_loop->start_mutex); } /* start thread tree */ ags_thread_start((AgsThread *) single_thread); } }
inline T *atomic_get(T*& p) { return static_cast<T*>(g_atomic_pointer_get(&p)); }
/** * gst_device_provider_factory_get: * @factory: factory to instantiate * * Returns the device provider of the type defined by the given device * providerfactory. * * Returns: (transfer full) (nullable): the #GstDeviceProvider or %NULL * if the device provider couldn't be created * * Since: 1.4 */ GstDeviceProvider * gst_device_provider_factory_get (GstDeviceProviderFactory * factory) { GstDeviceProvider *device_provider; GstDeviceProviderClass *oclass; GstDeviceProviderFactory *newfactory; g_return_val_if_fail (factory != NULL, NULL); newfactory = GST_DEVICE_PROVIDER_FACTORY (gst_plugin_feature_load (GST_PLUGIN_FEATURE (factory))); if (newfactory == NULL) goto load_failed; factory = newfactory; GST_INFO ("getting device provider \"%s\"", GST_OBJECT_NAME (factory)); if (factory->type == 0) goto no_type; device_provider = g_atomic_pointer_get (&newfactory->provider); if (device_provider) return gst_object_ref (device_provider); /* create an instance of the device provider, cast so we don't assert on NULL * also set name as early as we can */ device_provider = GST_DEVICE_PROVIDER_CAST (g_object_newv (factory->type, 0, NULL)); if (G_UNLIKELY (device_provider == NULL)) goto no_device_provider; /* fill in the pointer to the factory in the device provider class. The * class will not be unreffed currently. * Be thread safe as there might be 2 threads creating the first instance of * an device provider at the same moment */ oclass = GST_DEVICE_PROVIDER_GET_CLASS (device_provider); if (!g_atomic_pointer_compare_and_exchange (&oclass->factory, NULL, factory)) gst_object_unref (factory); gst_object_ref_sink (device_provider); /* We use an atomic to make sure we don't create two in parallel */ if (!g_atomic_pointer_compare_and_exchange (&newfactory->provider, NULL, device_provider)) { gst_object_unref (device_provider); device_provider = g_atomic_pointer_get (&newfactory->provider); } GST_DEBUG ("created device provider \"%s\"", GST_OBJECT_NAME (factory)); return gst_object_ref (device_provider); /* ERRORS */ load_failed: { GST_WARNING_OBJECT (factory, "loading plugin containing feature %s returned NULL!", GST_OBJECT_NAME (factory)); return NULL; } no_type: { GST_WARNING_OBJECT (factory, "factory has no type"); gst_object_unref (factory); return NULL; } no_device_provider: { GST_WARNING_OBJECT (factory, "could not create device provider"); gst_object_unref (factory); return NULL; } }
// public error functions const char *openslide_get_error(openslide_t *osr) { return g_atomic_pointer_get(&osr->error); }
void ags_test_launch_filename(gchar *filename, gboolean single_thread) { AgsThread *audio_loop, *polling_thread, *gui_thread, *task_thread; AgsThreadPool *thread_pool; AgsConfig *config; GList *start_queue; /* get threads, thread pool and config */ g_object_get(ags_application_context, "config", &config, "main-loop", &audio_loop, "task-thread", &task_thread, NULL); g_object_get(task_thread, "thread-pool", &thread_pool, NULL); polling_thread = ags_thread_find_type(audio_loop, AGS_TYPE_POLLING_THREAD); gui_thread = ags_thread_find_type(audio_loop, AGS_TYPE_GUI_THREAD); /* open file */ if(g_strcmp0(ags_config_get_value(config, AGS_CONFIG_GENERIC, "simple-file\0"), "false\0")){ AgsSimpleFile *simple_file; AgsSimpleFileRead *simple_file_read; GError *error; simple_file = (AgsSimpleFile *) g_object_new(AGS_TYPE_SIMPLE_FILE, "application-context\0", ags_application_context, "filename\0", filename, NULL); error = NULL; ags_simple_file_open(simple_file, &error); if(error != NULL){ ags_test_show_file_error(filename, error); ags_application_context_quit(ags_application_context); } /* start engine */ pthread_mutex_lock(audio_loop->start_mutex); start_queue = NULL; start_queue = g_list_prepend(start_queue, polling_thread); start_queue = g_list_prepend(start_queue, task_thread); // start_queue = g_list_prepend(start_queue, // gui_thread); g_atomic_pointer_set(&(audio_loop->start_queue), start_queue); pthread_mutex_unlock(audio_loop->start_mutex); /* start audio loop and thread pool */ ags_thread_start(audio_loop); ags_thread_pool_start(thread_pool); if(!single_thread){ /* wait for audio loop */ pthread_mutex_lock(audio_loop->start_mutex); if(g_atomic_int_get(&(audio_loop->start_wait)) == TRUE){ g_atomic_int_set(&(audio_loop->start_done), FALSE); while(g_atomic_int_get(&(audio_loop->start_wait)) == TRUE && g_atomic_int_get(&(audio_loop->start_done)) == FALSE){ pthread_cond_wait(audio_loop->start_cond, audio_loop->start_mutex); } } pthread_mutex_unlock(audio_loop->start_mutex); /* start gui thread */ ags_thread_start(gui_thread); /* wait for gui thread */ pthread_mutex_lock(gui_thread->start_mutex); if(g_atomic_int_get(&(gui_thread->start_done)) == FALSE){ g_atomic_int_set(&(gui_thread->start_wait), TRUE); while(g_atomic_int_get(&(gui_thread->start_done)) == FALSE){ g_atomic_int_set(&(gui_thread->start_wait), TRUE); pthread_cond_wait(gui_thread->start_cond, gui_thread->start_mutex); } } pthread_mutex_unlock(gui_thread->start_mutex); /* autosave thread */ if(!g_strcmp0(ags_config_get_value(config, AGS_CONFIG_GENERIC, "autosave-thread\0"), "true\0")){ pthread_mutex_lock(audio_loop->start_mutex); start_queue = g_atomic_pointer_get(&(audio_loop->start_queue)); start_queue = g_list_prepend(start_queue, task_thread); g_atomic_pointer_set(&(audio_loop->start_queue), start_queue); pthread_mutex_unlock(audio_loop->start_mutex); } /* now start read task */ simple_file_read = ags_simple_file_read_new(simple_file); ags_task_thread_append_task((AgsTaskThread *) task_thread, (AgsTask *) simple_file_read); }else{ AgsFile *file; GError *error; file = g_object_new(AGS_TYPE_FILE, "application-context\0", ags_application_context, "filename\0", filename, NULL); error = NULL; ags_file_open(file, &error); if(error != NULL){ ags_test_show_file_error(filename, error); ags_application_context_quit(ags_application_context); } ags_file_read(file); ags_file_close(file); } } }
static void insert_candidates(struct sdp_chopper *chop, struct packet_stream *rtp, struct packet_stream *rtcp, struct sdp_ng_flags *flags, struct sdp_media *sdp_media) { GList *l; struct interface_address *ifa; unsigned int pref; struct call_media *media; struct local_interface *lif; struct ice_agent *ag; unsigned int type_pref, local_pref; enum ice_candidate_type cand_type; struct ice_candidate *cand; media = rtp->media; cand_type = ICT_HOST; if (flags->ice_force_relay) cand_type = ICT_RELAY; if (MEDIA_ISSET(media, PASSTHRU)) new_priority(sdp_media, cand_type, &type_pref, &local_pref); else { type_pref = ice_type_preference(cand_type); local_pref = -1; } ag = media->ice_agent; lif = ag ? ag->local_interface : media->interface; if (ag && AGENT_ISSET(ag, COMPLETED)) { ifa = g_atomic_pointer_get(&media->local_address); insert_candidate(chop, rtp, 1, type_pref, ifa->preference, cand_type, ifa); if (rtcp) /* rtcp-mux only possible in answer */ insert_candidate(chop, rtcp, 2, type_pref, ifa->preference, cand_type, ifa); if (flags->opmode == OP_OFFER && AGENT_ISSET(ag, CONTROLLING)) { GQueue rc; GList *l; chopper_append_c(chop, "a=remote-candidates:"); ice_remote_candidates(&rc, ag); for (l = rc.head; l; l = l->next) { if (l != rc.head) chopper_append_c(chop, " "); cand = l->data; chopper_append_printf(chop, "%lu %s %u", cand->component_id, smart_ntop_buf(&cand->endpoint.ip46), cand->endpoint.port); } chopper_append_c(chop, "\r\n"); g_queue_clear(&rc); } return; } for (l = lif->list.head; l; l = l->next) { ifa = l->data; pref = (local_pref == -1) ? ifa->preference : local_pref; insert_candidate(chop, rtp, 1, type_pref, pref, cand_type, ifa); if (rtcp) /* rtcp-mux only possible in answer */ insert_candidate(chop, rtcp, 2, type_pref, pref, cand_type, ifa); if (local_pref != -1) local_pref++; } }