* [Qemu-devel] [PATCH 1/4] glib-compat.h: add new thread API emulation on top of pre-2.31 API
2014-05-23 11:44 [Qemu-devel] [PATCH 0/4] standalone libcacard Paolo Bonzini
@ 2014-05-23 11:44 ` Paolo Bonzini
2014-05-23 15:03 ` Stefan Hajnoczi
2014-06-06 13:28 ` Stefan Hajnoczi
2014-05-23 11:44 ` [Qemu-devel] [PATCH 2/4] vscclient: use glib thread primitives not qemu Paolo Bonzini
` (2 subsequent siblings)
3 siblings, 2 replies; 9+ messages in thread
From: Paolo Bonzini @ 2014-05-23 11:44 UTC (permalink / raw)
To: qemu-devel; +Cc: Michael Tokarev, stefanha, mjt
From: Michael Tokarev <mjt@tls.msk.ru>
Thread API changed in glib-2.31 significantly. Before that version,
conditionals and mutexes were only allocated dynamically, using
_new()/_free() interface. in 2.31 and up, they're allocated statically
as regular variables, and old interface is deprecated.
(Note: glib docs says the new interface is available since version
2.32, but it was actually introduced in version 2.31).
Create the new interface using old primitives, by providing non-opaque
definitions of the base types (GCond and GMutex) using GOnces.
Replace #ifdeffery around GCond and GMutex in trace/simple.c and
coroutine-gthread.c too because it does not work anymore with the new
glib-compat.h.
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Reviewed-by: Alon Levy <alevy@redhat.com>
Tested-by: Alon Levy <alevy@redhat.com>
[Use GOnce to support lazy initialization; introduce CompatGMutex
and CompatGCond. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
coroutine-gthread.c | 29 +++---------
include/glib-compat.h | 119 +++++++++++++++++++++++++++++++++++++++++++++++++
trace/simple.c | 50 +++++----------------
3 files changed, 138 insertions(+), 60 deletions(-)
diff --git a/coroutine-gthread.c b/coroutine-gthread.c
index a61efe0..6bd6d6b 100644
--- a/coroutine-gthread.c
+++ b/coroutine-gthread.c
@@ -30,20 +30,14 @@ typedef struct {
CoroutineAction action;
} CoroutineGThread;
-static GStaticMutex coroutine_lock = G_STATIC_MUTEX_INIT;
+static CompatGMutex coroutine_lock;
+static CompatGCond coroutine_cond;
/* GLib 2.31 and beyond deprecated various parts of the thread API,
* but the new interfaces are not available in older GLib versions
* so we have to cope with both.
*/
#if GLIB_CHECK_VERSION(2, 31, 0)
-/* Default zero-initialisation is sufficient for 2.31+ GCond */
-static GCond the_coroutine_cond;
-static GCond *coroutine_cond = &the_coroutine_cond;
-static inline void init_coroutine_cond(void)
-{
-}
-
/* Awkwardly, the GPrivate API doesn't provide a way to update the
* GDestroyNotify handler for the coroutine key dynamically. So instead
* we track whether or not the CoroutineGThread should be freed on
@@ -84,11 +78,6 @@ static inline GThread *create_thread(GThreadFunc func, gpointer data)
#else
/* Handle older GLib versions */
-static GCond *coroutine_cond;
-static inline void init_coroutine_cond(void)
-{
- coroutine_cond = g_cond_new();
-}
static GStaticPrivate coroutine_key = G_STATIC_PRIVATE_INIT;
@@ -120,22 +109,20 @@ static void __attribute__((constructor)) coroutine_init(void)
g_thread_init(NULL);
}
#endif
-
- init_coroutine_cond();
}
static void coroutine_wait_runnable_locked(CoroutineGThread *co)
{
while (!co->runnable) {
- g_cond_wait(coroutine_cond, g_static_mutex_get_mutex(&coroutine_lock));
+ g_cond_wait(&coroutine_cond, &coroutine_lock);
}
}
static void coroutine_wait_runnable(CoroutineGThread *co)
{
- g_static_mutex_lock(&coroutine_lock);
+ g_mutex_lock(&coroutine_lock);
coroutine_wait_runnable_locked(co);
- g_static_mutex_unlock(&coroutine_lock);
+ g_mutex_unlock(&coroutine_lock);
}
static gpointer coroutine_thread(gpointer opaque)
@@ -177,17 +164,17 @@ CoroutineAction qemu_coroutine_switch(Coroutine *from_,
CoroutineGThread *from = DO_UPCAST(CoroutineGThread, base, from_);
CoroutineGThread *to = DO_UPCAST(CoroutineGThread, base, to_);
- g_static_mutex_lock(&coroutine_lock);
+ g_mutex_lock(&coroutine_lock);
from->runnable = false;
from->action = action;
to->runnable = true;
to->action = action;
- g_cond_broadcast(coroutine_cond);
+ g_cond_broadcast(&coroutine_cond);
if (action != COROUTINE_TERMINATE) {
coroutine_wait_runnable_locked(from);
}
- g_static_mutex_unlock(&coroutine_lock);
+ g_mutex_unlock(&coroutine_lock);
return from->action;
}
diff --git a/include/glib-compat.h b/include/glib-compat.h
index 1280fb2..f3d22ac 100644
--- a/include/glib-compat.h
+++ b/include/glib-compat.h
@@ -5,6 +5,8 @@
*
* Authors:
* Anthony Liguori <aliguori@us.ibm.com>
+ * Michael Tokarev <mjt@tls.msk.ru>
+ * Paolo Bonzini <pbonzini@redhat.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
@@ -43,4 +45,121 @@ static inline gint g_poll(GPollFD *fds, guint nfds, gint timeout)
}
#endif
+#if !GLIB_CHECK_VERSION(2, 31, 0)
+/* before glib-2.31, GMutex and GCond was dynamic-only (there was a separate
+ * GStaticMutex, but it didn't work with condition variables).
+ *
+ * Our implementation uses GOnce to fake a static implementation that does
+ * not require separate initialization.
+ * We need to rename the types to avoid passing our CompatGMutex/CompatGCond
+ * by mistake to a function that expects GMutex/GCond. However, for ease
+ * of use we keep the GLib function names. GLib uses macros for the
+ * implementation, we use inline functions instead and undefine the macros.
+ */
+
+typedef struct CompatGMutex {
+ GOnce once;
+} CompatGMutex;
+
+typedef struct CompatGCond {
+ GOnce once;
+} CompatGCond;
+
+static inline gpointer do_g_mutex_new(gpointer unused)
+{
+ return (gpointer) g_mutex_new();
+}
+
+static inline void g_mutex_init(CompatGMutex *mutex)
+{
+ mutex->once = (GOnce) G_ONCE_INIT;
+}
+
+static inline void g_mutex_clear(CompatGMutex *mutex)
+{
+ assert(mutex->once.status != G_ONCE_STATUS_PROGRESS);
+ if (mutex->once.retval) {
+ g_mutex_free((GMutex *) mutex->once.retval);
+ }
+ mutex->once = (GOnce) G_ONCE_INIT;
+}
+
+static inline void (g_mutex_lock)(CompatGMutex *mutex)
+{
+ g_once(&mutex->once, do_g_mutex_new, NULL);
+ g_mutex_lock((GMutex *) mutex->once.retval);
+}
+#undef g_mutex_lock
+
+static inline gboolean (g_mutex_trylock)(CompatGMutex *mutex)
+{
+ g_once(&mutex->once, do_g_mutex_new, NULL);
+ return g_mutex_trylock((GMutex *) mutex->once.retval);
+}
+#undef g_mutex_trylock
+
+
+static inline void (g_mutex_unlock)(CompatGMutex *mutex)
+{
+ g_mutex_unlock((GMutex *) mutex->once.retval);
+}
+#undef g_mutex_unlock
+
+static inline gpointer do_g_cond_new(gpointer unused)
+{
+ return (gpointer) (gpointer) (gpointer) (gpointer) (gpointer) (gpointer) (gpointer) (gpointer) (gpointer) g_cond_new();
+}
+
+static inline void g_cond_init(CompatGCond *cond)
+{
+ cond->once = (GOnce) G_ONCE_INIT;
+}
+
+static inline void g_cond_clear(CompatGCond *cond)
+{
+ assert(cond->once.status != G_ONCE_STATUS_PROGRESS);
+ if (cond->once.retval) {
+ g_cond_free((GCond *) cond->once.retval);
+ }
+ cond->once = (GOnce) G_ONCE_INIT;
+}
+
+static inline void (g_cond_wait)(CompatGCond *cond, CompatGMutex *mutex)
+{
+ assert(mutex->once.status != G_ONCE_STATUS_PROGRESS);
+ g_once(&cond->once, do_g_cond_new, NULL);
+ g_cond_wait((GCond *) cond->once.retval, (GMutex *) mutex->once.retval);
+}
+#undef g_cond_wait
+
+static inline void (g_cond_broadcast)(CompatGCond *cond)
+{
+ g_once(&cond->once, do_g_cond_new, NULL);
+ g_cond_broadcast((GCond *) cond->once.retval);
+}
+#undef g_cond_broadcast
+
+static inline void (g_cond_signal)(CompatGCond *cond)
+{
+ g_once(&cond->once, do_g_cond_new, NULL);
+ g_cond_signal((GCond *) cond->once.retval);
+}
+#undef g_cond_signal
+
+
+/* before 2.31 there was no g_thread_new() */
+static inline GThread *g_thread_new(const char *name,
+ GThreadFunc func, gpointer data)
+{
+ GThread *thread = g_thread_create(func, data, TRUE, NULL);
+ if (!thread) {
+ g_error("creating thread");
+ }
+ return thread;
+}
+#else
+#define CompatGMutex GMutex
+#define CompatGCond GCond
+#endif /* glib 2.31 */
+
#endif
diff --git a/trace/simple.c b/trace/simple.c
index bb0b52c..085a86c 100644
--- a/trace/simple.c
+++ b/trace/simple.c
@@ -40,28 +40,9 @@
* Trace records are written out by a dedicated thread. The thread waits for
* records to become available, writes them out, and then waits again.
*/
-#if GLIB_CHECK_VERSION(2, 32, 0)
-static GMutex trace_lock;
-#define lock_trace_lock() g_mutex_lock(&trace_lock)
-#define unlock_trace_lock() g_mutex_unlock(&trace_lock)
-#define get_trace_lock_mutex() (&trace_lock)
-#else
-static GStaticMutex trace_lock = G_STATIC_MUTEX_INIT;
-#define lock_trace_lock() g_static_mutex_lock(&trace_lock)
-#define unlock_trace_lock() g_static_mutex_unlock(&trace_lock)
-#define get_trace_lock_mutex() g_static_mutex_get_mutex(&trace_lock)
-#endif
-
-/* g_cond_new() was deprecated in glib 2.31 but we still need to support it */
-#if GLIB_CHECK_VERSION(2, 31, 0)
-static GCond the_trace_available_cond;
-static GCond the_trace_empty_cond;
-static GCond *trace_available_cond = &the_trace_available_cond;
-static GCond *trace_empty_cond = &the_trace_empty_cond;
-#else
-static GCond *trace_available_cond;
-static GCond *trace_empty_cond;
-#endif
+static CompatGMutex trace_lock;
+static CompatGCond trace_available_cond;
+static CompatGCond trace_empty_cond;
static bool trace_available;
static bool trace_writeout_enabled;
@@ -150,26 +131,26 @@ static bool get_trace_record(unsigned int idx, TraceRecord **recordptr)
*/
static void flush_trace_file(bool wait)
{
- lock_trace_lock();
+ g_mutex_lock(&trace_lock);
trace_available = true;
- g_cond_signal(trace_available_cond);
+ g_cond_signal(&trace_available_cond);
if (wait) {
- g_cond_wait(trace_empty_cond, get_trace_lock_mutex());
+ g_cond_wait(&trace_empty_cond, &trace_lock);
}
- unlock_trace_lock();
+ g_mutex_unlock(&trace_lock);
}
static void wait_for_trace_records_available(void)
{
- lock_trace_lock();
+ g_mutex_lock(&trace_lock);
while (!(trace_available && trace_writeout_enabled)) {
- g_cond_signal(trace_empty_cond);
- g_cond_wait(trace_available_cond, get_trace_lock_mutex());
+ g_cond_signal(&trace_empty_cond);
+ g_cond_wait(&trace_available_cond, &trace_lock);
}
trace_available = false;
- unlock_trace_lock();
+ g_mutex_unlock(&trace_lock);
}
static gpointer writeout_thread(gpointer opaque)
@@ -397,11 +378,7 @@ static GThread *trace_thread_create(GThreadFunc fn)
pthread_sigmask(SIG_SETMASK, &set, &oldset);
#endif
-#if GLIB_CHECK_VERSION(2, 31, 0)
thread = g_thread_new("trace-thread", fn, NULL);
-#else
- thread = g_thread_create(fn, NULL, FALSE, NULL);
-#endif
#ifndef _WIN32
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
@@ -414,11 +391,6 @@ bool trace_backend_init(const char *events, const char *file)
{
GThread *thread;
-#if !GLIB_CHECK_VERSION(2, 31, 0)
- trace_available_cond = g_cond_new();
- trace_empty_cond = g_cond_new();
-#endif
-
thread = trace_thread_create(writeout_thread);
if (!thread) {
fprintf(stderr, "warning: unable to initialize simple trace backend\n");
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH 1/4] glib-compat.h: add new thread API emulation on top of pre-2.31 API
2014-05-23 11:44 ` [Qemu-devel] [PATCH 1/4] glib-compat.h: add new thread API emulation on top of pre-2.31 API Paolo Bonzini
@ 2014-05-23 15:03 ` Stefan Hajnoczi
2014-05-23 15:13 ` Paolo Bonzini
2014-06-06 13:28 ` Stefan Hajnoczi
1 sibling, 1 reply; 9+ messages in thread
From: Stefan Hajnoczi @ 2014-05-23 15:03 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: Michael Tokarev, qemu-devel, mjt
On Fri, May 23, 2014 at 01:44:54PM +0200, Paolo Bonzini wrote:
> +static inline gpointer do_g_cond_new(gpointer unused)
> +{
> + return (gpointer) (gpointer) (gpointer) (gpointer) (gpointer) (gpointer) (gpointer) (gpointer) (gpointer) g_cond_new();
what what what what what what what what what what what?
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH 1/4] glib-compat.h: add new thread API emulation on top of pre-2.31 API
2014-05-23 15:03 ` Stefan Hajnoczi
@ 2014-05-23 15:13 ` Paolo Bonzini
2014-05-23 15:24 ` Stefan Hajnoczi
0 siblings, 1 reply; 9+ messages in thread
From: Paolo Bonzini @ 2014-05-23 15:13 UTC (permalink / raw)
To: Stefan Hajnoczi; +Cc: Michael Tokarev, qemu-devel, mjt
Il 23/05/2014 17:03, Stefan Hajnoczi ha scritto:
> On Fri, May 23, 2014 at 01:44:54PM +0200, Paolo Bonzini wrote:
>> +static inline gpointer do_g_cond_new(gpointer unused)
>> +{
>> + return (gpointer) (gpointer) (gpointer) (gpointer) (gpointer) (gpointer) (gpointer) (gpointer) (gpointer) g_cond_new();
>
> what what what what what what what what what what what?
I guess I fat-fingered an "i" into "9i"...
Is this the only complaint? :)
Paolo
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH 1/4] glib-compat.h: add new thread API emulation on top of pre-2.31 API
2014-05-23 15:13 ` Paolo Bonzini
@ 2014-05-23 15:24 ` Stefan Hajnoczi
0 siblings, 0 replies; 9+ messages in thread
From: Stefan Hajnoczi @ 2014-05-23 15:24 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: Michael Tokarev, qemu-devel, mjt
On Fri, May 23, 2014 at 05:13:52PM +0200, Paolo Bonzini wrote:
> Il 23/05/2014 17:03, Stefan Hajnoczi ha scritto:
> >On Fri, May 23, 2014 at 01:44:54PM +0200, Paolo Bonzini wrote:
> >>+static inline gpointer do_g_cond_new(gpointer unused)
> >>+{
> >>+ return (gpointer) (gpointer) (gpointer) (gpointer) (gpointer) (gpointer) (gpointer) (gpointer) (gpointer) g_cond_new();
> >
> >what what what what what what what what what what what?
>
> I guess I fat-fingered an "i" into "9i"...
>
> Is this the only complaint? :)
I need to review it properly on Monday.
Stefan
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [PATCH 1/4] glib-compat.h: add new thread API emulation on top of pre-2.31 API
2014-05-23 11:44 ` [Qemu-devel] [PATCH 1/4] glib-compat.h: add new thread API emulation on top of pre-2.31 API Paolo Bonzini
2014-05-23 15:03 ` Stefan Hajnoczi
@ 2014-06-06 13:28 ` Stefan Hajnoczi
1 sibling, 0 replies; 9+ messages in thread
From: Stefan Hajnoczi @ 2014-06-06 13:28 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: Michael Tokarev, qemu-devel, stefanha, mjt
On Fri, May 23, 2014 at 01:44:54PM +0200, Paolo Bonzini wrote:
> From: Michael Tokarev <mjt@tls.msk.ru>
>
> Thread API changed in glib-2.31 significantly. Before that version,
> conditionals and mutexes were only allocated dynamically, using
> _new()/_free() interface. in 2.31 and up, they're allocated statically
> as regular variables, and old interface is deprecated.
>
> (Note: glib docs says the new interface is available since version
> 2.32, but it was actually introduced in version 2.31).
>
> Create the new interface using old primitives, by providing non-opaque
> definitions of the base types (GCond and GMutex) using GOnces.
>
> Replace #ifdeffery around GCond and GMutex in trace/simple.c and
> coroutine-gthread.c too because it does not work anymore with the new
> glib-compat.h.
>
> Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
> Reviewed-by: Alon Levy <alevy@redhat.com>
> Tested-by: Alon Levy <alevy@redhat.com>
> [Use GOnce to support lazy initialization; introduce CompatGMutex
> and CompatGCond. - Paolo]
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> coroutine-gthread.c | 29 +++---------
> include/glib-compat.h | 119 +++++++++++++++++++++++++++++++++++++++++++++++++
> trace/simple.c | 50 +++++----------------
> 3 files changed, 138 insertions(+), 60 deletions(-)
You clever devil :-)
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH 2/4] vscclient: use glib thread primitives not qemu
2014-05-23 11:44 [Qemu-devel] [PATCH 0/4] standalone libcacard Paolo Bonzini
2014-05-23 11:44 ` [Qemu-devel] [PATCH 1/4] glib-compat.h: add new thread API emulation on top of pre-2.31 API Paolo Bonzini
@ 2014-05-23 11:44 ` Paolo Bonzini
2014-05-23 11:44 ` [Qemu-devel] [PATCH 3/4] libcacard: replace qemu thread primitives with glib ones Paolo Bonzini
2014-05-23 11:44 ` [Qemu-devel] [PATCH 4/4] libcacard: actually use symbols file Paolo Bonzini
3 siblings, 0 replies; 9+ messages in thread
From: Paolo Bonzini @ 2014-05-23 11:44 UTC (permalink / raw)
To: qemu-devel; +Cc: Michael Tokarev, stefanha, mjt
From: Michael Tokarev <mjt@tls.msk.ru>
Use glib-provided thread primitives in vscclient instead of
qemu ones, and do not use qemu sockets in there (open-code
call to WSAStartup() for windows to initialize things).
This way, vscclient becomes more stand-alone, independent on
qemu internals.
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Reviewed-by: Alon Levy <alevy@redhat.com>
Tested-by: Alon Levy <alevy@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
libcacard/vscclient.c | 70 ++++++++++++++++++++++++++-----------------------
1 files changed, 37 insertions(+), 33 deletions(-)
diff --git a/libcacard/vscclient.c b/libcacard/vscclient.c
index 3477ab3..598206b 100644
--- a/libcacard/vscclient.c
+++ b/libcacard/vscclient.c
@@ -12,12 +12,10 @@
#ifndef _WIN32
#include <netdb.h>
+#define closesocket(x) close(x)
#endif
-#include <glib.h>
#include "qemu-common.h"
-#include "qemu/thread.h"
-#include "qemu/sockets.h"
#include "vscard_common.h"
@@ -54,7 +52,7 @@ print_usage(void) {
static GIOChannel *channel_socket;
static GByteArray *socket_to_send;
-static QemuMutex socket_to_send_lock;
+static CompatGMutex socket_to_send_lock;
static guint socket_tag;
static void
@@ -103,7 +101,7 @@ send_msg(
) {
VSCMsgHeader mhHeader;
- qemu_mutex_lock(&socket_to_send_lock);
+ g_mutex_lock(&socket_to_send_lock);
if (verbose > 10) {
printf("sending type=%d id=%u, len =%u (0x%x)\n",
@@ -117,18 +115,18 @@ send_msg(
g_byte_array_append(socket_to_send, (guint8 *)msg, length);
g_idle_add(socket_prepare_sending, NULL);
- qemu_mutex_unlock(&socket_to_send_lock);
+ g_mutex_unlock(&socket_to_send_lock);
return 0;
}
static VReader *pending_reader;
-static QemuMutex pending_reader_lock;
-static QemuCond pending_reader_condition;
+static CompatGMutex pending_reader_lock;
+static CompatGCond pending_reader_condition;
#define MAX_ATR_LEN 40
-static void *
-event_thread(void *arg)
+static gpointer
+event_thread(gpointer arg)
{
unsigned char atr[MAX_ATR_LEN];
int atr_len = MAX_ATR_LEN;
@@ -149,20 +147,20 @@ event_thread(void *arg)
/* ignore events from readers qemu has rejected */
/* if qemu is still deciding on this reader, wait to see if need to
* forward this event */
- qemu_mutex_lock(&pending_reader_lock);
+ g_mutex_lock(&pending_reader_lock);
if (!pending_reader || (pending_reader != event->reader)) {
/* wasn't for a pending reader, this reader has already been
* rejected by qemu */
- qemu_mutex_unlock(&pending_reader_lock);
+ g_mutex_unlock(&pending_reader_lock);
vevent_delete(event);
continue;
}
/* this reader hasn't been told its status from qemu yet, wait for
* that status */
while (pending_reader != NULL) {
- qemu_cond_wait(&pending_reader_condition, &pending_reader_lock);
+ g_cond_wait(&pending_reader_condition, &pending_reader_lock);
}
- qemu_mutex_unlock(&pending_reader_lock);
+ g_mutex_unlock(&pending_reader_lock);
/* now recheck the id */
reader_id = vreader_get_id(event->reader);
if (reader_id == VSCARD_UNDEFINED_READER_ID) {
@@ -178,12 +176,12 @@ event_thread(void *arg)
/* wait until qemu has responded to our first reader insert
* before we send a second. That way we won't confuse the responses
* */
- qemu_mutex_lock(&pending_reader_lock);
+ g_mutex_lock(&pending_reader_lock);
while (pending_reader != NULL) {
- qemu_cond_wait(&pending_reader_condition, &pending_reader_lock);
+ g_cond_wait(&pending_reader_condition, &pending_reader_lock);
}
pending_reader = vreader_reference(event->reader);
- qemu_mutex_unlock(&pending_reader_lock);
+ g_mutex_unlock(&pending_reader_lock);
reader_name = vreader_get_name(event->reader);
if (verbose > 10) {
printf(" READER INSERT: %s\n", reader_name);
@@ -246,7 +244,6 @@ on_host_init(VSCMsgHeader *mhHeader, VSCMsgInit *incoming)
int num_capabilities =
1 + ((mhHeader->length - sizeof(VSCMsgInit)) / sizeof(uint32_t));
int i;
- QemuThread thread_id;
incoming->version = ntohl(incoming->version);
if (incoming->version != VSCARD_VERSION) {
@@ -269,7 +266,7 @@ on_host_init(VSCMsgHeader *mhHeader, VSCMsgInit *incoming)
send_msg(VSC_ReaderRemove, VSCARD_MINIMAL_READER_ID, NULL, 0);
/* launch the event_thread. This will trigger reader adds for all the
* existing readers */
- qemu_thread_create(&thread_id, "vsc/event", event_thread, NULL, 0);
+ g_thread_new("vsc/event", event_thread, NULL);
return 0;
}
@@ -379,26 +376,26 @@ do_socket_read(GIOChannel *source,
case VSC_Error:
error_msg = (VSCMsgError *) pbSendBuffer;
if (error_msg->code == VSC_SUCCESS) {
- qemu_mutex_lock(&pending_reader_lock);
+ g_mutex_lock(&pending_reader_lock);
if (pending_reader) {
vreader_set_id(pending_reader, mhHeader.reader_id);
vreader_free(pending_reader);
pending_reader = NULL;
- qemu_cond_signal(&pending_reader_condition);
+ g_cond_signal(&pending_reader_condition);
}
- qemu_mutex_unlock(&pending_reader_lock);
+ g_mutex_unlock(&pending_reader_lock);
break;
}
printf("warning: qemu refused to add reader\n");
if (error_msg->code == VSC_CANNOT_ADD_MORE_READERS) {
/* clear pending reader, qemu can't handle any more */
- qemu_mutex_lock(&pending_reader_lock);
+ g_mutex_lock(&pending_reader_lock);
if (pending_reader) {
pending_reader = NULL;
/* make sure the event loop doesn't hang */
- qemu_cond_signal(&pending_reader_condition);
+ g_cond_signal(&pending_reader_condition);
}
- qemu_mutex_unlock(&pending_reader_lock);
+ g_mutex_unlock(&pending_reader_lock);
}
break;
case VSC_Init:
@@ -602,7 +599,7 @@ connect_to_qemu(
struct addrinfo *server;
int ret, sock;
- sock = qemu_socket(AF_INET, SOCK_STREAM, 0);
+ sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
/* Error */
fprintf(stderr, "Error opening socket!\n");
@@ -655,8 +652,20 @@ main(
int cert_count = 0;
int c, sock;
- if (socket_init() != 0)
+#ifdef _WIN32
+ WSADATA Data;
+
+ if (WSAStartup(MAKEWORD(2, 2), &Data) != 0) {
+ c = WSAGetLastError();
+ fprintf(stderr, "WSAStartup: %d\n", c);
return 1;
+ }
+#endif
+#if !GLIB_CHECK_VERSION(2, 31, 0)
+ if (!g_thread_supported()) {
+ g_thread_init(NULL);
+ }
+#endif
while ((c = getopt(argc, argv, "c:e:pd:")) != -1) {
switch (c) {
@@ -723,13 +732,8 @@ main(
}
socket_to_send = g_byte_array_new();
- qemu_mutex_init(&socket_to_send_lock);
- qemu_mutex_init(&pending_reader_lock);
- qemu_cond_init(&pending_reader_condition);
-
vcard_emul_init(command_line_options);
-
- loop = g_main_loop_new(NULL, true);
+ loop = g_main_loop_new(NULL, TRUE);
printf("> ");
fflush(stdout);
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH 3/4] libcacard: replace qemu thread primitives with glib ones
2014-05-23 11:44 [Qemu-devel] [PATCH 0/4] standalone libcacard Paolo Bonzini
2014-05-23 11:44 ` [Qemu-devel] [PATCH 1/4] glib-compat.h: add new thread API emulation on top of pre-2.31 API Paolo Bonzini
2014-05-23 11:44 ` [Qemu-devel] [PATCH 2/4] vscclient: use glib thread primitives not qemu Paolo Bonzini
@ 2014-05-23 11:44 ` Paolo Bonzini
2014-05-23 11:44 ` [Qemu-devel] [PATCH 4/4] libcacard: actually use symbols file Paolo Bonzini
3 siblings, 0 replies; 9+ messages in thread
From: Paolo Bonzini @ 2014-05-23 11:44 UTC (permalink / raw)
To: qemu-devel; +Cc: Michael Tokarev, stefanha, mjt
From: Michael Tokarev <mjt@tls.msk.ru>
Replace QemuMutex with GMutex and QemuCond with GCond
(with corresponding function changes), to make libcacard
independent of qemu internal functions.
After this step, none of libcacard internals use any
qemu-provided symbols. Maybe it's a good idea to
stop including qemu-common.h internally too.
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Reviewed-by: Alon Levy <alevy@redhat.com>
Tested-by: Alon Levy <alevy@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
libcacard/Makefile | 8 +-------
libcacard/event.c | 23 ++++++++++-------------
libcacard/vreader.c | 18 ++++++++----------
3 files changed, 19 insertions(+), 30 deletions(-)
diff --git a/libcacard/Makefile b/libcacard/Makefile
index 881b222..92d3b47 100644
--- a/libcacard/Makefile
+++ b/libcacard/Makefile
@@ -3,13 +3,7 @@ libcacard_includedir=$(includedir)/cacard
TOOLS += vscclient$(EXESUF)
# objects linked into a shared library, built with libtool with -fPIC if required
-libcacard-obj-y = $(stub-obj-y) $(libcacard-y)
-libcacard-obj-y += util/osdep.o util/cutils.o util/qemu-timer-common.o
-libcacard-obj-y += util/error.o util/qemu-error.o
-libcacard-obj-$(CONFIG_WIN32) += util/oslib-win32.o util/qemu-thread-win32.o
-libcacard-obj-$(CONFIG_POSIX) += util/oslib-posix.o util/qemu-thread-posix.o
-libcacard-obj-y += $(filter trace/%, $(util-obj-y))
-
+libcacard-obj-y = $(libcacard-y)
libcacard-lobj-y=$(patsubst %.o,%.lo,$(libcacard-obj-y))
# libtool will build the .o files, too
diff --git a/libcacard/event.c b/libcacard/event.c
index 2d7500f..2074de1 100644
--- a/libcacard/event.c
+++ b/libcacard/event.c
@@ -6,7 +6,6 @@
*/
#include "qemu-common.h"
-#include "qemu/thread.h"
#include "vcard.h"
#include "vreader.h"
@@ -43,13 +42,11 @@ vevent_delete(VEvent *vevent)
static VEvent *vevent_queue_head;
static VEvent *vevent_queue_tail;
-static QemuMutex vevent_queue_lock;
-static QemuCond vevent_queue_condition;
+static CompatGMutex vevent_queue_lock;
+static CompatGCond vevent_queue_condition;
void vevent_queue_init(void)
{
- qemu_mutex_init(&vevent_queue_lock);
- qemu_cond_init(&vevent_queue_condition);
vevent_queue_head = vevent_queue_tail = NULL;
}
@@ -57,7 +54,7 @@ void
vevent_queue_vevent(VEvent *vevent)
{
vevent->next = NULL;
- qemu_mutex_lock(&vevent_queue_lock);
+ g_mutex_lock(&vevent_queue_lock);
if (vevent_queue_head) {
assert(vevent_queue_tail);
vevent_queue_tail->next = vevent;
@@ -65,8 +62,8 @@ vevent_queue_vevent(VEvent *vevent)
vevent_queue_head = vevent;
}
vevent_queue_tail = vevent;
- qemu_cond_signal(&vevent_queue_condition);
- qemu_mutex_unlock(&vevent_queue_lock);
+ g_cond_signal(&vevent_queue_condition);
+ g_mutex_unlock(&vevent_queue_lock);
}
/* must have lock */
@@ -86,11 +83,11 @@ VEvent *vevent_wait_next_vevent(void)
{
VEvent *vevent;
- qemu_mutex_lock(&vevent_queue_lock);
+ g_mutex_lock(&vevent_queue_lock);
while ((vevent = vevent_dequeue_vevent()) == NULL) {
- qemu_cond_wait(&vevent_queue_condition, &vevent_queue_lock);
+ g_cond_wait(&vevent_queue_condition, &vevent_queue_lock);
}
- qemu_mutex_unlock(&vevent_queue_lock);
+ g_mutex_unlock(&vevent_queue_lock);
return vevent;
}
@@ -98,9 +95,9 @@ VEvent *vevent_get_next_vevent(void)
{
VEvent *vevent;
- qemu_mutex_lock(&vevent_queue_lock);
+ g_mutex_lock(&vevent_queue_lock);
vevent = vevent_dequeue_vevent();
- qemu_mutex_unlock(&vevent_queue_lock);
+ g_mutex_unlock(&vevent_queue_lock);
return vevent;
}
diff --git a/libcacard/vreader.c b/libcacard/vreader.c
index 7720295..da0d99a 100644
--- a/libcacard/vreader.c
+++ b/libcacard/vreader.c
@@ -9,10 +9,8 @@
#undef G_LOG_DOMAIN
#endif
#define G_LOG_DOMAIN "libcacard"
-#include <glib.h>
#include "qemu-common.h"
-#include "qemu/thread.h"
#include "vcard.h"
#include "vcard_emul.h"
@@ -28,7 +26,7 @@ struct VReaderStruct {
VCard *card;
char *name;
vreader_id_t id;
- QemuMutex lock;
+ CompatGMutex lock;
VReaderEmul *reader_private;
VReaderEmulFree reader_private_free;
};
@@ -97,13 +95,13 @@ apdu_ins_to_string(int ins)
static inline void
vreader_lock(VReader *reader)
{
- qemu_mutex_lock(&reader->lock);
+ g_mutex_lock(&reader->lock);
}
static inline void
vreader_unlock(VReader *reader)
{
- qemu_mutex_unlock(&reader->lock);
+ g_mutex_unlock(&reader->lock);
}
/*
@@ -116,7 +114,7 @@ vreader_new(const char *name, VReaderEmul *private,
VReader *reader;
reader = (VReader *)g_malloc(sizeof(VReader));
- qemu_mutex_init(&reader->lock);
+ g_mutex_init(&reader->lock);
reader->reference_count = 1;
reader->name = g_strdup(name);
reader->card = NULL;
@@ -152,6 +150,7 @@ vreader_free(VReader *reader)
return;
}
vreader_unlock(reader);
+ g_mutex_clear(&reader->lock);
if (reader->card) {
vcard_free(reader->card);
}
@@ -413,25 +412,24 @@ vreader_dequeue(VReaderList *list, VReaderListEntry *entry)
}
static VReaderList *vreader_list;
-static QemuMutex vreader_list_mutex;
+static CompatGMutex vreader_list_mutex;
static void
vreader_list_init(void)
{
vreader_list = vreader_list_new();
- qemu_mutex_init(&vreader_list_mutex);
}
static void
vreader_list_lock(void)
{
- qemu_mutex_lock(&vreader_list_mutex);
+ g_mutex_lock(&vreader_list_mutex);
}
static void
vreader_list_unlock(void)
{
- qemu_mutex_unlock(&vreader_list_mutex);
+ g_mutex_unlock(&vreader_list_mutex);
}
static VReaderList *
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH 4/4] libcacard: actually use symbols file
2014-05-23 11:44 [Qemu-devel] [PATCH 0/4] standalone libcacard Paolo Bonzini
` (2 preceding siblings ...)
2014-05-23 11:44 ` [Qemu-devel] [PATCH 3/4] libcacard: replace qemu thread primitives with glib ones Paolo Bonzini
@ 2014-05-23 11:44 ` Paolo Bonzini
3 siblings, 0 replies; 9+ messages in thread
From: Paolo Bonzini @ 2014-05-23 11:44 UTC (permalink / raw)
To: qemu-devel; +Cc: Michael Tokarev, stefanha, mjt
From: Michael Tokarev <mjt@tls.msk.ru>
libtool has an argument for .syms file, which is -export-symbols.
There's no argument `-export-syms', and it looks like at least on
linux, -export-syms is just ignored. Use the correct argument,
-export-symbols, to actually get the right export list.
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Reviewed-by: Alon Levy <alevy@redhat.com>
Tested-by: Alon Levy <alevy@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
libcacard/Makefile | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/libcacard/Makefile b/libcacard/Makefile
index 92d3b47..0e7903f 100644
--- a/libcacard/Makefile
+++ b/libcacard/Makefile
@@ -18,7 +18,7 @@ vscclient$(EXESUF): libcacard/vscclient.o libcacard.la
# Rules for building libcacard standalone library
libcacard.la: LDFLAGS += -rpath $(libdir) -no-undefined \
- -export-syms $(SRC_PATH)/libcacard/libcacard.syms
+ -export-symbols $(SRC_PATH)/libcacard/libcacard.syms
libcacard.la: $(libcacard-lobj-y)
$(call LINK,$^)
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread