threads: Acquire and release the lock around each public guestfs_* API.

Acquire the per-handle lock on entering each public API function.

The lock is released by a cleanup handler, so we only need to use the
ACQUIRE_LOCK_FOR_CURRENT_SCOPE macro at the top of each function.

Note this means we require __attribute__((cleanup)).  On platforms
where this is not supported, the code will probably hang whenever a
libguestfs function is called.

The only definitive list of public APIs is found indirectly in the
generator (in generator/c.ml : globals).
This commit is contained in:
Richard W.M. Jones
2015-06-02 22:21:18 +01:00
parent d94a881d87
commit b9847b404c
6 changed files with 51 additions and 1 deletions

View File

@@ -81,6 +81,7 @@ freer (void *x)
void
guestfs_set_private (guestfs_h *g, const char *key, void *data)
{
ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g);
struct pda_entry *new_entry, *old_entry, *entry;
if (g->pda == NULL) {
@@ -105,6 +106,8 @@ guestfs_set_private (guestfs_h *g, const char *key, void *data)
void *
guestfs_get_private (guestfs_h *g, const char *key)
{
ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g);
if (g->pda == NULL)
return NULL; /* no keys have been set */
@@ -120,6 +123,8 @@ guestfs_get_private (guestfs_h *g, const char *key)
void *
guestfs_first_private (guestfs_h *g, const char **key_rtn)
{
ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g);
if (g->pda == NULL)
return NULL;
@@ -139,6 +144,8 @@ guestfs_first_private (guestfs_h *g, const char **key_rtn)
void *
guestfs_next_private (guestfs_h *g, const char **key_rtn)
{
ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g);
if (g->pda == NULL)
return NULL;