Remove use of gnulib glthread.

This gnulib feature abstracts away threads, locks and TLS, and also
allowed libguestfs to be linked with or without pthread.  However
since pthread these days is part of glibc and so every program is
using pthread, and we want to get rid of gnulib as a dependency, just
use pthread directly.
This commit is contained in:
Richard W.M. Jones
2021-04-06 13:28:09 +01:00
parent 5244d11bd7
commit 9cfa1c410f
8 changed files with 95 additions and 108 deletions

View File

@@ -1704,7 +1704,7 @@ and generate_client_actions actions () =
~dll_public:true ~dll_public:true
c_name style; c_name style;
pr "{\n"; pr "{\n";
pr " ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g);\n"; pr " ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&g->lock);\n";
handle_null_optargs optargs c_name; handle_null_optargs optargs c_name;
@@ -1791,7 +1791,7 @@ and generate_client_actions actions () =
c_name style; c_name style;
pr "{\n"; pr "{\n";
pr " ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g);\n"; pr " ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&g->lock);\n";
handle_null_optargs optargs c_name; handle_null_optargs optargs c_name;
@@ -2137,7 +2137,7 @@ and generate_client_actions_variants () =
~handle:"g" ~prefix:"guestfs_" ~suffix:"_va" ~optarg_proto:VA ~handle:"g" ~prefix:"guestfs_" ~suffix:"_va" ~optarg_proto:VA
c_name style; c_name style;
pr "{\n"; pr "{\n";
pr " ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g);\n"; pr " ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&g->lock);\n";
pr " struct guestfs_%s_argv optargs_s;\n" c_name; pr " struct guestfs_%s_argv optargs_s;\n" c_name;
pr " struct guestfs_%s_argv *optargs = &optargs_s;\n" c_name; pr " struct guestfs_%s_argv *optargs = &optargs_s;\n" c_name;
pr " int i;\n"; pr " int i;\n";
@@ -2195,7 +2195,7 @@ and generate_client_actions_variants () =
~handle:"g" ~prefix:"guestfs_" ~handle:"g" ~prefix:"guestfs_"
name (ret, args, []); name (ret, args, []);
pr "{\n"; pr "{\n";
pr " ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g);\n"; pr " ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&g->lock);\n";
pr " struct guestfs_%s_opts_argv optargs_s = { .bitmask = 0 };\n" name; pr " struct guestfs_%s_opts_argv optargs_s = { .bitmask = 0 };\n" name;
pr " struct guestfs_%s_opts_argv *optargs = &optargs_s;\n" name; pr " struct guestfs_%s_opts_argv *optargs = &optargs_s;\n" name;
pr "\n"; pr "\n";

View File

