int test13 (void) { g_print ("%s started, main thread is %p\n", __FUNCTION__, g_thread_self ()); GdaWorker *worker; gint nfailed = 0; worker = gda_worker_new (); GError *error = NULL; g_timeout_add (200, (GSourceFunc) test13_time_func, gda_worker_ref (worker)); g_print ("Sumbitting job for test13_func()\n"); gpointer result; if (!gda_worker_do_job (worker, NULL, 0, &result, NULL, (GdaWorkerFunc) test13_func, "1st", NULL, NULL, &error)) { g_print ("gda_worker_do_job() failed: %s\n", error && error->message ? error->message : "No detail"); g_clear_error (&error); nfailed ++; } else if (GPOINTER_TO_UINT (result) != 2) { g_print ("In %s(): expected 2 and got %u\n", __FUNCTION__, GPOINTER_TO_UINT (result)); nfailed ++; } else if (test13_sub_failed) nfailed ++; g_print ("Unref worker...\n"); gda_worker_unref (worker); g_print ("%s done\n", __FUNCTION__); return nfailed; }
/* * Reopens a connection after the server has closed it (possibly because of a timeout) */ gboolean gda_ldap_rebind (GdaLdapConnection *cnc, GError **error) { g_return_val_if_fail (GDA_IS_LDAP_CONNECTION (cnc), FALSE); gda_lockable_lock ((GdaLockable*) cnc); /* CNC LOCK */ LdapConnectionData *cdata; cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data (GDA_VIRTUAL_CONNECTION (cnc)); if (!cdata) { gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */ g_warning ("cdata != NULL failed"); return FALSE; } GdaServerProviderConnectionData *pcdata; pcdata = gda_connection_internal_get_provider_data_error ((GdaConnection*) cnc, NULL); GdaWorker *worker; worker = gda_worker_ref (gda_connection_internal_get_worker (pcdata)); GMainContext *context; context = gda_server_provider_get_real_main_context ((GdaConnection *) cnc); gpointer retval; gda_worker_do_job (worker, context, 0, &retval, NULL, (GdaWorkerFunc) worker_gda_ldap_rebind, (gpointer) cdata, NULL, NULL, error); if (context) g_main_context_unref (context); gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */ gda_worker_unref (worker); return retval ? TRUE : FALSE; }
/* * Unbinds the connection if possible (i.e. if cdata->keep_bound_count is 0) * This allows to avoid keeping the connection to the LDAP server if unused */ void gda_ldap_may_unbind (GdaLdapConnection *cnc) { gda_lockable_lock ((GdaLockable*) cnc); /* CNC LOCK */ LdapConnectionData *cdata; cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data (GDA_VIRTUAL_CONNECTION (cnc)); if (!cdata || (cdata->keep_bound_count > 0)) { gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */ return; } GdaServerProviderConnectionData *pcdata; pcdata = gda_connection_internal_get_provider_data_error ((GdaConnection*) cnc, NULL); GdaWorker *worker; worker = gda_worker_ref (gda_connection_internal_get_worker (pcdata)); GMainContext *context; context = gda_server_provider_get_real_main_context ((GdaConnection *) cnc); gpointer retval; gda_worker_do_job (worker, context, 0, &retval, NULL, (GdaWorkerFunc) worker_gda_ldap_may_unbind, (gpointer) cdata, NULL, NULL, NULL); if (context) g_main_context_unref (context); gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */ gda_worker_unref (worker); }
/** * gda_worker_new_unique: (skip) * @location: a place to store and test for existence, not %NULL * @allow_destroy: defines if the created @GdaWorker (see case 1 below) will allow its reference to drop to 0 and be destroyed * * This function creates a new #GdaWorker, or reuses the one at @location. Specifically: * <orderedlist> * <listitem><para>if *@location is %NULL, then a new #GdaWorker is created. In this case if @allow_destroy is %FALSE, then the returned * #GdaWorker's reference count is 2, thus preventing it form ever being destroyed (unless gda_worker_unref() is called somewhere else)</para></listitem> * <listitem><para>if *@location is not %NULL, the the #GdaWorker it points to is returned, its reference count increased by 1</para></listitem> * </orderedlist> * * When the returned #GdaWorker's reference count reaches 0, then it is destroyed, and *@location is set to %NULL. * * In any case, the returned value is the same as *@location. * * Returns: (transfer full): a #GdaWorker */ GdaWorker * gda_worker_new_unique (GdaWorker **location, gboolean allow_destroy) { g_return_val_if_fail (location, NULL); g_mutex_lock (&unique_worker_mutex); if (*location) gda_worker_ref (*location); else { GdaWorker *worker; worker = gda_worker_new (); if (! allow_destroy) gda_worker_ref (worker); worker->location = location; *location = worker; } g_mutex_unlock (&unique_worker_mutex); return *location; }
/** * gda_worker_fetch_job_result: (skip) * @worker: a #GdaWorker object * @job_id: the ID of the job, as returned by gda_worker_submit_job() * @out_result: (allow-none): a place to store the value returned by the execution of the requested function within the worker thread, or %NULL * @error: (allow-none): a place to store errors, or %NULL * * Fetch the value returned by execution the @job_id job. * * Warning: if an error occurred during the * execution of the requested function within the worker thread, then it will show as @error, while the return value * of this function will be %TRUE. * * Note: if there is a result, it will be stored in @out_result, and 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: %TRUE if the jobs has completed * * Since: 6.0 */ gboolean gda_worker_fetch_job_result (GdaWorker *worker, guint job_id, gpointer *out_result, GError **error) { g_return_val_if_fail (worker, FALSE); if (!worker->jobs_hash) { g_warning ("GdaWorker has been destroyed\n"); return FALSE; } gda_worker_ref (worker); /* increase reference count to having @worker freed while destroying job */ if (out_result) *out_result = NULL; g_rec_mutex_lock (&worker->rmutex); WorkerJob *job; job = g_hash_table_lookup (worker->jobs_hash, &job_id); if (!job) { g_rec_mutex_unlock (& worker->rmutex); g_set_error (error, GDA_WORKER_ERROR, GDA_WORKER_JOB_NOT_FOUND_ERROR, _("Unknown requested job %u"), job_id); gda_worker_unref (worker); return FALSE; } gboolean retval = FALSE; if (job->status & JOB_CANCELLED) g_set_error (error, GDA_WORKER_ERROR, GDA_WORKER_JOB_CANCELLED_ERROR, _("Job %u has been cancelled"), job_id); else if (job->status & JOB_PROCESSED) { retval = TRUE; if (out_result) { *out_result = job->result; job->result = NULL; } if (job->error) { g_propagate_error (error, job->error); job->error = NULL; } g_hash_table_remove (worker->jobs_hash, &job_id); } else if (job->status & JOB_BEING_PROCESSED) g_set_error (error, GDA_WORKER_ERROR, GDA_WORKER_JOB_BEING_PROCESSED_ERROR, _("Job %u is being processed"), job_id); else g_set_error (error, GDA_WORKER_ERROR, GDA_WORKER_JOB_QUEUED_ERROR, _("Job %u has not yet been processed"), job_id); g_rec_mutex_unlock (&worker->rmutex); gda_worker_unref (worker); return retval; }
/** * gdaprov_ldap_get_class_info: * @cnc: a #GdaLdapConnection (not %NULL) * @classname: the class name (not %NULL) * * Returns: the #GdaLdapClass for @classname, or %NULL */ GdaLdapClass * gdaprov_ldap_get_class_info (GdaLdapConnection *cnc, const gchar *classname) { g_return_val_if_fail (GDA_IS_LDAP_CONNECTION (cnc), NULL); g_return_val_if_fail (classname, NULL); gda_lockable_lock ((GdaLockable*) cnc); /* CNC LOCK */ LdapConnectionData *cdata; cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data (GDA_VIRTUAL_CONNECTION (cnc)); if (!cdata) { gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */ return NULL; } if (cdata->classes_hash) { gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */ return g_hash_table_lookup (cdata->classes_hash, classname); } GdaServerProviderConnectionData *pcdata; pcdata = gda_connection_internal_get_provider_data_error ((GdaConnection*) cnc, NULL); GdaWorker *worker; worker = gda_worker_ref (gda_connection_internal_get_worker (pcdata)); GMainContext *context; context = gda_server_provider_get_real_main_context ((GdaConnection *) cnc); WorkerLdapClassInfoData data; data.cnc = cnc; data.cdata = cdata; data.classname = classname; gda_connection_increase_usage ((GdaConnection*) cnc); /* USAGE ++ */ gpointer retval; gda_worker_do_job (worker, context, 0, &retval, NULL, (GdaWorkerFunc) worker_gdaprov_ldap_get_class_info, (gpointer) &data, NULL, NULL, NULL); if (context) g_main_context_unref (context); gda_connection_decrease_usage ((GdaConnection*) cnc); /* USAGE -- */ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */ gda_worker_unref (worker); return (GdaLdapClass*) retval; }
GdaLdapEntry * gdaprov_ldap_describe_entry (GdaLdapConnection *cnc, const gchar *dn, GError **error) { g_return_val_if_fail (GDA_IS_LDAP_CONNECTION (cnc), NULL); g_return_val_if_fail (!dn || (dn && *dn), NULL); gda_lockable_lock ((GdaLockable*) cnc); /* CNC LOCK */ LdapConnectionData *cdata; cdata = (LdapConnectionData*) gda_virtual_connection_internal_get_provider_data (GDA_VIRTUAL_CONNECTION (cnc)); if (!cdata) { gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */ return NULL; } GdaServerProviderConnectionData *pcdata; pcdata = gda_connection_internal_get_provider_data_error ((GdaConnection*) cnc, NULL); GdaWorker *worker; worker = gda_worker_ref (gda_connection_internal_get_worker (pcdata)); GMainContext *context; context = gda_server_provider_get_real_main_context ((GdaConnection *) cnc); WorkerLdapDescrEntryData data; data.cnc = cnc; data.cdata = cdata; data.dn = dn; gda_connection_increase_usage ((GdaConnection*) cnc); /* USAGE ++ */ gpointer retval; gda_worker_do_job (worker, context, 0, &retval, NULL, (GdaWorkerFunc) worker_gdaprov_ldap_describe_entry, (gpointer) &data, NULL, NULL, error); if (context) g_main_context_unref (context); gda_connection_decrease_usage ((GdaConnection*) cnc); /* USAGE -- */ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */ gda_worker_unref (worker); return (GdaLdapEntry*) retval; }
/** * gda_ldap_get_attr_info: * @cnc: a #GdaLdapConnection * @cdata: * @attribute: * * Returns: (transfer none): the #LdapAttribute for @attribute, or %NULL */ LdapAttribute * gda_ldap_get_attr_info (GdaLdapConnection *cnc, LdapConnectionData *cdata, const gchar *attribute) { g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL); if (! attribute || !cdata) return NULL; gda_lockable_lock ((GdaLockable*) cnc); /* CNC LOCK */ GdaServerProviderConnectionData *pcdata; pcdata = gda_connection_internal_get_provider_data_error ((GdaConnection*) cnc, NULL); GdaWorker *worker; worker = gda_worker_ref (gda_connection_internal_get_worker (pcdata)); GMainContext *context; context = gda_server_provider_get_real_main_context ((GdaConnection *) cnc); WorkerLdapAttrInfoData data; data.cnc = cnc; data.cdata = cdata; data.attribute = attribute; gda_connection_increase_usage ((GdaConnection*) cnc); /* USAGE ++ */ gpointer retval; gda_worker_do_job (worker, context, 0, &retval, NULL, (GdaWorkerFunc) worker_gda_ldap_get_attr_info, (gpointer) &data, NULL, NULL, NULL); if (context) g_main_context_unref (context); gda_connection_decrease_usage ((GdaConnection*) cnc); /* USAGE -- */ gda_lockable_unlock ((GdaLockable*) cnc); /* CNC UNLOCK */ gda_worker_unref (worker); return (LdapAttribute*) retval; }