mirror of https://github.com/xemu-project/xemu.git
wxx patch queue
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABCAAGBQJWBE4CAAoJEOCMIdVndFCtv+YP/ieFC5jYs4OHW3y9KCFk1PIJ 7NNQrURf6bIZzbJWrMyloa0Tcv5tSgi6tfha6K2nUGTw+dyUKEfUM7WugadEKc8U 7oLmExJ+QTog7wTdLzZecfaZ2z8cpHihUTn4YQlmAgUy52b1FEo6DW0lDvte7bU0 LY3o9IPL9pFkH6BDyXqfwbQK55slHmR+iCB9IJUI13sRdpA0wRiKH+w0Kd0yR2SY Krqz8dC1DC+TKu04rpFIszy9HAxUMxO/JVVrfz7Tft/Mmi5vxrfyuPABocsPjsXf Xv55YYwu03J0v01f4AaVpap6MaypXotm0eyktWY0kqqhePoSU5+2qqwjZaVzsUYU ddTMHukDCoNHhFQmOGnMZ49nPvrx1UoIsy84El6Q3tyF6dUSSy0XfXLoB8lWN7j4 ZZa+jSC4FChuejxxcspjnlogg/bguW8uAQttB7ASiDr46PIpCWZTYLiDs1KO2b4J BKmlKXHVkdG026rZOekeGzkObnfOMOKUqig9nDBbfB1ULBk2TQuI5i0GSYj3Crlm v9okF420xHKRBTa1gbP9Rl2122bHwtYwVnIwzACtbK6kJ6cnZv2u2j1MwGQOd4i4 5D40HhmXElNYfcluFMVmGlfvNv6W4oVe/id9bP4s9x4mmtXJl0+/ZVjoS2mqo0AT 4ZQdR3DRLXe3F4LHPJQP =xdVb -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/weil/tags/pull-wxx-20150924' into staging wxx patch queue # gpg: Signature made Thu 24 Sep 2015 20:24:50 BST using RSA key ID 677450AD # gpg: Good signature from "Stefan Weil <sw@weilnetz.de>" # gpg: aka "Stefan Weil <stefan.weil@weilnetz.de>" # gpg: aka "Stefan Weil <stefan.weil@bib.uni-mannheim.de>" # gpg: WARNING: This key is not certified with sufficiently trusted signatures! # gpg: It is not certain that the signature belongs to the owner. # Primary key fingerprint: 4923 6FEA 75C9 5D69 8EC2 B78A E08C 21D5 6774 50AD * remotes/weil/tags/pull-wxx-20150924: oslib-win32: only provide localtime_r/gmtime_r if missing gtk: avoid redefining _WIN32_WINNT macro qemu-thread: add a fast path to the Win32 QemuEvent slirp: Fix non blocking connect for w32 nsis: Add QEMU version information to Windows registry Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
8a47d575df
1
Makefile
1
Makefile
|
@ -623,6 +623,7 @@ endif # SIGNCODE
|
||||||
$(if $(DLL_PATH),-DDLLDIR="$(DLL_PATH)") \
|
$(if $(DLL_PATH),-DDLLDIR="$(DLL_PATH)") \
|
||||||
-DSRCDIR="$(SRC_PATH)" \
|
-DSRCDIR="$(SRC_PATH)" \
|
||||||
-DOUTFILE="$(INSTALLER)" \
|
-DOUTFILE="$(INSTALLER)" \
|
||||||
|
-DDISPLAYVERSION="$(VERSION)" \
|
||||||
$(SRC_PATH)/qemu.nsi
|
$(SRC_PATH)/qemu.nsi
|
||||||
rm -r ${INSTDIR}
|
rm -r ${INSTDIR}
|
||||||
ifdef SIGNCODE
|
ifdef SIGNCODE
|
||||||
|
|
|
@ -1736,6 +1736,37 @@ else
|
||||||
l2tpv3=no
|
l2tpv3=no
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
##########################################
|
||||||
|
# MinGW / Mingw-w64 localtime_r/gmtime_r check
|
||||||
|
|
||||||
|
if test "$mingw32" = "yes"; then
|
||||||
|
# Some versions of MinGW / Mingw-w64 lack localtime_r
|
||||||
|
# and gmtime_r entirely.
|
||||||
|
#
|
||||||
|
# Some versions of Mingw-w64 define a macro for
|
||||||
|
# localtime_r/gmtime_r.
|
||||||
|
#
|
||||||
|
# Some versions of Mingw-w64 will define functions
|
||||||
|
# for localtime_r/gmtime_r, but only if you have
|
||||||
|
# _POSIX_THREAD_SAFE_FUNCTIONS defined. For fun
|
||||||
|
# though, unistd.h and pthread.h both define
|
||||||
|
# that for you.
|
||||||
|
#
|
||||||
|
# So this #undef localtime_r and #include <unistd.h>
|
||||||
|
# are not in fact redundant.
|
||||||
|
cat > $TMPC << EOF
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <time.h>
|
||||||
|
#undef localtime_r
|
||||||
|
int main(void) { localtime_r(NULL, NULL); return 0; }
|
||||||
|
EOF
|
||||||
|
if compile_prog "" "" ; then
|
||||||
|
localtime_r="yes"
|
||||||
|
else
|
||||||
|
localtime_r="no"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
##########################################
|
##########################################
|
||||||
# pkg-config probe
|
# pkg-config probe
|
||||||
|
|
||||||
|
@ -5034,6 +5065,9 @@ fi
|
||||||
if test "$zero_malloc" = "yes" ; then
|
if test "$zero_malloc" = "yes" ; then
|
||||||
echo "CONFIG_ZERO_MALLOC=y" >> $config_host_mak
|
echo "CONFIG_ZERO_MALLOC=y" >> $config_host_mak
|
||||||
fi
|
fi
|
||||||
|
if test "$localtime_r" = "yes" ; then
|
||||||
|
echo "CONFIG_LOCALTIME_R=y" >> $config_host_mak
|
||||||
|
fi
|
||||||
if test "$qom_cast_debug" = "yes" ; then
|
if test "$qom_cast_debug" = "yes" ; then
|
||||||
echo "CONFIG_QOM_CAST_DEBUG=y" >> $config_host_mak
|
echo "CONFIG_QOM_CAST_DEBUG=y" >> $config_host_mak
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
/*
|
||||||
|
* This model describes the implementation of QemuEvent in
|
||||||
|
* util/qemu-thread-win32.c.
|
||||||
|
*
|
||||||
|
* Author: Paolo Bonzini <pbonzini@redhat.com>
|
||||||
|
*
|
||||||
|
* This file is in the public domain. If you really want a license,
|
||||||
|
* the WTFPL will do.
|
||||||
|
*
|
||||||
|
* To verify it:
|
||||||
|
* spin -a docs/event.promela
|
||||||
|
* gcc -O2 pan.c -DSAFETY
|
||||||
|
* ./a.out
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool event;
|
||||||
|
int value;
|
||||||
|
|
||||||
|
/* Primitives for a Win32 event */
|
||||||
|
#define RAW_RESET event = false
|
||||||
|
#define RAW_SET event = true
|
||||||
|
#define RAW_WAIT do :: event -> break; od
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* Basic sanity checking: test the Win32 event primitives */
|
||||||
|
#define RESET RAW_RESET
|
||||||
|
#define SET RAW_SET
|
||||||
|
#define WAIT RAW_WAIT
|
||||||
|
#else
|
||||||
|
/* Full model: layer a userspace-only fast path on top of the RAW_*
|
||||||
|
* primitives. SET/RESET/WAIT have exactly the same semantics as
|
||||||
|
* RAW_SET/RAW_RESET/RAW_WAIT, but try to avoid invoking them.
|
||||||
|
*/
|
||||||
|
#define EV_SET 0
|
||||||
|
#define EV_FREE 1
|
||||||
|
#define EV_BUSY -1
|
||||||
|
|
||||||
|
int state = EV_FREE;
|
||||||
|
|
||||||
|
int xchg_result;
|
||||||
|
#define SET if :: state != EV_SET -> \
|
||||||
|
atomic { /* xchg_result=xchg(state, EV_SET) */ \
|
||||||
|
xchg_result = state; \
|
||||||
|
state = EV_SET; \
|
||||||
|
} \
|
||||||
|
if :: xchg_result == EV_BUSY -> RAW_SET; \
|
||||||
|
:: else -> skip; \
|
||||||
|
fi; \
|
||||||
|
:: else -> skip; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
#define RESET if :: state == EV_SET -> atomic { state = state | EV_FREE; } \
|
||||||
|
:: else -> skip; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
int tmp1, tmp2;
|
||||||
|
#define WAIT tmp1 = state; \
|
||||||
|
if :: tmp1 != EV_SET -> \
|
||||||
|
if :: tmp1 == EV_FREE -> \
|
||||||
|
RAW_RESET; \
|
||||||
|
atomic { /* tmp2=cas(state, EV_FREE, EV_BUSY) */ \
|
||||||
|
tmp2 = state; \
|
||||||
|
if :: tmp2 == EV_FREE -> state = EV_BUSY; \
|
||||||
|
:: else -> skip; \
|
||||||
|
fi; \
|
||||||
|
} \
|
||||||
|
if :: tmp2 == EV_SET -> tmp1 = EV_SET; \
|
||||||
|
:: else -> tmp1 = EV_BUSY; \
|
||||||
|
fi; \
|
||||||
|
:: else -> skip; \
|
||||||
|
fi; \
|
||||||
|
assert(tmp1 != EV_FREE); \
|
||||||
|
if :: tmp1 == EV_BUSY -> RAW_WAIT; \
|
||||||
|
:: else -> skip; \
|
||||||
|
fi; \
|
||||||
|
:: else -> skip; \
|
||||||
|
fi
|
||||||
|
#endif
|
||||||
|
|
||||||
|
active proctype waiter()
|
||||||
|
{
|
||||||
|
if
|
||||||
|
:: !value ->
|
||||||
|
RESET;
|
||||||
|
if
|
||||||
|
:: !value -> WAIT;
|
||||||
|
:: else -> skip;
|
||||||
|
fi;
|
||||||
|
:: else -> skip;
|
||||||
|
fi;
|
||||||
|
assert(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
active proctype notifier()
|
||||||
|
{
|
||||||
|
value = true;
|
||||||
|
SET;
|
||||||
|
}
|
|
@ -38,10 +38,12 @@
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
/* Put unistd.h before time.h as that triggers localtime_r/gmtime_r
|
||||||
|
* function availability on recentish Mingw-w64 platforms. */
|
||||||
|
#include <unistd.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
|
@ -18,6 +18,7 @@ struct QemuSemaphore {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct QemuEvent {
|
struct QemuEvent {
|
||||||
|
int value;
|
||||||
HANDLE event;
|
HANDLE event;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -73,10 +73,12 @@
|
||||||
#define siglongjmp(env, val) longjmp(env, val)
|
#define siglongjmp(env, val) longjmp(env, val)
|
||||||
|
|
||||||
/* Missing POSIX functions. Don't use MinGW-w64 macros. */
|
/* Missing POSIX functions. Don't use MinGW-w64 macros. */
|
||||||
|
#ifndef CONFIG_LOCALTIME_R
|
||||||
#undef gmtime_r
|
#undef gmtime_r
|
||||||
struct tm *gmtime_r(const time_t *timep, struct tm *result);
|
struct tm *gmtime_r(const time_t *timep, struct tm *result);
|
||||||
#undef localtime_r
|
#undef localtime_r
|
||||||
struct tm *localtime_r(const time_t *timep, struct tm *result);
|
struct tm *localtime_r(const time_t *timep, struct tm *result);
|
||||||
|
#endif /* CONFIG_LOCALTIME_R */
|
||||||
|
|
||||||
|
|
||||||
static inline void os_setup_signal_handling(void) {}
|
static inline void os_setup_signal_handling(void) {}
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
#ifndef UI_GTK_H
|
#ifndef UI_GTK_H
|
||||||
#define UI_GTK_H
|
#define UI_GTK_H
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
# define _WIN32_WINNT 0x0601 /* needed to get definition of MAPVK_VK_TO_VSC */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE
|
#ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE
|
||||||
/* Work around an -Wstrict-prototypes warning in GTK headers */
|
/* Work around an -Wstrict-prototypes warning in GTK headers */
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
|
|
3
qemu.nsi
3
qemu.nsi
|
@ -139,6 +139,9 @@ Section "${PRODUCT} (required)"
|
||||||
|
|
||||||
; Write the uninstall keys for Windows
|
; Write the uninstall keys for Windows
|
||||||
WriteRegStr HKLM "${UNINST_KEY}" "DisplayName" "QEMU"
|
WriteRegStr HKLM "${UNINST_KEY}" "DisplayName" "QEMU"
|
||||||
|
!ifdef DISPLAYVERSION
|
||||||
|
WriteRegStr HKLM "${UNINST_KEY}" "DisplayVersion" "${DISPLAYVERSION}"
|
||||||
|
!endif
|
||||||
WriteRegStr HKLM "${UNINST_KEY}" "UninstallString" '"${UNINST_EXE}"'
|
WriteRegStr HKLM "${UNINST_KEY}" "UninstallString" '"${UNINST_EXE}"'
|
||||||
WriteRegDWORD HKLM "${UNINST_KEY}" "NoModify" 1
|
WriteRegDWORD HKLM "${UNINST_KEY}" "NoModify" 1
|
||||||
WriteRegDWORD HKLM "${UNINST_KEY}" "NoRepair" 1
|
WriteRegDWORD HKLM "${UNINST_KEY}" "NoRepair" 1
|
||||||
|
|
|
@ -584,7 +584,13 @@ findso:
|
||||||
goto cont_input;
|
goto cont_input;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((tcp_fconnect(so) == -1) && (errno != EINPROGRESS) && (errno != EWOULDBLOCK)) {
|
if ((tcp_fconnect(so) == -1) &&
|
||||||
|
#if defined(_WIN32)
|
||||||
|
socket_error() != WSAEWOULDBLOCK
|
||||||
|
#else
|
||||||
|
(errno != EINPROGRESS) && (errno != EWOULDBLOCK)
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
u_char code=ICMP_UNREACH_NET;
|
u_char code=ICMP_UNREACH_NET;
|
||||||
DEBUG_MISC((dfd, " tcp fconnect errno = %d-%s\n",
|
DEBUG_MISC((dfd, " tcp fconnect errno = %d-%s\n",
|
||||||
errno,strerror(errno)));
|
errno,strerror(errno)));
|
||||||
|
|
9
ui/gtk.c
9
ui/gtk.c
|
@ -104,6 +104,15 @@
|
||||||
#define GDK_KEY_Pause GDK_Pause
|
#define GDK_KEY_Pause GDK_Pause
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Some older mingw versions lack this constant or have
|
||||||
|
* it conditionally defined */
|
||||||
|
#ifdef _WIN32
|
||||||
|
# ifndef MAPVK_VK_TO_VSC
|
||||||
|
# define MAPVK_VK_TO_VSC 0
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define HOTKEY_MODIFIERS (GDK_CONTROL_MASK | GDK_MOD1_MASK)
|
#define HOTKEY_MODIFIERS (GDK_CONTROL_MASK | GDK_MOD1_MASK)
|
||||||
|
|
||||||
static const int modifier_keycode[] = {
|
static const int modifier_keycode[] = {
|
||||||
|
|
|
@ -95,6 +95,7 @@ void qemu_anon_ram_free(void *ptr, size_t size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CONFIG_LOCALTIME_R
|
||||||
/* FIXME: add proper locking */
|
/* FIXME: add proper locking */
|
||||||
struct tm *gmtime_r(const time_t *timep, struct tm *result)
|
struct tm *gmtime_r(const time_t *timep, struct tm *result)
|
||||||
{
|
{
|
||||||
|
@ -118,6 +119,7 @@ struct tm *localtime_r(const time_t *timep, struct tm *result)
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
#endif /* CONFIG_LOCALTIME_R */
|
||||||
|
|
||||||
void qemu_set_block(int fd)
|
void qemu_set_block(int fd)
|
||||||
{
|
{
|
||||||
|
|
|
@ -238,10 +238,34 @@ void qemu_sem_wait(QemuSemaphore *sem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Wrap a Win32 manual-reset event with a fast userspace path. The idea
|
||||||
|
* is to reset the Win32 event lazily, as part of a test-reset-test-wait
|
||||||
|
* sequence. Such a sequence is, indeed, how QemuEvents are used by
|
||||||
|
* RCU and other subsystems!
|
||||||
|
*
|
||||||
|
* Valid transitions:
|
||||||
|
* - free->set, when setting the event
|
||||||
|
* - busy->set, when setting the event, followed by futex_wake
|
||||||
|
* - set->free, when resetting the event
|
||||||
|
* - free->busy, when waiting
|
||||||
|
*
|
||||||
|
* set->busy does not happen (it can be observed from the outside but
|
||||||
|
* it really is set->free->busy).
|
||||||
|
*
|
||||||
|
* busy->free provably cannot happen; to enforce it, the set->free transition
|
||||||
|
* is done with an OR, which becomes a no-op if the event has concurrently
|
||||||
|
* transitioned to free or busy (and is faster than cmpxchg).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define EV_SET 0
|
||||||
|
#define EV_FREE 1
|
||||||
|
#define EV_BUSY -1
|
||||||
|
|
||||||
void qemu_event_init(QemuEvent *ev, bool init)
|
void qemu_event_init(QemuEvent *ev, bool init)
|
||||||
{
|
{
|
||||||
/* Manual reset. */
|
/* Manual reset. */
|
||||||
ev->event = CreateEvent(NULL, TRUE, init, NULL);
|
ev->event = CreateEvent(NULL, TRUE, TRUE, NULL);
|
||||||
|
ev->value = (init ? EV_SET : EV_FREE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void qemu_event_destroy(QemuEvent *ev)
|
void qemu_event_destroy(QemuEvent *ev)
|
||||||
|
@ -251,17 +275,51 @@ void qemu_event_destroy(QemuEvent *ev)
|
||||||
|
|
||||||
void qemu_event_set(QemuEvent *ev)
|
void qemu_event_set(QemuEvent *ev)
|
||||||
{
|
{
|
||||||
|
if (atomic_mb_read(&ev->value) != EV_SET) {
|
||||||
|
if (atomic_xchg(&ev->value, EV_SET) == EV_BUSY) {
|
||||||
|
/* There were waiters, wake them up. */
|
||||||
SetEvent(ev->event);
|
SetEvent(ev->event);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void qemu_event_reset(QemuEvent *ev)
|
void qemu_event_reset(QemuEvent *ev)
|
||||||
{
|
{
|
||||||
ResetEvent(ev->event);
|
if (atomic_mb_read(&ev->value) == EV_SET) {
|
||||||
|
/* If there was a concurrent reset (or even reset+wait),
|
||||||
|
* do nothing. Otherwise change EV_SET->EV_FREE.
|
||||||
|
*/
|
||||||
|
atomic_or(&ev->value, EV_FREE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void qemu_event_wait(QemuEvent *ev)
|
void qemu_event_wait(QemuEvent *ev)
|
||||||
{
|
{
|
||||||
|
unsigned value;
|
||||||
|
|
||||||
|
value = atomic_mb_read(&ev->value);
|
||||||
|
if (value != EV_SET) {
|
||||||
|
if (value == EV_FREE) {
|
||||||
|
/* qemu_event_set is not yet going to call SetEvent, but we are
|
||||||
|
* going to do another check for EV_SET below when setting EV_BUSY.
|
||||||
|
* At that point it is safe to call WaitForSingleObject.
|
||||||
|
*/
|
||||||
|
ResetEvent(ev->event);
|
||||||
|
|
||||||
|
/* Tell qemu_event_set that there are waiters. No need to retry
|
||||||
|
* because there cannot be a concurent busy->free transition.
|
||||||
|
* After the CAS, the event will be either set or busy.
|
||||||
|
*/
|
||||||
|
if (atomic_cmpxchg(&ev->value, EV_FREE, EV_BUSY) == EV_SET) {
|
||||||
|
value = EV_SET;
|
||||||
|
} else {
|
||||||
|
value = EV_BUSY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (value == EV_BUSY) {
|
||||||
WaitForSingleObject(ev->event, INFINITE);
|
WaitForSingleObject(ev->event, INFINITE);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct QemuThreadData {
|
struct QemuThreadData {
|
||||||
|
|
Loading…
Reference in New Issue