libostree: Allow OstreeAsyncProgress:status to be set atomically
Rework how the status is handled in OstreeAsyncProgress so that it’s now a well-known key in the hash table. This means that it can be retrieved and set atomically with other keys using ostree_async_progress_[get|set](). The behaviour of ostree_async_progress_[get|set]_status() is preserved, with the caveat that `status` can now also be accessed using the other API on OstreeAsyncProgress, and has to be accessed with the right GVariant type. Internally, a NULL status is represented by an empty status string (since ostree_async_progress_[get|set]_variant() deliberately don’t allow NULL variants to be set against keys, since that would break the ostree_async_progress_get() API). Signed-off-by: Philip Withnall <withnall@endlessm.com> Closes: #819 Approved by: cgwalters
This commit is contained in:
parent
cdf876101b
commit
ce83abb868
|
|
@ -39,6 +39,11 @@
|
||||||
* handles thread safety, ensuring that the progress change
|
* handles thread safety, ensuring that the progress change
|
||||||
* notification occurs in the thread-default context of the calling
|
* notification occurs in the thread-default context of the calling
|
||||||
* operation.
|
* operation.
|
||||||
|
*
|
||||||
|
* The ostree_async_progress_get_status() and ostree_async_progress_set_status()
|
||||||
|
* methods get and set a well-known `status` key of type %G_VARIANT_TYPE_STRING.
|
||||||
|
* This key may be accessed using the other #OstreeAsyncProgress methods, but it
|
||||||
|
* must always have the correct type.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|
@ -58,8 +63,6 @@ struct OstreeAsyncProgress
|
||||||
GHashTable *values; /* (element-type uint GVariant) */
|
GHashTable *values; /* (element-type uint GVariant) */
|
||||||
|
|
||||||
gboolean dead;
|
gboolean dead;
|
||||||
|
|
||||||
char *status;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE (OstreeAsyncProgress, ostree_async_progress, G_TYPE_OBJECT)
|
G_DEFINE_TYPE (OstreeAsyncProgress, ostree_async_progress, G_TYPE_OBJECT)
|
||||||
|
|
@ -75,7 +78,6 @@ ostree_async_progress_finalize (GObject *object)
|
||||||
g_clear_pointer (&self->maincontext, g_main_context_unref);
|
g_clear_pointer (&self->maincontext, g_main_context_unref);
|
||||||
g_clear_pointer (&self->idle_source, g_source_unref);
|
g_clear_pointer (&self->idle_source, g_source_unref);
|
||||||
g_hash_table_unref (self->values);
|
g_hash_table_unref (self->values);
|
||||||
g_free (self->status);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (ostree_async_progress_parent_class)->finalize (object);
|
G_OBJECT_CLASS (ostree_async_progress_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
@ -243,28 +245,47 @@ ensure_callback_locked (OstreeAsyncProgress *self)
|
||||||
g_source_attach (self->idle_source, self->maincontext);
|
g_source_attach (self->idle_source, self->maincontext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ostree_async_progress_set_status:
|
||||||
|
* @self: an #OstreeAsyncProgress
|
||||||
|
* @status: (nullable): new status string, or %NULL to clear the status
|
||||||
|
*
|
||||||
|
* Set the human-readable status string for the #OstreeAsyncProgress. This
|
||||||
|
* operation is thread-safe. %NULL may be passed to clear the status.
|
||||||
|
*
|
||||||
|
* This is a convenience function to set the well-known `status` key.
|
||||||
|
*
|
||||||
|
* Since: 2017.6
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
ostree_async_progress_set_status (OstreeAsyncProgress *self,
|
ostree_async_progress_set_status (OstreeAsyncProgress *self,
|
||||||
const char *status)
|
const char *status)
|
||||||
{
|
{
|
||||||
g_mutex_lock (&self->lock);
|
ostree_async_progress_set_variant (self, "status",
|
||||||
if (!self->dead)
|
g_variant_new_string ((status != NULL) ? status : ""));
|
||||||
{
|
|
||||||
g_free (self->status);
|
|
||||||
self->status = g_strdup (status);
|
|
||||||
ensure_callback_locked (self);
|
|
||||||
}
|
|
||||||
g_mutex_unlock (&self->lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ostree_async_progress_get_status:
|
||||||
|
* @self: an #OstreeAsyncProgress
|
||||||
|
*
|
||||||
|
* Get the human-readable status string from the #OstreeAsyncProgress. This
|
||||||
|
* operation is thread-safe. The retuned value may be %NULL if no status is
|
||||||
|
* set.
|
||||||
|
*
|
||||||
|
* This is a convenience function to get the well-known `status` key.
|
||||||
|
*
|
||||||
|
* Returns: (transfer full) (nullable): the current status, or %NULL if none is set
|
||||||
|
* Since: 2017.6
|
||||||
|
*/
|
||||||
char *
|
char *
|
||||||
ostree_async_progress_get_status (OstreeAsyncProgress *self)
|
ostree_async_progress_get_status (OstreeAsyncProgress *self)
|
||||||
{
|
{
|
||||||
char *ret;
|
g_autoptr(GVariant) rval = ostree_async_progress_get_variant (self, "status");
|
||||||
g_mutex_lock (&self->lock);
|
const gchar *status = (rval != NULL) ? g_variant_get_string (rval, NULL) : NULL;
|
||||||
ret = g_strdup (self->status);
|
if (status != NULL && *status == '\0')
|
||||||
g_mutex_unlock (&self->lock);
|
status = NULL;
|
||||||
return ret;
|
return g_strdup (status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue