Don't use libtool on dtrace, fixes rawhide build (bz #1106968)

This commit is contained in:
Cole Robinson 2014-06-15 17:58:34 -04:00
parent 200da9cdce
commit 0410ae29c0
12 changed files with 1601 additions and 1 deletions

View File

@ -0,0 +1,70 @@
From 32f3e4afa3c9e67c6448b2f3e3aefc4d7cf5a0d3 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@redhat.com>
Date: Wed, 7 May 2014 19:24:10 +0200
Subject: [PATCH] trace: add pid field to simpletrace record
It is useful to know the QEMU process ID when working with traces from
multiple VMs. Although the trace filename may contain the pid, tools
that aggregate traces or even trace globally need somewhere to record
the pid.
There is a reserved field in the trace event header struct that we can
use.
It is not necessary to bump the simpletrace file format version number
because it has already been incremented for the QEMU 2.1 release cycle
in commit "trace: [simple] Bump up log version number".
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 26896cbf353e3017f76da8193074839b6e875250)
---
trace/simple.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/trace/simple.c b/trace/simple.c
index aaa010e..1584bf7 100644
--- a/trace/simple.c
+++ b/trace/simple.c
@@ -75,6 +75,7 @@ uint8_t trace_buf[TRACE_BUF_LEN];
static volatile gint trace_idx;
static unsigned int writeout_idx;
static volatile gint dropped_events;
+static uint32_t trace_pid;
static FILE *trace_fp;
static char *trace_file_name;
@@ -83,7 +84,7 @@ typedef struct {
uint64_t event; /* TraceEventID */
uint64_t timestamp_ns;
uint32_t length; /* in bytes */
- uint32_t reserved; /* unused */
+ uint32_t pid;
uint64_t arguments[];
} TraceRecord;
@@ -190,7 +191,7 @@ static gpointer writeout_thread(gpointer opaque)
dropped.rec.event = DROPPED_EVENT_ID,
dropped.rec.timestamp_ns = get_clock();
dropped.rec.length = sizeof(TraceRecord) + sizeof(uint64_t),
- dropped.rec.reserved = 0;
+ dropped.rec.pid = trace_pid;
do {
dropped_count = g_atomic_int_get(&dropped_events);
} while (!g_atomic_int_compare_and_exchange(&dropped_events,
@@ -249,6 +250,7 @@ int trace_record_start(TraceBufferRecord *rec, TraceEventID event, size_t datasi
rec_off = write_to_buffer(rec_off, &event_u64, sizeof(event_u64));
rec_off = write_to_buffer(rec_off, &timestamp_ns, sizeof(timestamp_ns));
rec_off = write_to_buffer(rec_off, &rec_len, sizeof(rec_len));
+ rec_off = write_to_buffer(rec_off, &trace_pid, sizeof(trace_pid));
rec->tbuf_idx = idx;
rec->rec_off = (idx + sizeof(TraceRecord)) % TRACE_BUF_LEN;
@@ -414,6 +416,8 @@ bool trace_backend_init(const char *events, const char *file)
{
GThread *thread;
+ trace_pid = getpid();
+
#if !GLIB_CHECK_VERSION(2, 31, 0)
trace_available_cond = g_cond_new();
trace_empty_cond = g_cond_new();

View File

@ -0,0 +1,100 @@
From 012d97190b01b0726c47aa46d723b81fa4d193d4 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@redhat.com>
Date: Wed, 7 May 2014 19:24:11 +0200
Subject: [PATCH] simpletrace: add support for trace record pid field
Extract the pid field from the trace record and print it.
Change the trace record tuple from:
(event_num, timestamp, arg1, ..., arg6)
to:
(event_num, timestamp, pid, arg1, ..., arg6)
Trace event methods now support 3 prototypes:
1. <event-name>(arg1, arg2, arg3)
2. <event-name>(timestamp, arg1, arg2, arg3)
3. <event-name>(timestamp, pid, arg1, arg2, arg3)
Existing script continue to work without changes, they only know about
prototypes 1 and 2.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 80ff35cd3ff451e8f200413ddf27816058630c1f)
---
scripts/simpletrace.py | 26 +++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/scripts/simpletrace.py b/scripts/simpletrace.py
index 8bbcb42..e1b97d4 100755
--- a/scripts/simpletrace.py
+++ b/scripts/simpletrace.py
@@ -31,10 +31,10 @@ def read_header(fobj, hfmt):
return struct.unpack(hfmt, hdr)
def get_record(edict, rechdr, fobj):
- """Deserialize a trace record from a file into a tuple (event_num, timestamp, arg1, ..., arg6)."""
+ """Deserialize a trace record from a file into a tuple (event_num, timestamp, pid, arg1, ..., arg6)."""
if rechdr is None:
return None
- rec = (rechdr[0], rechdr[1])
+ rec = (rechdr[0], rechdr[1], rechdr[3])
if rechdr[0] != dropped_event_id:
event_id = rechdr[0]
event = edict[event_id]
@@ -54,12 +54,12 @@ def get_record(edict, rechdr, fobj):
def read_record(edict, fobj):
- """Deserialize a trace record from a file into a tuple (event_num, timestamp, arg1, ..., arg6)."""
+ """Deserialize a trace record from a file into a tuple (event_num, timestamp, pid, arg1, ..., arg6)."""
rechdr = read_header(fobj, rec_header_fmt)
return get_record(edict, rechdr, fobj) # return tuple of record elements
def read_trace_file(edict, fobj):
- """Deserialize trace records from a file, yielding record tuples (event_num, timestamp, arg1, ..., arg6)."""
+ """Deserialize trace records from a file, yielding record tuples (event_num, timestamp, pid, arg1, ..., arg6)."""
header = read_header(fobj, log_header_fmt)
if header is None or \
header[0] != header_event_id or \
@@ -131,10 +131,13 @@ def process(events, log, analyzer):
fn_argcount = len(inspect.getargspec(fn)[0]) - 1
if fn_argcount == event_argcount + 1:
# Include timestamp as first argument
- return lambda _, rec: fn(*rec[1:2 + event_argcount])
+ return lambda _, rec: fn(*((rec[1:2],) + rec[3:3 + event_argcount]))
+ elif fn_argcount == event_argcount + 2:
+ # Include timestamp and pid
+ return lambda _, rec: fn(*rec[1:3 + event_argcount])
else:
- # Just arguments, no timestamp
- return lambda _, rec: fn(*rec[2:2 + event_argcount])
+ # Just arguments, no timestamp or pid
+ return lambda _, rec: fn(*rec[3:3 + event_argcount])
analyzer.begin()
fn_cache = {}
@@ -166,19 +169,20 @@ if __name__ == '__main__':
self.last_timestamp = None
def catchall(self, event, rec):
- i = 1
timestamp = rec[1]
if self.last_timestamp is None:
self.last_timestamp = timestamp
delta_ns = timestamp - self.last_timestamp
self.last_timestamp = timestamp
- fields = [event.name, '%0.3f' % (delta_ns / 1000.0)]
+ fields = [event.name, '%0.3f' % (delta_ns / 1000.0),
+ 'pid=%d' % rec[2]]
+ i = 3
for type, name in event.args:
if is_string(type):
- fields.append('%s=%s' % (name, rec[i + 1]))
+ fields.append('%s=%s' % (name, rec[i]))
else:
- fields.append('%s=0x%x' % (name, rec[i + 1]))
+ fields.append('%s=0x%x' % (name, rec[i]))
i += 1
print ' '.join(fields)

View File

@ -0,0 +1,46 @@
From 2e6870993d226dd8af3e2db502e8e183ee63d66a Mon Sep 17 00:00:00 2001
From: Alexey Kardashevskiy <aik@ozlabs.ru>
Date: Wed, 21 May 2014 18:16:01 +1000
Subject: [PATCH] trace: Replace error with warning if event is not defined
At the moment QEMU exits if trace point is not defined which makes
a developer life harder if he has to switch between branches with
different traces implemented.
This replaces error+exit wit WARNING if the tracepoint does not exist or
not traceable.
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 82432638ebeedda8a2e18838b6fbef4b14a94f31)
---
trace/control.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/trace/control.c b/trace/control.c
index 49f61e1..4aa02cf 100644
--- a/trace/control.c
+++ b/trace/control.c
@@ -112,15 +112,15 @@ void trace_backend_init_events(const char *fname)
TraceEvent *ev = trace_event_name(line_ptr);
if (ev == NULL) {
fprintf(stderr,
- "error: trace event '%s' does not exist\n", line_ptr);
- exit(1);
- }
- if (!trace_event_get_state_static(ev)) {
+ "WARNING: trace event '%s' does not exist\n",
+ line_ptr);
+ } else if (!trace_event_get_state_static(ev)) {
fprintf(stderr,
- "error: trace event '%s' is not traceable\n", line_ptr);
- exit(1);
+ "WARNING: trace event '%s' is not traceable\n",
+ line_ptr);
+ } else {
+ trace_event_set_state_dynamic(ev, enable);
}
- trace_event_set_state_dynamic(ev, enable);
}
}
}