@@ -126,7 +126,7 @@ guestfs_int_free_error_data_list (guestfs_h *g)
{ {
struct error_data *p, *next_p; struct error_data *p, *next_p;
gl_lock_lock (g->error_data_list_lock); ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&g->error_data_list_lock);
for (p = g->error_data_list; p != NULL; p = next_p) { for (p = g->error_data_list; p != NULL; p = next_p) {
next_p = p->next; next_p = p->next;
@@ -134,8 +134,6 @@ guestfs_int_free_error_data_list (guestfs_h *g)
} }
g->error_data_list = NULL; g->error_data_list = NULL;
gl_lock_unlock (g->error_data_list_lock);
} }
/* Get thread-specific error_data struct. Create it if necessary. */ /* Get thread-specific error_data struct. Create it if necessary. */
@@ -144,7 +142,7 @@ get_error_data (guestfs_h *g)
{ {
struct error_data *ret; struct error_data *ret;
ret = gl_tls_get (g->error_data); ret = pthread_getspecific (g->error_data);
/* Not allocated yet for this thread, so allocate one. */ /* Not allocated yet for this thread, so allocate one. */
if (ret == NULL) { if (ret == NULL) {
@@ -159,15 +157,16 @@ get_error_data (guestfs_h *g)
* associated with this handle, so we can free them when the * associated with this handle, so we can free them when the
* handle is closed. * handle is closed.
*/ */
gl_lock_lock (g->error_data_list_lock); {
ret->next = g->error_data_list; ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&g->error_data_list_lock);
g->error_data_list = ret; ret->next = g->error_data_list;
gl_lock_unlock (g->error_data_list_lock); g->error_data_list = ret;
}
/* Set the TLS to point to the struct. This is safe because we /* Set the TLS to point to the struct. This is safe because we
* should have acquired the handle lock. * should have acquired the handle lock.
*/ */
gl_tls_set (g->error_data, ret); pthread_setspecific (g->error_data, ret);
} }
return ret; return ret;
@@ -176,14 +175,14 @@ get_error_data (guestfs_h *g)
const char * const char *
guestfs_last_error (guestfs_h *g) guestfs_last_error (guestfs_h *g)
{ {
ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&g->lock);
return get_error_data (g)->last_error; return get_error_data (g)->last_error;
} }
int int
guestfs_last_errno (guestfs_h *g) guestfs_last_errno (guestfs_h *g)
{ {
ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&g->lock);
return get_error_data (g)->last_errnum; return get_error_data (g)->last_errnum;
} }
@@ -347,14 +346,14 @@ guestfs_int_perrorf (guestfs_h *g, const char *fs, ...)
void void
guestfs_set_out_of_memory_handler (guestfs_h *g, guestfs_abort_cb cb) guestfs_set_out_of_memory_handler (guestfs_h *g, guestfs_abort_cb cb)
{ {
ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&g->lock);
g->abort_cb = cb; g->abort_cb = cb;
} }
guestfs_abort_cb guestfs_abort_cb
guestfs_get_out_of_memory_handler (guestfs_h *g) guestfs_get_out_of_memory_handler (guestfs_h *g)
{ {
ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&g->lock);
return g->abort_cb; return g->abort_cb;
} }
@@ -362,7 +361,7 @@ void
guestfs_set_error_handler (guestfs_h *g, guestfs_set_error_handler (guestfs_h *g,
guestfs_error_handler_cb cb, void *data) guestfs_error_handler_cb cb, void *data)
{ {
ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&g->lock);
struct error_data *error_data; struct error_data *error_data;
error_data = get_error_data (g); error_data = get_error_data (g);
@@ -373,7 +372,7 @@ guestfs_set_error_handler (guestfs_h *g,
guestfs_error_handler_cb guestfs_error_handler_cb
guestfs_get_error_handler (guestfs_h *g, void **data_rtn) guestfs_get_error_handler (guestfs_h *g, void **data_rtn)
{ {
ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&g->lock);
struct error_data *error_data = get_error_data (g); struct error_data *error_data = get_error_data (g);
if (data_rtn) *data_rtn = error_data->error_cb_data; if (data_rtn) *data_rtn = error_data->error_cb_data;
@@ -384,7 +383,7 @@ void
guestfs_push_error_handler (guestfs_h *g, guestfs_push_error_handler (guestfs_h *g,
guestfs_error_handler_cb cb, void *data) guestfs_error_handler_cb cb, void *data)
{ {
ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&g->lock);
struct error_data *error_data; struct error_data *error_data;
struct error_cb_stack *old_stack; struct error_cb_stack *old_stack;
@@ -401,7 +400,7 @@ guestfs_push_error_handler (guestfs_h *g,
void void
guestfs_pop_error_handler (guestfs_h *g) guestfs_pop_error_handler (guestfs_h *g)
{ {
ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&g->lock);
struct error_data *error_data; struct error_data *error_data;
struct error_cb_stack *next_stack; struct error_cb_stack *next_stack;

View File

@@ -35,7 +35,7 @@ guestfs_set_event_callback (guestfs_h *g,
int flags, int flags,
void *opaque) void *opaque)
{ {
ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&g->lock);
int event_handle; int event_handle;
if (flags != 0) { if (flags != 0) {
@@ -70,7 +70,7 @@ guestfs_set_event_callback (guestfs_h *g,
void void
guestfs_delete_event_callback (guestfs_h *g, int event_handle) guestfs_delete_event_callback (guestfs_h *g, int event_handle)
{ {
ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&g->lock);
if (event_handle < 0 || event_handle >= (int) g->nr_events) if (event_handle < 0 || event_handle >= (int) g->nr_events)
return; return;
@@ -299,7 +299,7 @@ void
guestfs_set_log_message_callback (guestfs_h *g, guestfs_set_log_message_callback (guestfs_h *g,
guestfs_log_message_cb cb, void *opaque) guestfs_log_message_cb cb, void *opaque)
{ {
ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&g->lock);
replace_old_style_event_callback (g, log_message_callback_wrapper, replace_old_style_event_callback (g, log_message_callback_wrapper,
GUESTFS_EVENT_APPLIANCE, GUESTFS_EVENT_APPLIANCE,
opaque, cb); opaque, cb);
@@ -322,7 +322,7 @@ void
guestfs_set_subprocess_quit_callback (guestfs_h *g, guestfs_set_subprocess_quit_callback (guestfs_h *g,
guestfs_subprocess_quit_cb cb, void *opaque) guestfs_subprocess_quit_cb cb, void *opaque)
{ {
ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&g->lock);
replace_old_style_event_callback (g, subprocess_quit_callback_wrapper, replace_old_style_event_callback (g, subprocess_quit_callback_wrapper,
GUESTFS_EVENT_SUBPROCESS_QUIT, GUESTFS_EVENT_SUBPROCESS_QUIT,
opaque, cb); opaque, cb);
@@ -345,7 +345,7 @@ void
guestfs_set_launch_done_callback (guestfs_h *g, guestfs_set_launch_done_callback (guestfs_h *g,
guestfs_launch_done_cb cb, void *opaque) guestfs_launch_done_cb cb, void *opaque)
{ {
ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&g->lock);
replace_old_style_event_callback (g, launch_done_callback_wrapper, replace_old_style_event_callback (g, launch_done_callback_wrapper,
GUESTFS_EVENT_LAUNCH_DONE, GUESTFS_EVENT_LAUNCH_DONE,
opaque, cb); opaque, cb);
@@ -368,7 +368,7 @@ void
guestfs_set_close_callback (guestfs_h *g, guestfs_set_close_callback (guestfs_h *g,
guestfs_close_cb cb, void *opaque) guestfs_close_cb cb, void *opaque)
{ {
ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&g->lock);
replace_old_style_event_callback (g, close_callback_wrapper, replace_old_style_event_callback (g, close_callback_wrapper,
GUESTFS_EVENT_CLOSE, GUESTFS_EVENT_CLOSE,
opaque, cb); opaque, cb);
@@ -392,7 +392,7 @@ void
guestfs_set_progress_callback (guestfs_h *g, guestfs_set_progress_callback (guestfs_h *g,
guestfs_progress_cb cb, void *opaque) guestfs_progress_cb cb, void *opaque)
{ {
ACQUIRE_LOCK_FOR_CURRENT_SCOPE (g); ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&g->lock);
replace_old_style_event_callback (g, progress_callback_wrapper, replace_old_style_event_callback (g, progress_callback_wrapper,
GUESTFS_EVENT_PROGRESS, GUESTFS_EVENT_PROGRESS,
opaque, cb); opaque, cb);

View File

@@ -47,7 +47,6 @@
#endif #endif
#include "cloexec.h" #include "cloexec.h"
#include "glthread/lock.h"
#include "hash.h" #include "hash.h"
#include "hash-pjw.h" #include "hash-pjw.h"
@@ -71,7 +70,7 @@ static const struct guestfs_xattr_list *xac_lookup (guestfs_h *, const char *pat
static const char *rlc_lookup (guestfs_h *, const char *pathname); static const char *rlc_lookup (guestfs_h *, const char *pathname);
/* This lock protects access to g->localmountpoint. */ /* This lock protects access to g->localmountpoint. */
gl_lock_define_initialized (static, mount_local_lock); static pthread_mutex_t mount_local_lock = PTHREAD_MUTEX_INITIALIZER;
#define DECL_G() guestfs_h *g = fuse_get_context()->private_data #define DECL_G() guestfs_h *g = fuse_get_context()->private_data
#define DEBUG_CALL(fs,...) \ #define DEBUG_CALL(fs,...) \
@@ -965,9 +964,10 @@ guestfs_impl_mount_local (guestfs_h *g, const char *localmountpoint,
int fd; int fd;
/* You can only mount each handle in one place in one thread. */ /* You can only mount each handle in one place in one thread. */
gl_lock_lock (mount_local_lock); {
t = g->localmountpoint; ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&mount_local_lock);
gl_lock_unlock (mount_local_lock); t = g->localmountpoint;
}
if (t) { if (t) {
error (g, _("filesystem is already mounted in another thread")); error (g, _("filesystem is already mounted in another thread"));
return -1; return -1;
@@ -1041,9 +1041,8 @@ guestfs_impl_mount_local (guestfs_h *g, const char *localmountpoint,
debug (g, "%s: leaving fuse_mount_local", __func__); debug (g, "%s: leaving fuse_mount_local", __func__);
/* Set g->localmountpoint in the handle. */ /* Set g->localmountpoint in the handle. */
gl_lock_lock (mount_local_lock); ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&mount_local_lock);
g->localmountpoint = safe_strdup (g, localmountpoint); g->localmountpoint = safe_strdup (g, localmountpoint);
gl_lock_unlock (mount_local_lock);
return 0; return 0;
} }
@@ -1053,9 +1052,10 @@ guestfs_impl_mount_local_run (guestfs_h *g)
{ {
int r, mounted; int r, mounted;
gl_lock_lock (mount_local_lock); {
mounted = g->localmountpoint != NULL; ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&mount_local_lock);
gl_lock_unlock (mount_local_lock); mounted = g->localmountpoint != NULL;
}
if (!mounted) { if (!mounted) {
error (g, _("you must call guestfs_mount_local first")); error (g, _("you must call guestfs_mount_local first"));
@@ -1084,10 +1084,9 @@ guestfs_impl_mount_local_run (guestfs_h *g)
debug (g, "%s: leaving fuse_loop", __func__); debug (g, "%s: leaving fuse_loop", __func__);
guestfs_int_free_fuse (g); guestfs_int_free_fuse (g);
gl_lock_lock (mount_local_lock); ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&mount_local_lock);
free (g->localmountpoint); free (g->localmountpoint);
g->localmountpoint = NULL; g->localmountpoint = NULL;
gl_lock_unlock (mount_local_lock);
/* By inspection, I found that fuse_loop only returns 0 or -1, but /* By inspection, I found that fuse_loop only returns 0 or -1, but
* don't rely on this in future. * don't rely on this in future.
@@ -1122,12 +1121,13 @@ guestfs_impl_umount_local (guestfs_h *g,
/* Make a local copy of g->localmountpoint. It could be freed from /* Make a local copy of g->localmountpoint. It could be freed from
* under us by another thread, except when we are holding the lock. * under us by another thread, except when we are holding the lock.
*/ */
gl_lock_lock (mount_local_lock); {
if (g->localmountpoint) ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&mount_local_lock);
localmountpoint = safe_strdup (g, g->localmountpoint); if (g->localmountpoint)
else localmountpoint = safe_strdup (g, g->localmountpoint);
localmountpoint = NULL; else
gl_lock_unlock (mount_local_lock); localmountpoint = NULL;
}
if (!localmountpoint) { if (!localmountpoint) {
error (g, _("no filesystem is mounted")); error (g, _("no filesystem is mounted"));

View File

@@ -27,6 +27,7 @@
#define GUESTFS_INTERNAL_H_ #define GUESTFS_INTERNAL_H_
#include <stdbool.h> #include <stdbool.h>
#include <assert.h>
#include <rpc/types.h> /* Needed on libc's different than glibc. */ #include <rpc/types.h> /* Needed on libc's different than glibc. */
#include <rpc/xdr.h> #include <rpc/xdr.h>
@@ -34,6 +35,8 @@
#define PCRE2_CODE_UNIT_WIDTH 8 #define PCRE2_CODE_UNIT_WIDTH 8
#include <pcre2.h> #include <pcre2.h>
#include <pthread.h>
/* Minimum required version of libvirt for the libvirt backend. /* Minimum required version of libvirt for the libvirt backend.
* *
* This is also checked at runtime because you can dynamically link * This is also checked at runtime because you can dynamically link
@@ -53,8 +56,6 @@
#endif #endif
#endif #endif
#include "glthread/lock.h"
#include "glthread/tls.h"
#include "hash.h" #include "hash.h"
#include "guestfs-utils.h" #include "guestfs-utils.h"
@@ -79,22 +80,29 @@
#define TRACE4(name, arg1, arg2, arg3, arg4) #define TRACE4(name, arg1, arg2, arg3, arg4)
#endif #endif
/* https://stackoverflow.com/a/1597129 */
#define XXUNIQUE_VAR(name, line) name ## line
#define XUNIQUE_VAR(name, line) XXUNIQUE_VAR (name, line)
#define UNIQUE_VAR(name) XUNIQUE_VAR (name, __LINE__)
/* Acquire and release the per-handle lock. Note the release happens /* Acquire and release the per-handle lock. Note the release happens
* in an __attribute__((cleanup)) handler, making it simple to write * in an __attribute__((cleanup)) handler, making it simple to write
* bug-free code. * bug-free code.
*/ */
#define ACQUIRE_LOCK_FOR_CURRENT_SCOPE(g) \ #define ACQUIRE_LOCK_FOR_CURRENT_SCOPE(mutex) \
CLEANUP_GL_RECURSIVE_LOCK_UNLOCK gl_recursive_lock_t *_lock = &(g)->lock; \ CLEANUP_MUTEX_UNLOCK pthread_mutex_t *UNIQUE_VAR(_lock) = mutex; \
gl_recursive_lock_lock (*_lock) do { \
int _r = pthread_mutex_lock (UNIQUE_VAR(_lock)); \
assert (!_r); \
} while (0)
#define CLEANUP_GL_RECURSIVE_LOCK_UNLOCK \ #define CLEANUP_MUTEX_UNLOCK __attribute__((cleanup (cleanup_mutex_unlock)))
__attribute__((cleanup(guestfs_int_cleanup_gl_recursive_lock_unlock)))
static inline void static inline void
guestfs_int_cleanup_gl_recursive_lock_unlock (void *ptr) cleanup_mutex_unlock (pthread_mutex_t **ptr)
{ {
gl_recursive_lock_t *lockp = * (gl_recursive_lock_t **) ptr; int r = pthread_mutex_unlock (*ptr);
gl_recursive_lock_unlock (*lockp); assert (!r);
} }
/* Default and minimum appliance memory size. */ /* Default and minimum appliance memory size. */
@@ -389,7 +397,7 @@ struct guestfs_h {
/* Lock acquired when entering any public guestfs_* function to /* Lock acquired when entering any public guestfs_* function to
* protect the handle. * protect the handle.
*/ */
gl_recursive_lock_define (, lock); pthread_mutex_t lock;
/**** Configuration of the handle. ****/ /**** Configuration of the handle. ****/
bool verbose; /* Debugging. */ bool verbose; /* Debugging. */
@@ -459,12 +467,12 @@ struct guestfs_h {
char *int_cachedir; /* $LIBGUESTFS_CACHEDIR or guestfs_set_cachedir or NULL */ char *int_cachedir; /* $LIBGUESTFS_CACHEDIR or guestfs_set_cachedir or NULL */
/* Error handler, plus stack of old error handlers. */ /* Error handler, plus stack of old error handlers. */
gl_tls_key_t error_data; pthread_key_t error_data;
/* Linked list of error_data structures allocated for this handle, /* Linked list of error_data structures allocated for this handle,
* plus a mutex to protect the linked list. * plus a mutex to protect the linked list.
*/ */
gl_lock_define (, error_data_list_lock); pthread_mutex_t error_data_list_lock;
struct error_data *error_data_list; struct error_data *error_data_list;
/* Out of memory error handler. */ /* Out of memory error handler. */

View File

@@ -31,8 +31,6 @@
#include <libxml/parser.h> #include <libxml/parser.h>
#include <libxml/xmlversion.h> #include <libxml/xmlversion.h>
#include "glthread/lock.h"
#include "glthread/tls.h"
#include "ignore-value.h" #include "ignore-value.h"
#include "c-ctype.h" #include "c-ctype.h"
#include "getprogname.h" #include "getprogname.h"
@@ -44,11 +42,11 @@
static int shutdown_backend (guestfs_h *g, int check_for_errors); static int shutdown_backend (guestfs_h *g, int check_for_errors);
static void close_handles (void); static void close_handles (void);
gl_lock_define_initialized (static, handles_lock); static pthread_mutex_t handles_lock = PTHREAD_MUTEX_INITIALIZER;
static guestfs_h *handles = NULL; static guestfs_h *handles = NULL;
static int atexit_handler_set = 0; static int atexit_handler_set = 0;
gl_lock_define_initialized (static, init_lock); static pthread_mutex_t init_lock = PTHREAD_MUTEX_INITIALIZER;
static void init_libguestfs (void) __attribute__((constructor)); static void init_libguestfs (void) __attribute__((constructor));
@@ -61,7 +59,7 @@ static void init_libguestfs (void) __attribute__((constructor));
static void static void
init_libguestfs (void) init_libguestfs (void)
{ {
gl_lock_lock (init_lock); ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&init_lock);
#ifdef HAVE_LIBVIRT #ifdef HAVE_LIBVIRT
virInitialize (); virInitialize ();
@@ -69,8 +67,6 @@ init_libguestfs (void)
xmlInitParser (); xmlInitParser ();
LIBXML_TEST_VERSION; LIBXML_TEST_VERSION;
gl_lock_unlock (init_lock);
} }
guestfs_h * guestfs_h *
@@ -83,18 +79,23 @@ guestfs_h *
guestfs_create_flags (unsigned flags, ...) guestfs_create_flags (unsigned flags, ...)
{ {
guestfs_h *g; guestfs_h *g;
pthread_mutexattr_t attr;
g = calloc (1, sizeof (*g)); g = calloc (1, sizeof (*g));
if (!g) return NULL; if (!g) return NULL;
gl_recursive_lock_init (g->lock); /* The per-handle lock is recursive. */
gl_lock_init (g->error_data_list_lock); pthread_mutexattr_init (&attr);
pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init (&g->lock, &attr);
pthread_mutex_init (&g->error_data_list_lock, NULL);
g->state = CONFIG; g->state = CONFIG;
g->conn = NULL; g->conn = NULL;
gl_tls_key_init (g->error_data, NULL); pthread_key_create (&g->error_data, NULL);
g->abort_cb = abort; g->abort_cb = abort;
g->recovery_proc = 1; g->recovery_proc = 1;
@@ -152,14 +153,13 @@ guestfs_create_flags (unsigned flags, ...)
g->close_on_exit = true; g->close_on_exit = true;
/* Link the handles onto a global list. */ /* Link the handles onto a global list. */
gl_lock_lock (handles_lock); ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&handles_lock);
g->next = handles; g->next = handles;
handles = g; handles = g;
if (!atexit_handler_set) { if (!atexit_handler_set) {
atexit (close_handles); atexit (close_handles);
atexit_handler_set = 1; atexit_handler_set = 1;
} }
gl_lock_unlock (handles_lock);
} }
debug (g, "create: flags = %u, handle = %p, program = %s", debug (g, "create: flags = %u, handle = %p, program = %s",
@@ -176,9 +176,9 @@ guestfs_create_flags (unsigned flags, ...)
free (g->hv); free (g->hv);
free (g->append); free (g->append);
guestfs_int_free_error_data_list (g); guestfs_int_free_error_data_list (g);
gl_tls_key_destroy (g->error_data); pthread_key_delete (g->error_data);
gl_lock_destroy (g->error_data_list_lock); pthread_mutex_destroy (&g->error_data_list_lock);
gl_recursive_lock_destroy (g->lock); pthread_mutex_destroy (&g->lock);
free (g); free (g);
return NULL; return NULL;
} }
@@ -329,7 +329,6 @@ guestfs_close (guestfs_h *g)
{ {
struct hv_param *hp, *hp_next; struct hv_param *hp, *hp_next;
guestfs_h **gg; guestfs_h **gg;
int r;
if (g->state == NO_HANDLE) { if (g->state == NO_HANDLE) {
/* Not safe to call ANY callbacks here, so ... */ /* Not safe to call ANY callbacks here, so ... */
@@ -339,11 +338,10 @@ guestfs_close (guestfs_h *g)
/* Remove the handle from the handles list. */ /* Remove the handle from the handles list. */
if (g->close_on_exit) { if (g->close_on_exit) {
gl_lock_lock (handles_lock); ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&handles_lock);
for (gg = &handles; *gg != g; gg = &(*gg)->next) for (gg = &handles; *gg != g; gg = &(*gg)->next)
; ;
*gg = g->next; *gg = g->next;
gl_lock_unlock (handles_lock);
} }
if (g->trace) { if (g->trace) {
@@ -409,22 +407,8 @@ guestfs_close (guestfs_h *g)
guestfs_int_free_string_list (g->backend_settings); guestfs_int_free_string_list (g->backend_settings);
free (g->append); free (g->append);
guestfs_int_free_error_data_list (g); guestfs_int_free_error_data_list (g);
gl_tls_key_destroy (g->error_data); pthread_key_delete (g->error_data);
r = glthread_recursive_lock_destroy (&g->lock); pthread_mutex_destroy (&g->lock);
if (r != 0) {
/* If pthread_mutex_destroy returns 16 (EBUSY), this indicates
* that the lock is held somewhere. That means a programming
* error if the main program is using threads.
*/
errno = r;
perror ("guestfs_close: g->lock");
/* While we're debugging locks in libguestfs I want this to fail
* noisily. Remove this later since there are valid times when
* this might fail such as if the program exits during a
* libguestfs operation.
*/
abort ();
}
free (g); free (g);
} }

View File

@@ -25,7 +25,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/wait.h> #include <sys/wait.h>
#include "glthread/lock.h" #include <pthread.h>
#include "guestfs.h" #include "guestfs.h"
#include "guestfs-internal.h" #include "guestfs-internal.h"
@@ -50,7 +50,7 @@
* (Suggested by Marcelo Tosatti) * (Suggested by Marcelo Tosatti)
*/ */
gl_lock_define_initialized (static, lpj_lock); static pthread_mutex_t lpj_lock = PTHREAD_MUTEX_INITIALIZER;
static int lpj = 0; static int lpj = 0;
static int read_lpj_from_dmesg (guestfs_h *g); static int read_lpj_from_dmesg (guestfs_h *g);
static int read_lpj_from_files (guestfs_h *g); static int read_lpj_from_files (guestfs_h *g);
@@ -61,9 +61,9 @@ guestfs_int_get_lpj (guestfs_h *g)
{ {
int r; int r;
gl_lock_lock (lpj_lock); ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&lpj_lock);
if (lpj != 0) if (lpj != 0)
goto out; return lpj;
/* Try reading lpj from these sources: /* Try reading lpj from these sources:
* - /proc/cpuinfo [in future] * - /proc/cpuinfo [in future]
@@ -73,14 +73,10 @@ guestfs_int_get_lpj (guestfs_h *g)
* + /var/log/boot.msg * + /var/log/boot.msg
*/ */
r = read_lpj_from_dmesg (g); r = read_lpj_from_dmesg (g);
if (r > 0) { if (r > 0)
lpj = r; return lpj = r;
goto out;
}
lpj = read_lpj_from_files (g);
out: lpj = read_lpj_from_files (g);
gl_lock_unlock (lpj_lock);
return lpj; return lpj;
} }

View File

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