Skip to content

Commit

Permalink
libostree: Allow OstreeAsyncProgress:status to be set atomically
Browse files Browse the repository at this point in the history
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 <[email protected]>

Closes: #819
Approved by: cgwalters
  • Loading branch information
pwithnall authored and rh-atomic-bot committed Apr 29, 2017
1 parent cdf8761 commit ce83abb
Showing 1 changed file with 37 additions and 16 deletions.
53 changes: 37 additions & 16 deletions src/libostree/ostree-async-progress.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@
* handles thread safety, ensuring that the progress change
* notification occurs in the thread-default context of the calling
* 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 {
Expand All @@ -58,8 +63,6 @@ struct OstreeAsyncProgress
GHashTable *values; /* (element-type uint GVariant) */

gboolean dead;

char *status;
};

G_DEFINE_TYPE (OstreeAsyncProgress, ostree_async_progress, G_TYPE_OBJECT)
Expand All @@ -75,7 +78,6 @@ ostree_async_progress_finalize (GObject *object)
g_clear_pointer (&self->maincontext, g_main_context_unref);
g_clear_pointer (&self->idle_source, g_source_unref);
g_hash_table_unref (self->values);
g_free (self->status);

G_OBJECT_CLASS (ostree_async_progress_parent_class)->finalize (object);
}
Expand Down Expand Up @@ -243,28 +245,47 @@ ensure_callback_locked (OstreeAsyncProgress *self)
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
ostree_async_progress_set_status (OstreeAsyncProgress *self,
const char *status)
{
g_mutex_lock (&self->lock);
if (!self->dead)
{
g_free (self->status);
self->status = g_strdup (status);
ensure_callback_locked (self);
}
g_mutex_unlock (&self->lock);
ostree_async_progress_set_variant (self, "status",
g_variant_new_string ((status != NULL) ? status : ""));
}

/**
* 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 *
ostree_async_progress_get_status (OstreeAsyncProgress *self)
{
char *ret;
g_mutex_lock (&self->lock);
ret = g_strdup (self->status);
g_mutex_unlock (&self->lock);
return ret;
g_autoptr(GVariant) rval = ostree_async_progress_get_variant (self, "status");
const gchar *status = (rval != NULL) ? g_variant_get_string (rval, NULL) : NULL;
if (status != NULL && *status == '\0')
status = NULL;
return g_strdup (status);
}

/**
Expand Down

0 comments on commit ce83abb

Please sign in to comment.