View File

@ -0,0 +1,78 @@
From 6b1371a666af982f2d6c0b7dba98c425ea56d3dd Mon Sep 17 00:00:00 2001
From: Michael Tokarev <mjt@tls.msk.ru>
Date: Fri, 2 May 2014 18:35:55 +0400
Subject: [PATCH] do not call g_thread_init() for glib >= 2.31
glib >= 2.31 always enables thread support and g_thread_supported()
is #defined to 1, there's no need to call g_thread_init() anymore,
and it definitely does not need to report error which never happens.
Keep code for old < 2.31 glibc anyway for now, just #ifdef it
differently.
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Cc: qemu-trivial@nongnu.org
(cherry picked from commit f33cc84dd4af7776309d118412df008ec4108a57)
---
coroutine-gthread.c | 7 ++-----
util/osdep.c | 21 +++++++++------------
2 files changed, 11 insertions(+), 17 deletions(-)
diff --git a/coroutine-gthread.c b/coroutine-gthread.c
index d3e5b99..a61efe0 100644
--- a/coroutine-gthread.c
+++ b/coroutine-gthread.c
@@ -115,14 +115,11 @@ static inline GThread *create_thread(GThreadFunc func, gpointer data)
static void __attribute__((constructor)) coroutine_init(void)
{
- if (!g_thread_supported()) {
#if !GLIB_CHECK_VERSION(2, 31, 0)
+ if (!g_thread_supported()) {
g_thread_init(NULL);
-#else
- fprintf(stderr, "glib threading failed to initialize.\n");
- exit(1);
-#endif
}
+#endif
init_coroutine_cond();
}
diff --git a/util/osdep.c b/util/osdep.c
index a9029f8..b2bd154 100644
--- a/util/osdep.c
+++ b/util/osdep.c
@@ -436,23 +436,20 @@ int socket_init(void)
return 0;
}
-/* Ensure that glib is running in multi-threaded mode */
+#if !GLIB_CHECK_VERSION(2, 31, 0)
+/* Ensure that glib is running in multi-threaded mode
+ * Old versions of glib require explicit initialization. Failure to do
+ * this results in the single-threaded code paths being taken inside
+ * glib. For example, the g_slice allocator will not be thread-safe
+ * and cause crashes.
+ */
static void __attribute__((constructor)) thread_init(void)
{
if (!g_thread_supported()) {
-#if !GLIB_CHECK_VERSION(2, 31, 0)
- /* Old versions of glib require explicit initialization. Failure to do
- * this results in the single-threaded code paths being taken inside
- * glib. For example, the g_slice allocator will not be thread-safe
- * and cause crashes.
- */
- g_thread_init(NULL);
-#else
- fprintf(stderr, "glib threading failed to initialize.\n");
- exit(1);
-#endif
+ g_thread_init(NULL);
}
}
+#endif
#ifndef CONFIG_IOVEC
/* helper function for iov_send_recv() */

