void gst_droidcamsrc_dev_close (GstDroidCamSrcDev * dev) { GST_DEBUG ("dev close"); g_rec_mutex_lock (dev->lock); if (dev->cam) { droid_media_camera_disconnect (dev->cam); dev->cam = NULL; dev->queue = NULL; } g_rec_mutex_unlock (dev->lock); }
static gboolean on_timer_source_ready (GObject *stream, GoaAlarm *self) { gint64 number_of_fires; gssize bytes_read; gboolean run_again = FALSE; GError *error = NULL; g_return_val_if_fail (GOA_IS_ALARM (self), FALSE); g_rec_mutex_lock (&self->priv->lock); if (self->priv->type != GOA_ALARM_TYPE_TIMER) { g_warning ("GoaAlarm: timer source ready callback called " "when timer source isn't supposed to be used. " "Current timer type is %u", self->priv->type); goto out; } bytes_read = g_pollable_input_stream_read_nonblocking (G_POLLABLE_INPUT_STREAM (stream), &number_of_fires, sizeof (gint64), NULL, &error); if (bytes_read < 0) { g_warning ("GoaAlarm: failed to read from timer fd: %s\n", error->message); g_error_free (error); goto out; } if (bytes_read == sizeof (gint64)) { if (number_of_fires < 0 || number_of_fires > 1) { g_warning ("GoaAlarm: expected timerfd to report firing once," "but it reported firing %ld times\n", (long) number_of_fires); } } fire_or_rearm_alarm (self); run_again = TRUE; out: g_rec_mutex_unlock (&self->priv->lock); return run_again; }
/** * g_static_rec_mutex_unlock_full: * @mutex: a #GStaticRecMutex to completely unlock. * @Returns: number of times @mutex has been locked by the current * thread. * * Completely unlocks @mutex. If another thread is blocked in a * g_static_rec_mutex_lock() call for @mutex, it will be woken and can * lock @mutex itself. This function returns the number of times that * @mutex has been locked by the current thread. To restore the state * before the call to g_static_rec_mutex_unlock_full() you can call * g_static_rec_mutex_lock_full() with the depth returned by this * function. * * Deprecated: 2.32: Use g_rec_mutex_unlock() */ guint g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex) { GRecMutex *rm; gint depth; rm = g_static_rec_mutex_get_rec_mutex_impl (mutex); depth = mutex->depth; while (mutex->depth) { mutex->depth--; g_rec_mutex_unlock (rm); } return depth; }
void tracker_locale_set (TrackerLocaleID id, const gchar *value) { g_rec_mutex_lock (&locales_mutex); if (current_locales[id]) { g_debug ("Locale '%s' was changed from '%s' to '%s'", locale_names[id], current_locales[id], value); g_free (current_locales[id]); } else { g_debug ("Locale '%s' was set to '%s'", locale_names[id], value); } /* Store the new one */ current_locales[id] = g_strdup (value); /* And also set the new one in the corresponding envvar */ switch (id) { case TRACKER_LOCALE_LANGUAGE: g_setenv ("LANG", value, TRUE); break; case TRACKER_LOCALE_TIME: setlocale (LC_TIME, value); break; case TRACKER_LOCALE_COLLATE: setlocale (LC_COLLATE, value); break; case TRACKER_LOCALE_NUMERIC: setlocale (LC_NUMERIC, value); break; case TRACKER_LOCALE_MONETARY: setlocale (LC_MONETARY, value); break; case TRACKER_LOCALE_LAST: /* Make compiler happy */ g_warn_if_reached (); break; } g_rec_mutex_unlock (&locales_mutex); }
gchar * tracker_locale_get (TrackerLocaleID id) { gchar *locale; g_return_val_if_fail (initialized, NULL); g_rec_mutex_lock (&locales_mutex); /* Always return a duplicated string, as the locale may change at any * moment */ locale = g_strdup (current_locales[id]); g_rec_mutex_unlock (&locales_mutex); return locale; }
/** * camel_binding_bind_property: * @source: (type GObject.Object): the source #GObject * @source_property: the property on @source to bind * @target: (type GObject.Object): the target #GObject * @target_property: the property on @target to bind * @flags: flags to pass to #GBinding * * Thread safe variant of g_object_bind_property(). See its documentation * for more information on arguments and return value. * * Returns: (transfer none): * * Since: 3.16 **/ GBinding * camel_binding_bind_property (gpointer source, const gchar *source_property, gpointer target, const gchar *target_property, GBindingFlags flags) { GBinding *binding; g_rec_mutex_lock (&camel_binding_lock); binding = g_object_bind_property (source, source_property, target, target_property, flags); g_rec_mutex_unlock (&camel_binding_lock); return binding; }
gchar * tracker_locale_get (TrackerLocaleID id) { const gchar *env_locale = NULL; gchar *locale; g_rec_mutex_lock (&locales_mutex); env_locale = tracker_locale_get_unlocked (id); /* Always return a duplicated string, as the locale may change at any * moment */ locale = g_strdup (env_locale); g_rec_mutex_unlock (&locales_mutex); return locale; }
static void gst_droidcamsrc_dev_release_recording_frame (void *data, GstDroidCamSrcDevVideoData * video_data) { GstDroidCamSrcDev *dev; GST_DEBUG ("dev release recording frame %p", data); dev = video_data->dev; g_rec_mutex_lock (dev->lock); --dev->vid->queued_frames; droid_media_camera_release_recording_frame (dev->cam, video_data->data); g_slice_free (GstDroidCamSrcDevVideoData, video_data); g_rec_mutex_unlock (dev->lock); }
static gboolean on_timeout_source_ready (GoaAlarm *self) { g_return_val_if_fail (GOA_IS_ALARM (self), FALSE); g_rec_mutex_lock (&self->priv->lock); if (self->priv->type == GOA_ALARM_TYPE_UNSCHEDULED) goto out; fire_or_rearm_alarm (self); schedule_wakeups_with_timeout_source (self); out: g_rec_mutex_unlock (&self->priv->lock); return FALSE; }
static void gst_droidcamsrc_dev_shutter_callback (void *user) { GstDroidCamSrcDev *dev = (GstDroidCamSrcDev *) user; GstDroidCamSrc *src = GST_DROIDCAMSRC (GST_PAD_PARENT (dev->imgsrc->pad)); GST_DEBUG_OBJECT (src, "dev shutter callback"); g_rec_mutex_lock (dev->lock); if (!dev->img->image_start_sent) { gst_droidcamsrc_post_message (src, gst_structure_new_empty (GST_DROIDCAMSRC_CAPTURE_START)); dev->img->image_start_sent = TRUE; } g_rec_mutex_unlock (dev->lock); }
static void goa_alarm_set_time (GoaAlarm *self, GDateTime *time) { g_rec_mutex_lock (&self->priv->lock); g_date_time_ref (time); self->priv->time = time; if (self->priv->context == NULL) self->priv->context = g_main_context_ref (g_main_context_default ()); schedule_wakeups (self); /* Wake up right away, in case it's already expired leaving the gate */ schedule_immediate_wakeup (self); g_rec_mutex_unlock (&self->priv->lock); g_object_notify (G_OBJECT (self), "time"); }
/** * gda_worker_wait_job: (skip) * @worker: a #GdaWorker object * @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 * @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 (blocks) until @func has been executed. * * Note: it's up to the caller to free the result, the #GdaWorker object will not do it (ownership of the result is * transfered to the caller). * * Returns: (transfer full): the result of @func's execution * * Since: 6.0 */ gpointer gda_worker_wait_job (GdaWorker *worker, GdaWorkerFunc func, gpointer data, GDestroyNotify data_destroy_func, GError **error) { g_return_val_if_fail (worker, NULL); g_return_val_if_fail (func, NULL); if (gda_worker_thread_is_worker (worker)) { /* we are called from within the worker thread => call the function directly */ gpointer retval; retval = func (data, error); if (data_destroy_func) data_destroy_func (data); return retval; } guint jid; /* prepare ITSignaler to be notified */ ITSignaler *its; its = itsignaler_new (); /* 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, NULL, error); g_rec_mutex_unlock (& worker->rmutex); if (jid == 0) { /* an error occurred */ itsignaler_unref (its); return NULL; } WorkerJob *job; job = itsignaler_pop_notification (its, -1); g_assert (job); itsignaler_unref (its); gpointer result; g_assert (gda_worker_fetch_job_result (worker, jid, &result, error)); return result; }
/** * g_module_symbol: * @module: a #GModule * @symbol_name: the name of the symbol to find * @symbol: (out): returns the pointer to the symbol value * * Gets a symbol pointer from a module, such as one exported * by #G_MODULE_EXPORT. Note that a valid symbol can be %NULL. * * Returns: %TRUE on success */ gboolean g_module_symbol (GModule *module, const gchar *symbol_name, gpointer *symbol) { const gchar *module_error; if (symbol) *symbol = NULL; SUPPORT_OR_RETURN (FALSE); g_return_val_if_fail (module != NULL, FALSE); g_return_val_if_fail (symbol_name != NULL, FALSE); g_return_val_if_fail (symbol != NULL, FALSE); g_rec_mutex_lock (&g_module_global_lock); #ifdef G_MODULE_NEED_USCORE { gchar *name; name = g_strconcat ("_", symbol_name, NULL); *symbol = _g_module_symbol (module->handle, name); g_free (name); } #else /* !G_MODULE_NEED_USCORE */ *symbol = _g_module_symbol (module->handle, symbol_name); #endif /* !G_MODULE_NEED_USCORE */ module_error = g_module_error (); if (module_error) { gchar *error; error = g_strconcat ("'", symbol_name, "': ", module_error, NULL); g_module_set_error (error); g_free (error); *symbol = NULL; } g_rec_mutex_unlock (&g_module_global_lock); return !module_error; }
void tracker_locale_sanity_check (void) { guint i; g_rec_mutex_lock (&locales_mutex); for (i = 0; i < TRACKER_LOCALE_LAST; i++) { const gchar *env_locale = NULL; env_locale = tracker_locale_get_unlocked (i); if (!env_locale) { g_warning ("Locale '%s' is not set, defaulting to C locale", locale_names[i]); } } g_rec_mutex_unlock (&locales_mutex); }
/** * g_static_rec_mutex_unlock_full: * @mutex: a #GStaticRecMutex to completely unlock. * * Completely unlocks @mutex. If another thread is blocked in a * g_static_rec_mutex_lock() call for @mutex, it will be woken and can * lock @mutex itself. This function returns the number of times that * @mutex has been locked by the current thread. To restore the state * before the call to g_static_rec_mutex_unlock_full() you can call * g_static_rec_mutex_lock_full() with the depth returned by this * function. * * Returns: number of times @mutex has been locked by the current * thread. * * Deprecated: 2.32: Use g_rec_mutex_unlock() */ guint g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex) { GRecMutex *rm; gint depth; gint i; rm = g_static_rec_mutex_get_rec_mutex_impl (mutex); /* all access to mutex->depth done while still holding the lock */ depth = mutex->depth; i = mutex->depth; mutex->depth = 0; while (i--) g_rec_mutex_unlock (rm); return depth; }
/* * @stmt may be %NULL */ static void gda_stmt_reset_cb (GdaStatement *stmt, GdaPStmt *pstmt) { g_rec_mutex_lock (& pstmt->priv->mutex); if (stmt) g_signal_handlers_disconnect_by_func (G_OBJECT (stmt), G_CALLBACK (gda_stmt_reset_cb), pstmt); else { stmt = g_weak_ref_get (& pstmt->priv->gda_stmt_ref); if (stmt) { g_signal_handlers_disconnect_by_func (G_OBJECT (stmt), G_CALLBACK (gda_stmt_reset_cb), pstmt); g_object_unref (stmt); } } g_weak_ref_clear (& pstmt->priv->gda_stmt_ref); g_weak_ref_init (& pstmt->priv->gda_stmt_ref, NULL); g_rec_mutex_unlock (& pstmt->priv->mutex); }
gboolean gst_droidcamsrc_dev_restart (GstDroidCamSrcDev * dev) { gboolean ret = FALSE; g_rec_mutex_lock (dev->lock); GST_DEBUG ("dev restart"); if (dev->running) { gst_droidcamsrc_dev_stop (dev); ret = gst_droidcamsrc_dev_start (dev, TRUE); } else { ret = TRUE; } g_rec_mutex_unlock (dev->lock); return ret; }
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); } }
/** * camel_binding_bind_property_with_closures: (rename-to camel_binding_bind_property_full) * @source: (type GObject.Object): the source #GObject * @source_property: the property on @source to bind * @target: (type GObject.Object): the target #GObject * @target_property: the property on @target to bind * @flags: flags to pass to #GBinding * @transform_to: a #GClosure wrapping the transformation function * from the @source to the @target, or %NULL to use the default * @transform_from: a #GClosure wrapping the transformation function * from the @target to the @source, or %NULL to use the default * * Thread safe variant of g_object_bind_property_with_closures(). See its * documentation for more information on arguments and return value. * * Return value: (transfer none): the #GBinding instance representing the * binding between the two #GObject instances. The binding is released * whenever the #GBinding reference count reaches zero. * * Since: 3.16 **/ GBinding * camel_binding_bind_property_with_closures (gpointer source, const gchar *source_property, gpointer target, const gchar *target_property, GBindingFlags flags, GClosure *transform_to, GClosure *transform_from) { GBinding *binding; g_rec_mutex_lock (&camel_binding_lock); binding = g_object_bind_property_with_closures (source, source_property, target, target_property, flags, transform_to, transform_from); g_rec_mutex_unlock (&camel_binding_lock); return binding; }
/** * g_volume_monitor_get: * * Gets the volume monitor used by gio. * * Returns: (transfer full): a reference to the #GVolumeMonitor used by gio. Call * g_object_unref() when done with it. **/ GVolumeMonitor * g_volume_monitor_get (void) { GVolumeMonitor *vm; g_rec_mutex_lock (&the_volume_monitor_mutex); if (the_volume_monitor) vm = G_VOLUME_MONITOR (g_object_ref (the_volume_monitor)); else { the_volume_monitor = g_union_volume_monitor_new (); populate_union_monitor (the_volume_monitor); vm = G_VOLUME_MONITOR (the_volume_monitor); } g_rec_mutex_unlock (&the_volume_monitor_mutex); return vm; }
gboolean gst_droidcamsrc_dev_set_params (GstDroidCamSrcDev * dev) { bool err; gboolean ret = FALSE; gchar *params; g_rec_mutex_lock (dev->lock); if (!dev->cam) { GST_ERROR ("camera device is not open"); goto out; } if (!dev->params) { GST_ERROR ("camera device is not initialized"); goto out; } if (!gst_droidcamsrc_params_is_dirty (dev->params)) { GST_DEBUG ("no need to reset params"); ret = TRUE; goto out; } params = gst_droidcamsrc_params_to_string (dev->params); GST_LOG ("setting parameters %s", params); err = droid_media_camera_set_parameters (dev->cam, params); g_free (params); if (!err) { GST_ERROR ("error setting parameters"); goto out; } ret = TRUE; out: g_rec_mutex_unlock (dev->lock); return ret; }
gboolean gst_droidcamsrc_dev_start_video_recording (GstDroidCamSrcDev * dev) { GstDroidCamSrc *src = GST_DROIDCAMSRC (GST_PAD_PARENT (dev->imgsrc->pad)); gboolean ret = FALSE; GST_DEBUG ("dev start video recording"); gst_buffer_pool_set_flushing (dev->pool, TRUE); g_mutex_lock (&dev->vidsrc->lock); dev->vidsrc->pushed_buffers = 0; g_mutex_unlock (&dev->vidsrc->lock); g_rec_mutex_lock (dev->lock); if (dev->use_raw_data) { GST_ELEMENT_ERROR (src, STREAM, FORMAT, ("Cannot record video in raw mode"), (NULL)); goto out; } dev->vid->running = TRUE; dev->vid->eos_sent = FALSE; dev->vid->video_frames = 0; dev->vid->queued_frames = 0; if (!droid_media_camera_start_recording (dev->cam)) { GST_ELEMENT_ERROR (src, LIBRARY, FAILED, ("error starting video recording"), (NULL)); goto out; } ret = TRUE; out: g_rec_mutex_unlock (dev->lock); gst_buffer_pool_set_flushing (dev->pool, FALSE); return ret; }
static gint accept_add_any (ACCEPT_POOL ap, int srv, GError **err) { gint rc = 0; if (!ap || srv<0) { GSETERROR (err, "Invalid parameter"); return 0; } g_rec_mutex_lock (&(ap->mut)); /*allocates an array if it is necessary*/ if (!ap->srv) { GSETERROR(err, "AcceptPool not initialized (should not happen)"); goto exitLabel; } /*make the arrays grows if it is too small*/ if (ap->size <= ap->count) { gint *newSrv, newSize; newSize = ap->size + 2; newSrv = g_try_realloc (ap->srv, sizeof(gint) * newSize); if (!newSrv) { GSETERROR(err, "Memory allocation error (%s)", strerror(errno)); goto exitLabel; } memset (newSrv+ap->size, 0x00, sizeof(gint) * 2); ap->size = newSize; ap->srv = newSrv; } ap->srv [ap->count++] = srv; rc = 1; exitLabel: g_rec_mutex_unlock (&(ap->mut)); return rc; }
static void g_union_volume_monitor_dispose (GObject *object) { GUnionVolumeMonitor *monitor; GVolumeMonitor *child_monitor; GList *l; monitor = G_UNION_VOLUME_MONITOR (object); g_rec_mutex_lock (&the_volume_monitor_mutex); the_volume_monitor = NULL; for (l = monitor->monitors; l != NULL; l = l->next) { child_monitor = l->data; g_object_run_dispose (G_OBJECT (child_monitor)); } g_rec_mutex_unlock (&the_volume_monitor_mutex); G_OBJECT_CLASS (g_union_volume_monitor_parent_class)->dispose (object); }
/** * camel_binding_bind_property_full: * @source: (type GObject.Object): the source #GObject * @source_property: the property on @source to bind * @target: (type GObject.Object): the target #GObject * @target_property: the property on @target to bind * @flags: flags to pass to #GBinding * @transform_to: (scope notified) (allow-none): the transformation function * from the @source to the @target, or %NULL to use the default * @transform_from: (scope notified) (allow-none): the transformation function * from the @target to the @source, or %NULL to use the default * @user_data: custom data to be passed to the transformation functions, * or %NULL * @notify: function to be called when disposing the binding, to free the * resources used by the transformation functions * * Thread safe variant of g_object_bind_property_full(). See its documentation * for more information on arguments and return value. * * Return value: (transfer none): the #GBinding instance representing the * binding between the two #GObject instances. The binding is released * whenever the #GBinding reference count reaches zero. * * Since: 3.16 **/ GBinding * camel_binding_bind_property_full (gpointer source, const gchar *source_property, gpointer target, const gchar *target_property, GBindingFlags flags, GBindingTransformFunc transform_to, GBindingTransformFunc transform_from, gpointer user_data, GDestroyNotify notify) { GBinding *binding; g_rec_mutex_lock (&camel_binding_lock); binding = g_object_bind_property_full (source, source_property, target, target_property, flags, transform_to, transform_from, user_data, notify); g_rec_mutex_unlock (&camel_binding_lock); return binding; }
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 gst_droidcamsrc_dev_stop (GstDroidCamSrcDev * dev) { g_rec_mutex_lock (dev->lock); GST_DEBUG ("dev stop"); if (dev->running) { GST_DEBUG ("stopping preview"); gst_buffer_pool_set_active (dev->pool, FALSE); droid_media_camera_stop_preview (dev->cam); dev->running = FALSE; GST_DEBUG ("stopped preview"); } /* Now we need to empty the queue */ g_mutex_lock (&dev->vfsrc->lock); g_queue_foreach (dev->vfsrc->queue, (GFunc) gst_buffer_unref, NULL); g_queue_clear (dev->vfsrc->queue); g_mutex_unlock (&dev->vfsrc->lock); g_rec_mutex_unlock (dev->lock); }
/* * @stmt may be %NULL */ static void gda_stmt_reset_cb (GdaStatement *stmt, GdaPStmt *pstmt) { GdaPStmtPrivate *priv = gda_pstmt_get_instance_private (pstmt); g_rec_mutex_lock (& priv->mutex); if (stmt) { g_object_ref (stmt); g_signal_handlers_disconnect_by_func (G_OBJECT (stmt), G_CALLBACK (gda_stmt_reset_cb), pstmt); g_object_unref (stmt); } else { GdaStatement *stm = g_weak_ref_get (& priv->gda_stmt_ref); if (stm) { g_signal_handlers_disconnect_by_func (G_OBJECT (stm), G_CALLBACK (gda_stmt_reset_cb), pstmt); g_object_unref (stm); } } g_weak_ref_set (& priv->gda_stmt_ref, NULL); g_rec_mutex_unlock (& priv->mutex); }
/** * gda_worker_forget_job: (skip) * @worker: a #GdaWorker object * @job_id: the ID of the job, as returned by gda_worker_submit_job() * * Forget all about the job with ID @job_id. As opposed to gda_worker_cancel_job(), this function can be used to tell * @worker that whatever happens to the specific job, you are not interrested anymore (i.e. that @worker can * do whatever is possible to simple discard everything related to that job). * * Since: 6.0 */ void gda_worker_forget_job (GdaWorker *worker, guint job_id) { g_return_if_fail (worker); if (!worker->jobs_hash) { g_warning ("GdaWorker has been destroyed\n"); return; } g_rec_mutex_lock (& worker->rmutex); WorkerJob *job; job = g_hash_table_lookup (worker->jobs_hash, &job_id); if (job) { if (job->status & JOB_PROCESSED) /* only case where we can remove the job because the worker thread won't use it */ g_hash_table_remove (worker->jobs_hash, & job->id); else /* the job will be 'cleared' by the worker thread */ job->status |= JOB_CANCELLED; } g_rec_mutex_unlock (&worker->rmutex); }
/* executed in sub thread */ static void worker_got_chunk_cb (SoupMessage *msg, SoupBuffer *chunk, ThreadData *thdata) { xmlDocPtr doc; gchar *data, *ptr; data = g_strndup (chunk->data, chunk->length); soup_message_body_set_accumulate (msg->response_body, FALSE); #ifdef DEBUG_WEB_PROV if (*data) g_print (">>>> WORKER\n%s\n<<<< WORKER\n", data); #endif if (!thdata->cdata->session_id) { ptr = strstr (data, "</reply>"); if (ptr) { gchar status; guint counter_id; ptr += 8; *ptr = 0; doc = decode_buffer_response (thdata->cnc, thdata->cdata, chunk, &status, &counter_id); if (!doc || (status != 'O')) { /* this cannot happen at the moment */ g_assert_not_reached (); if (doc) xmlFreeDoc (doc); } else { g_rec_mutex_lock (& (thdata->cdata->mutex)); g_assert (thdata->cdata->worker_counter == counter_id); g_rec_mutex_unlock (& (thdata->cdata->mutex)); xmlFreeDoc (doc); } } } g_free (data); }