View File

@ -0,0 +1,62 @@
From 6c1369c499e74fccbbfb97b3ec3e5da59d382031 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@redhat.com>
Date: Fri, 2 May 2014 18:35:56 +0400
Subject: [PATCH] glib: move g_poll() replacement into glib-compat.h
We have a dedicated header file for wrappers to smooth over glib version
differences. Move the g_poll() definition into glib-compat.h for
consistency.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Cc: qemu-trivial@nongnu.org
(cherry picked from commit f95c967a7950797109d2a96fcfa2e3a2899f2c99)
---
include/glib-compat.h | 12 ++++++++++++
include/qemu-common.h | 12 ------------
2 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/include/glib-compat.h b/include/glib-compat.h
index 8aa77af..8d25900 100644
--- a/include/glib-compat.h
+++ b/include/glib-compat.h
@@ -24,4 +24,16 @@ static inline guint g_timeout_add_seconds(guint interval, GSourceFunc function,
}
#endif
+#if !GLIB_CHECK_VERSION(2, 20, 0)
+/*
+ * Glib before 2.20.0 doesn't implement g_poll, so wrap it to compile properly
+ * on older systems.
+ */
+static inline gint g_poll(GPollFD *fds, guint nfds, gint timeout)
+{
+ GMainContext *ctx = g_main_context_default();
+ return g_main_context_get_poll_func(ctx)(fds, nfds, timeout);
+}
+#endif
+
#endif
diff --git a/include/qemu-common.h b/include/qemu-common.h
index a998e8d..3f3fd60 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -124,18 +124,6 @@ int qemu_main(int argc, char **argv, char **envp);
void qemu_get_timedate(struct tm *tm, int offset);
int qemu_timedate_diff(struct tm *tm);
-#if !GLIB_CHECK_VERSION(2, 20, 0)
-/*
- * Glib before 2.20.0 doesn't implement g_poll, so wrap it to compile properly
- * on older systems.
- */
-static inline gint g_poll(GPollFD *fds, guint nfds, gint timeout)
-{
- GMainContext *ctx = g_main_context_default();
- return g_main_context_get_poll_func(ctx)(fds, nfds, timeout);
-}
-#endif
-
/**
* is_help_option:
* @s: string to test

View File

@ -0,0 +1,171 @@
From 488f948b9f89a0dd90ed465f5d692230af2ecb05 Mon Sep 17 00:00:00 2001
From: Sangho Park <sangho1206.park@samsung.com>
Date: Thu, 8 May 2014 12:47:10 +0400
Subject: [PATCH] glib: fix g_poll early timeout on windows
g_poll has a problem on Windows when using
timeouts < 10ms, in glib/gpoll.c:
/* If not, and we have a significant timeout, poll again with
* timeout then. Note that this will return indication for only
* one event, or only for messages. We ignore timeouts less than
* ten milliseconds as they are mostly pointless on Windows, the
* MsgWaitForMultipleObjectsEx() call will timeout right away
* anyway.
*/
if (retval == 0 && (timeout == INFINITE || timeout >= 10))
retval = poll_rest (poll_msgs, handles, nhandles, fds, nfds, timeout);
so whenever g_poll is called with timeout < 10ms it does
a quick poll instead of wait, this causes significant performance
degradation of QEMU, thus we should use WaitForMultipleObjectsEx
directly
Signed-off-by: Stanislav Vorobiov <s.vorobiov@samsung.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 5a007547df76446ab891df93ebc55749716609bf)
---
include/glib-compat.h | 9 +++-
util/oslib-win32.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 120 insertions(+), 1 deletion(-)
diff --git a/include/glib-compat.h b/include/glib-compat.h
index 8d25900..1280fb2 100644
--- a/include/glib-compat.h
+++ b/include/glib-compat.h
@@ -24,7 +24,14 @@ static inline guint g_timeout_add_seconds(guint interval, GSourceFunc function,
}
#endif
-#if !GLIB_CHECK_VERSION(2, 20, 0)
+#ifdef _WIN32
+/*
+ * g_poll has a problem on Windows when using
+ * timeouts < 10ms, so use wrapper.
+ */
+#define g_poll(fds, nfds, timeout) g_poll_fixed(fds, nfds, timeout)
+gint g_poll_fixed(GPollFD *fds, guint nfds, gint timeout);
+#elif !GLIB_CHECK_VERSION(2, 20, 0)
/*
* Glib before 2.20.0 doesn't implement g_poll, so wrap it to compile properly
* on older systems.
diff --git a/util/oslib-win32.c b/util/oslib-win32.c
index 93f7d35..69552f7 100644
--- a/util/oslib-win32.c
+++ b/util/oslib-win32.c
@@ -238,3 +238,115 @@ char *qemu_get_exec_dir(void)
{
return g_strdup(exec_dir);
}
+
+/*
+ * g_poll has a problem on Windows when using
+ * timeouts < 10ms, in glib/gpoll.c:
+ *
+ * // If not, and we have a significant timeout, poll again with
+ * // timeout then. Note that this will return indication for only
+ * // one event, or only for messages. We ignore timeouts less than
+ * // ten milliseconds as they are mostly pointless on Windows, the
+ * // MsgWaitForMultipleObjectsEx() call will timeout right away
+ * // anyway.
+ *
+ * if (retval == 0 && (timeout == INFINITE || timeout >= 10))
+ * retval = poll_rest (poll_msgs, handles, nhandles, fds, nfds, timeout);
+ *
+ * So whenever g_poll is called with timeout < 10ms it does
+ * a quick poll instead of wait, this causes significant performance
+ * degradation of QEMU, thus we should use WaitForMultipleObjectsEx
+ * directly
+ */
+gint g_poll_fixed(GPollFD *fds, guint nfds, gint timeout)
+{
+ guint i;
+ HANDLE handles[MAXIMUM_WAIT_OBJECTS];
+ gint nhandles = 0;
+ int num_completed = 0;
+
+ for (i = 0; i < nfds; i++) {
+ gint j;
+
+ if (fds[i].fd <= 0) {
+ continue;
+ }
+
+ /* don't add same handle several times
+ */
+ for (j = 0; j < nhandles; j++) {
+ if (handles[j] == (HANDLE)fds[i].fd) {
+ break;
+ }
+ }
+
+ if (j == nhandles) {
+ if (nhandles == MAXIMUM_WAIT_OBJECTS) {
+ fprintf(stderr, "Too many handles to wait for!\n");
+ break;
+ } else {
+ handles[nhandles++] = (HANDLE)fds[i].fd;
+ }
+ }
+ }
+
+ for (i = 0; i < nfds; ++i) {
+ fds[i].revents = 0;
+ }
+
+ if (timeout == -1) {
+ timeout = INFINITE;
+ }
+
+ if (nhandles == 0) {
+ if (timeout == INFINITE) {
+ return -1;
+ } else {
+ SleepEx(timeout, TRUE);
+ return 0;
+ }
+ }
+
+ while (1) {
+ DWORD res;
+ gint j;
+
+ res = WaitForMultipleObjectsEx(nhandles, handles, FALSE,
+ timeout, TRUE);
+
+ if (res == WAIT_FAILED) {
+ for (i = 0; i < nfds; ++i) {
+ fds[i].revents = 0;
+ }
+
+ return -1;
+ } else if ((res == WAIT_TIMEOUT) || (res == WAIT_IO_COMPLETION) ||
+ ((int)res < (int)WAIT_OBJECT_0) ||
+ (res >= (WAIT_OBJECT_0 + nhandles))) {
+ break;
+ }
+
+ for (i = 0; i < nfds; ++i) {
+ if (handles[res - WAIT_OBJECT_0] == (HANDLE)fds[i].fd) {
+ fds[i].revents = fds[i].events;
+ }
+ }
+
+ ++num_completed;
+
+ if (nhandles <= 1) {
+ break;
+ }
+
+ /* poll the rest of the handles
+ */
+ for (j = res - WAIT_OBJECT_0 + 1; j < nhandles; j++) {
+ handles[j - 1] = handles[j];
+ }
+ --nhandles;
+
+ timeout = 0;
+ }
+
+ return num_completed;
+}

View File

@ -0,0 +1,350 @@
From 57a1d211179279727d5afa21a7feba2d249d6867 Mon Sep 17 00:00:00 2001
From: Michael Tokarev <mjt@tls.msk.ru>
Date: Thu, 8 May 2014 12:30:46 +0400
Subject: [PATCH] glib-compat.h: add new thread API emulation on top of
pre-2.31 API
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: Stefan Hajnoczi <stefanha@redhat.com>
[Use GOnce to support lazy initialization; introduce CompatGMutex
and CompatGCond. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 86946a2d835614050b90bc8e5c82982fe45deff2)
---
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..4ae0671 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) 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 1584bf7..8fc96fe 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;
@@ -151,26 +132,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)
@@ -399,11 +380,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);
@@ -418,11 +395,6 @@ bool trace_backend_init(const char *events, const char *file)
trace_pid = getpid();
-#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");

View File

@ -0,0 +1,38 @@
From c916d06403eec41a92eabf52b31102d3b7068da8 Mon Sep 17 00:00:00 2001
From: Michael Tokarev <mjt@tls.msk.ru>
Date: Fri, 2 May 2014 18:35:59 +0400
Subject: [PATCH] libcacard: replace pstrcpy() with memcpy()
Commit 2e679780ae86c6ca8 replaced strncpy() with pstrcpy()
in one place in libcacard. This is a qemu-specific function,
while libcacard is a stand-alone library (or tries to be).
But since we know the exact length of the string to copy,
and know that it definitely will fit in the destination
buffer, use memcpy() instead, and null-terminate the string
after that.
An alternative is to use g_strlcpy() or strncpy(), but memcpy()
is more than adequate in this place.
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Cc: qemu-trivial@nongnu.org
Cc: Alon Levy <alevy@redhat.com>
(cherry picked from commit a22f8f38942623dc473bf5ced5b4117b8bdf4821)
---
libcacard/vcard_emul_nss.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libcacard/vcard_emul_nss.c b/libcacard/vcard_emul_nss.c
index ee2dfae..e2b196d 100644
--- a/libcacard/vcard_emul_nss.c
+++ b/libcacard/vcard_emul_nss.c
@@ -1162,7 +1162,8 @@ vcard_emul_options(const char *args)
NEXT_TOKEN(vname)
NEXT_TOKEN(type_params)
type_params_length = MIN(type_params_length, sizeof(type_str)-1);
- pstrcpy(type_str, type_params_length, type_params);
+ memcpy(type_str, type_params, type_params_length);
+ type_str[type_params_length] = '\0';
type = vcard_emul_type_from_string(type_str);
NEXT_TOKEN(type_params)

View File

@ -0,0 +1,236 @@
From 118436ff47d7269f4bf3e3c1cd83df4b44b7d5c2 Mon Sep 17 00:00:00 2001
From: Michael Tokarev <mjt@tls.msk.ru>
Date: Thu, 8 May 2014 19:51:01 +0400
Subject: [PATCH] libcacard: g_malloc cleanups
This patch replaces g_malloc() in libcacard into g_new()
or g_new0() where appropriate (removing some init-to-zero
surrounding code), g_malloc+memcpy into g_memdup() and the
like.
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Reviewed-by: Alon Levy <alevy@redhat.com>
(cherry picked from commit 78a4b8d2051bff8e8794e9419b7925122212b096)
---
libcacard/cac.c | 11 +++--------
libcacard/card_7816.c | 11 +++++------
libcacard/event.c | 2 +-
libcacard/vcard.c | 22 +++++-----------------
libcacard/vcard_emul_nss.c | 12 ++++++------
libcacard/vreader.c | 11 +++--------
6 files changed, 23 insertions(+), 46 deletions(-)
diff --git a/libcacard/cac.c b/libcacard/cac.c
index 74ef3e3..122129e 100644
--- a/libcacard/cac.c
+++ b/libcacard/cac.c
@@ -310,16 +310,11 @@ static VCardAppletPrivate *
cac_new_pki_applet_private(const unsigned char *cert,
int cert_len, VCardKey *key)
{
- CACPKIAppletData *pki_applet_data = NULL;
- VCardAppletPrivate *applet_private = NULL;
- applet_private = (VCardAppletPrivate *)g_malloc(sizeof(VCardAppletPrivate));
+ CACPKIAppletData *pki_applet_data;
+ VCardAppletPrivate *applet_private;
+ applet_private = g_new0(VCardAppletPrivate, 1);
pki_applet_data = &(applet_private->u.pki_data);
- pki_applet_data->cert_buffer = NULL;
- pki_applet_data->cert_buffer_len = 0;
- pki_applet_data->sign_buffer = NULL;
- pki_applet_data->sign_buffer_len = 0;
- pki_applet_data->key = NULL;
pki_applet_data->cert = (unsigned char *)g_malloc(cert_len+1);
/*
* if we want to support compression, then we simply change the 0 to a 1
diff --git a/libcacard/card_7816.c b/libcacard/card_7816.c
index c28bb60..bca8c4a 100644
--- a/libcacard/card_7816.c
+++ b/libcacard/card_7816.c
@@ -51,7 +51,7 @@ vcard_response_new_data(unsigned char *buf, int len)
{
VCardResponse *new_response;
- new_response = (VCardResponse *)g_malloc(sizeof(VCardResponse));
+ new_response = g_new(VCardResponse, 1);
new_response->b_data = g_malloc(len + 2);
memcpy(new_response->b_data, buf, len);
new_response->b_total_len = len+2;
@@ -132,7 +132,7 @@ vcard_response_new_status(vcard_7816_status_t status)
{
VCardResponse *new_response;
- new_response = (VCardResponse *)g_malloc(sizeof(VCardResponse));
+ new_response = g_new(VCardResponse, 1);
new_response->b_data = &new_response->b_sw1;
new_response->b_len = 0;
new_response->b_total_len = 2;
@@ -149,7 +149,7 @@ vcard_response_new_status_bytes(unsigned char sw1, unsigned char sw2)
{
VCardResponse *new_response;
- new_response = (VCardResponse *)g_malloc(sizeof(VCardResponse));
+ new_response = g_new(VCardResponse, 1);
new_response->b_data = &new_response->b_sw1;
new_response->b_len = 0;
new_response->b_total_len = 2;
@@ -336,9 +336,8 @@ vcard_apdu_new(unsigned char *raw_apdu, int len, vcard_7816_status_t *status)
return NULL;
}
- new_apdu = (VCardAPDU *)g_malloc(sizeof(VCardAPDU));
- new_apdu->a_data = g_malloc(len);
- memcpy(new_apdu->a_data, raw_apdu, len);
+ new_apdu = g_new(VCardAPDU, 1);
+ new_apdu->a_data = g_memdup(raw_apdu, len);
new_apdu->a_len = len;
*status = vcard_apdu_set_class(new_apdu);
if (*status != VCARD7816_STATUS_SUCCESS) {
diff --git a/libcacard/event.c b/libcacard/event.c
index 2d7500f..a2e6c7d 100644
--- a/libcacard/event.c
+++ b/libcacard/event.c
@@ -17,7 +17,7 @@ vevent_new(VEventType type, VReader *reader, VCard *card)
{
VEvent *new_vevent;
- new_vevent = (VEvent *)g_malloc(sizeof(VEvent));
+ new_vevent = g_new(VEvent, 1);
new_vevent->next = NULL;
new_vevent->type = type;
new_vevent->reader = vreader_reference(reader);
diff --git a/libcacard/vcard.c b/libcacard/vcard.c
index 539177b..227e477 100644
--- a/libcacard/vcard.c
+++ b/libcacard/vcard.c
@@ -37,9 +37,8 @@ vcard_buffer_response_new(unsigned char *buffer, int size)
{
VCardBufferResponse *new_buffer;
- new_buffer = (VCardBufferResponse *)g_malloc(sizeof(VCardBufferResponse));
- new_buffer->buffer = (unsigned char *)g_malloc(size);
- memcpy(new_buffer->buffer, buffer, size);
+ new_buffer = g_new(VCardBufferResponse, 1);
+ new_buffer->buffer = (unsigned char *)g_memdup(buffer, size);
new_buffer->buffer_len = size;
new_buffer->current = new_buffer->buffer;
new_buffer->len = size;
@@ -102,15 +101,11 @@ vcard_new_applet(VCardProcessAPDU applet_process_function,
{
VCardApplet *applet;
- applet = (VCardApplet *)g_malloc(sizeof(VCardApplet));
- applet->next = NULL;
- applet->applet_private = NULL;
- applet->applet_private_free = NULL;
+ applet = g_new0(VCardApplet, 1);
applet->process_apdu = applet_process_function;
applet->reset_applet = applet_reset_function;
- applet->aid = g_malloc(aid_len);
- memcpy(applet->aid, aid, aid_len);
+ applet->aid = g_memdup(aid, aid_len);
applet->aid_len = aid_len;
return applet;
}
@@ -149,18 +144,11 @@ VCard *
vcard_new(VCardEmul *private, VCardEmulFree private_free)
{
VCard *new_card;
- int i;
- new_card = (VCard *)g_malloc(sizeof(VCard));
- new_card->applet_list = NULL;
- for (i = 0; i < MAX_CHANNEL; i++) {
- new_card->current_applet[i] = NULL;
- }
- new_card->vcard_buffer_response = NULL;
+ new_card = g_new0(VCard, 1);
new_card->type = VCARD_VM;
new_card->vcard_private = private;
new_card->vcard_private_free = private_free;
- new_card->vcard_get_atr = NULL;
new_card->reference_count = 1;
return new_card;
}
diff --git a/libcacard/vcard_emul_nss.c b/libcacard/vcard_emul_nss.c
index e2b196d..75b9d79 100644
--- a/libcacard/vcard_emul_nss.c
+++ b/libcacard/vcard_emul_nss.c
@@ -94,9 +94,9 @@ static void
vcard_emul_alloc_arrays(unsigned char ***certsp, int **cert_lenp,
VCardKey ***keysp, int cert_count)
{
- *certsp = (unsigned char **)g_malloc(sizeof(unsigned char *)*cert_count);
- *cert_lenp = (int *)g_malloc(sizeof(int)*cert_count);
- *keysp = (VCardKey **)g_malloc(sizeof(VCardKey *)*cert_count);
+ *certsp = g_new(unsigned char *, cert_count);
+ *cert_lenp = g_new(int, cert_count);
+ *keysp = g_new(VCardKey *, cert_count);
}
/*
@@ -139,7 +139,7 @@ vcard_emul_make_key(PK11SlotInfo *slot, CERTCertificate *cert)
{
VCardKey *key;
- key = (VCardKey *)g_malloc(sizeof(VCardKey));
+ key = g_new(VCardKey, 1);
key->slot = PK11_ReferenceSlot(slot);
key->cert = CERT_DupCertificate(cert);
/* NOTE: if we aren't logged into the token, this could return NULL */
@@ -449,7 +449,7 @@ vreader_emul_new(PK11SlotInfo *slot, VCardEmulType type, const char *params)
{
VReaderEmul *new_reader_emul;
- new_reader_emul = (VReaderEmul *)g_malloc(sizeof(VReaderEmul));
+ new_reader_emul = g_new(VReaderEmul, 1);
new_reader_emul->slot = PK11_ReferenceSlot(slot);
new_reader_emul->default_type = type;
@@ -1189,7 +1189,7 @@ vcard_emul_options(const char *args)
g_strndup(type_params, type_params_length);
count = count_tokens(args, ',', ')') + 1;
vreaderOpt->cert_count = count;
- vreaderOpt->cert_name = (char **)g_malloc(count*sizeof(char *));
+ vreaderOpt->cert_name = g_new(char *, count);
for (i = 0; i < count; i++) {
const char *cert = args;
args = strpbrk(args, ",)");
diff --git a/libcacard/vreader.c b/libcacard/vreader.c
index 5793d73..215a2f6 100644
--- a/libcacard/vreader.c
+++ b/libcacard/vreader.c
@@ -115,7 +115,7 @@ vreader_new(const char *name, VReaderEmul *private,
{
VReader *reader;
- reader = (VReader *)g_malloc(sizeof(VReader));
+ reader = g_new(VReader, 1);
qemu_mutex_init(&reader->lock);
reader->reference_count = 1;
reader->name = g_strdup(name);
@@ -312,10 +312,7 @@ vreader_list_entry_new(VReader *reader)
{
VReaderListEntry *new_reader_list_entry;
- new_reader_list_entry = (VReaderListEntry *)
- g_malloc(sizeof(VReaderListEntry));
- new_reader_list_entry->next = NULL;
- new_reader_list_entry->prev = NULL;
+ new_reader_list_entry = g_new0(VReaderListEntry, 1);
new_reader_list_entry->reader = vreader_reference(reader);
return new_reader_list_entry;
}
@@ -336,9 +333,7 @@ vreader_list_new(void)
{
VReaderList *new_reader_list;
- new_reader_list = (VReaderList *)g_malloc(sizeof(VReaderList));
- new_reader_list->head = NULL;
- new_reader_list->tail = NULL;
+ new_reader_list = g_new0(VReaderList, 1);
return new_reader_list;
}

View File

@ -0,0 +1,218 @@
From 4a609afa4206d7af9fe2c8dcfbe7850509701aff Mon Sep 17 00:00:00 2001
From: Michael Tokarev <mjt@tls.msk.ru>
Date: Thu, 8 May 2014 12:30:47 +0400
Subject: [PATCH] vscclient: use glib thread primitives not qemu
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>
(cherry picked from commit 2a0c46da967e5dc8cfe73b1b6fe7a1600c04f461)
---
libcacard/vscclient.c | 70 +++++++++++++++++++++++++++------------------------
1 file 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);

View File

@ -0,0 +1,204 @@
From 95d830ad782262bac47e4cc368e8dff108b789f1 Mon Sep 17 00:00:00 2001
From: Michael Tokarev <mjt@tls.msk.ru>
Date: Thu, 8 May 2014 12:30:48 +0400
Subject: [PATCH] libcacard: replace qemu thread primitives with glib ones
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>
(cherry picked from commit fd25c0e6dd1ed2aa932fa7ef814b32457bf270fd)
---
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 6b06448..89a5942 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 a2e6c7d..4c551e4 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 215a2f6..75b5b28 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 = g_new(VReader, 1);
- 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);
}
@@ -408,25 +407,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 *

View File

@ -158,7 +158,7 @@
Summary: QEMU is a FAST! processor emulator
Name: qemu
Version: 2.0.0
Release: 6%{?dist}
Release: 7%{?dist}
Epoch: 2
License: GPLv2+ and LGPLv2+ and BSD
Group: Development/Tools
@ -236,6 +236,18 @@ Patch0105: 0105-qcow1-Stricter-backing-file-length-check.patch
# CVE-2014-3461: Issues in USB post load checks (bz #1097260, bz
# #1096821)
Patch0106: 0106-usb-fix-up-post-load-checks.patch
# Don't use libtool on dtrace, fixes rawhide build (bz #1106968)
Patch0107: 0107-trace-add-pid-field-to-simpletrace-record.patch
Patch0108: 0108-simpletrace-add-support-for-trace-record-pid-field.patch
Patch0109: 0109-trace-Replace-error-with-warning-if-event-is-not-def.patch
Patch0110: 0110-do-not-call-g_thread_init-for-glib-2.31.patch
Patch0111: 0111-glib-move-g_poll-replacement-into-glib-compat.h.patch
Patch0112: 0112-glib-fix-g_poll-early-timeout-on-windows.patch
Patch0113: 0113-glib-compat.h-add-new-thread-API-emulation-on-top-of.patch
Patch0114: 0114-libcacard-replace-pstrcpy-with-memcpy.patch
Patch0115: 0115-libcacard-g_malloc-cleanups.patch
Patch0116: 0116-vscclient-use-glib-thread-primitives-not-qemu.patch
Patch0117: 0117-libcacard-replace-qemu-thread-primitives-with-glib-o.patch
BuildRequires: SDL-devel
BuildRequires: zlib-devel
@ -796,6 +808,18 @@ CAC emulation development files.
# CVE-2014-3461: Issues in USB post load checks (bz #1097260, bz
# #1096821)
%patch0106 -p1
# Don't use libtool on dtrace, fixes rawhide build (bz #1106968)
%patch0107 -p1
%patch0108 -p1
%patch0109 -p1
%patch0110 -p1
%patch0111 -p1
%patch0112 -p1
%patch0113 -p1
%patch0114 -p1
%patch0115 -p1
%patch0116 -p1
%patch0117 -p1
%build
@ -1563,6 +1587,9 @@ getent passwd qemu >/dev/null || \
%endif
%changelog
* Sun Jun 15 2014 Cole Robinson <crobinso@redhat.com> - 2:2.0.0-7
- Don't use libtool on dtrace, fixes rawhide build (bz #1106968)
* Sun Jun 08 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2:2.0.0-6
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild