remove glib dependency by provide compatible replacements
This commit is contained in:
@ -67,7 +67,7 @@ void error_set_errno(Error **errp, int os_errno, ErrorClass err_class,
|
||||
msg1 = g_strdup_vprintf(fmt, ap);
|
||||
if (os_errno != 0) {
|
||||
err->msg = g_strdup_printf("%s: %s", msg1, strerror(os_errno));
|
||||
g_free(msg1);
|
||||
free(msg1);
|
||||
} else {
|
||||
err->msg = msg1;
|
||||
}
|
||||
@ -110,8 +110,8 @@ void error_set_win32(Error **errp, int win32_err, ErrorClass err_class,
|
||||
char *msg2 = g_win32_error_message(win32_err);
|
||||
err->msg = g_strdup_printf("%s: %s (error: %x)", msg1, msg2,
|
||||
(unsigned)win32_err);
|
||||
g_free(msg2);
|
||||
g_free(msg1);
|
||||
free(msg2);
|
||||
free(msg1);
|
||||
} else {
|
||||
err->msg = msg1;
|
||||
}
|
||||
@ -152,8 +152,8 @@ const char *error_get_pretty(Error *err)
|
||||
void error_free(Error *err)
|
||||
{
|
||||
if (err) {
|
||||
g_free(err->msg);
|
||||
g_free(err);
|
||||
free(err->msg);
|
||||
free(err);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,8 +51,6 @@ extern int daemon(int, int);
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <glib/gprintf.h>
|
||||
|
||||
#include "config-host.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include <sys/mman.h>
|
||||
@ -183,13 +181,6 @@ int qemu_pipe(int pipefd[2])
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *
|
||||
qemu_get_local_state_pathname(const char *relative_pathname)
|
||||
{
|
||||
return g_strdup_printf("%s/%s", CONFIG_QEMU_LOCALSTATEDIR,
|
||||
relative_pathname);
|
||||
}
|
||||
|
||||
void qemu_set_tty_echo(int fd, bool echo)
|
||||
{
|
||||
struct termios tty;
|
||||
|
@ -25,15 +25,9 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* The implementation of g_poll (functions poll_rest, g_poll) at the end of
|
||||
* this file are based on code from GNOME glib-2 and use a different license,
|
||||
* see the license comment there.
|
||||
*/
|
||||
#include <windows.h>
|
||||
|
||||
#define G_OS_WIN32
|
||||
|
||||
#include <glib.h>
|
||||
#include <stdlib.h>
|
||||
#include "config-host.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
@ -156,23 +150,6 @@ int qemu_gettimeofday(qemu_timeval *tp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *
|
||||
qemu_get_local_state_pathname(const char *relative_pathname)
|
||||
{
|
||||
HRESULT result;
|
||||
char base_path[MAX_PATH+1] = "";
|
||||
|
||||
result = SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL,
|
||||
/* SHGFP_TYPE_CURRENT */ 0, base_path);
|
||||
if (result != S_OK) {
|
||||
/* misconfigured environment */
|
||||
g_critical("CSIDL_COMMON_APPDATA unavailable: %ld", (long)result);
|
||||
abort();
|
||||
}
|
||||
return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", base_path,
|
||||
relative_pathname);
|
||||
}
|
||||
|
||||
void qemu_set_tty_echo(int fd, bool echo)
|
||||
{
|
||||
HANDLE handle = (HANDLE)_get_osfhandle(fd);
|
||||
@ -192,210 +169,6 @@ void qemu_set_tty_echo(int fd, bool echo)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The original implementation of g_poll from glib has a problem on Windows
|
||||
* when using timeouts < 10 ms.
|
||||
*
|
||||
* Whenever g_poll is called with timeout < 10 ms, it does a quick poll instead
|
||||
* of wait. This causes significant performance degradation of QEMU.
|
||||
*
|
||||
* The following code is a copy of the original code from glib/gpoll.c
|
||||
* (glib commit 20f4d1820b8d4d0fc4447188e33efffd6d4a88d8 from 2014-02-19).
|
||||
* Some debug code was removed and the code was reformatted.
|
||||
* All other code modifications are marked with 'QEMU'.
|
||||
*/
|
||||
|
||||
/*
|
||||
* gpoll.c: poll(2) abstraction
|
||||
* Copyright 1998 Owen Taylor
|
||||
* Copyright 2008 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
static int poll_rest(gboolean poll_msgs, HANDLE *handles, gint nhandles,
|
||||
GPollFD *fds, guint nfds, gint timeout)
|
||||
{
|
||||
DWORD ready;
|
||||
GPollFD *f;
|
||||
int recursed_result;
|
||||
|
||||
if (poll_msgs) {
|
||||
/* Wait for either messages or handles
|
||||
* -> Use MsgWaitForMultipleObjectsEx
|
||||
*/
|
||||
ready = MsgWaitForMultipleObjectsEx(nhandles, handles, timeout,
|
||||
QS_ALLINPUT, MWMO_ALERTABLE);
|
||||
|
||||
if (ready == WAIT_FAILED) {
|
||||
gchar *emsg = g_win32_error_message(GetLastError());
|
||||
g_warning("MsgWaitForMultipleObjectsEx failed: %s", emsg);
|
||||
g_free(emsg);
|
||||
}
|
||||
} else if (nhandles == 0) {
|
||||
/* No handles to wait for, just the timeout */
|
||||
if (timeout == INFINITE) {
|
||||
ready = WAIT_FAILED;
|
||||
} else {
|
||||
SleepEx(timeout, TRUE);
|
||||
ready = WAIT_TIMEOUT;
|
||||
}
|
||||
} else {
|
||||
/* Wait for just handles
|
||||
* -> Use WaitForMultipleObjectsEx
|
||||
*/
|
||||
ready =
|
||||
WaitForMultipleObjectsEx(nhandles, handles, FALSE, timeout, TRUE);
|
||||
if (ready == WAIT_FAILED) {
|
||||
gchar *emsg = g_win32_error_message(GetLastError());
|
||||
g_warning("WaitForMultipleObjectsEx failed: %s", emsg);
|
||||
g_free(emsg);
|
||||
}
|
||||
}
|
||||
|
||||
if (ready == WAIT_FAILED) {
|
||||
return -1;
|
||||
} else if (ready == WAIT_TIMEOUT || ready == WAIT_IO_COMPLETION) {
|
||||
return 0;
|
||||
} else if (poll_msgs && ready == WAIT_OBJECT_0 + nhandles) {
|
||||
for (f = fds; f < &fds[nfds]; ++f) {
|
||||
if (f->fd == G_WIN32_MSG_HANDLE && f->events & G_IO_IN) {
|
||||
f->revents |= G_IO_IN;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we have a timeout, or no handles to poll, be satisfied
|
||||
* with just noticing we have messages waiting.
|
||||
*/
|
||||
if (timeout != 0 || nhandles == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* If no timeout and handles to poll, recurse to poll them,
|
||||
* too.
|
||||
*/
|
||||
recursed_result = poll_rest(FALSE, handles, nhandles, fds, nfds, 0);
|
||||
return (recursed_result == -1) ? -1 : 1 + recursed_result;
|
||||
} else if (/* QEMU: removed the following unneeded statement which causes
|
||||
* a compiler warning: ready >= WAIT_OBJECT_0 && */
|
||||
ready < WAIT_OBJECT_0 + nhandles) {
|
||||
for (f = fds; f < &fds[nfds]; ++f) {
|
||||
if ((HANDLE) f->fd == handles[ready - WAIT_OBJECT_0]) {
|
||||
f->revents = f->events;
|
||||
}
|
||||
}
|
||||
|
||||
/* If no timeout and polling several handles, recurse to poll
|
||||
* the rest of them.
|
||||
*/
|
||||
if (timeout == 0 && nhandles > 1) {
|
||||
/* Remove the handle that fired */
|
||||
int i;
|
||||
if (ready < nhandles - 1) {
|
||||
for (i = ready - WAIT_OBJECT_0 + 1; i < nhandles; i++) {
|
||||
handles[i-1] = handles[i];
|
||||
}
|
||||
}
|
||||
nhandles--;
|
||||
recursed_result = poll_rest(FALSE, handles, nhandles, fds, nfds, 0);
|
||||
return (recursed_result == -1) ? -1 : 1 + recursed_result;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
gint g_poll(GPollFD *fds, guint nfds, gint timeout)
|
||||
{
|
||||
HANDLE handles[MAXIMUM_WAIT_OBJECTS];
|
||||
gboolean poll_msgs = FALSE;
|
||||
GPollFD *f;
|
||||
gint nhandles = 0;
|
||||
int retval;
|
||||
|
||||
for (f = fds; f < &fds[nfds]; ++f) {
|
||||
if (f->fd == G_WIN32_MSG_HANDLE && (f->events & G_IO_IN)) {
|
||||
poll_msgs = TRUE;
|
||||
} else if (f->fd > 0) {
|
||||
/* Don't add the same handle several times into the array, as
|
||||
* docs say that is not allowed, even if it actually does seem
|
||||
* to work.
|
||||
*/
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < nhandles; i++) {
|
||||
if (handles[i] == (HANDLE) f->fd) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == nhandles) {
|
||||
if (nhandles == MAXIMUM_WAIT_OBJECTS) {
|
||||
g_warning("Too many handles to wait for!\n");
|
||||
break;
|
||||
} else {
|
||||
handles[nhandles++] = (HANDLE) f->fd;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (f = fds; f < &fds[nfds]; ++f) {
|
||||
f->revents = 0;
|
||||
}
|
||||
|
||||
if (timeout == -1) {
|
||||
timeout = INFINITE;
|
||||
}
|
||||
|
||||
/* Polling for several things? */
|
||||
if (nhandles > 1 || (nhandles > 0 && poll_msgs)) {
|
||||
/* First check if one or several of them are immediately
|
||||
* available
|
||||
*/
|
||||
retval = poll_rest(poll_msgs, handles, nhandles, fds, nfds, 0);
|
||||
|
||||
/* 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.
|
||||
*
|
||||
* Modification for QEMU: replaced timeout >= 10 by timeout > 0.
|
||||
*/
|
||||
if (retval == 0 && (timeout == INFINITE || timeout > 0)) {
|
||||
retval = poll_rest(poll_msgs, handles, nhandles,
|
||||
fds, nfds, timeout);
|
||||
}
|
||||
} else {
|
||||
/* Just polling for one thing, so no need to check first if
|
||||
* available immediately
|
||||
*/
|
||||
retval = poll_rest(poll_msgs, handles, nhandles, fds, nfds, timeout);
|
||||
}
|
||||
|
||||
if (retval == -1) {
|
||||
for (f = fds; f < &fds[nfds]; ++f) {
|
||||
f->revents = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
size_t getpagesize(void)
|
||||
{
|
||||
SYSTEM_INFO system_info;
|
||||
|
@ -288,9 +288,9 @@ QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name)
|
||||
static void qemu_opt_del(QemuOpt *opt)
|
||||
{
|
||||
QTAILQ_REMOVE(&opt->opts->head, opt, next);
|
||||
g_free(opt->name);
|
||||
g_free(opt->str);
|
||||
g_free(opt);
|
||||
free(opt->name);
|
||||
free(opt->str);
|
||||
free(opt);
|
||||
}
|
||||
|
||||
/* qemu_opt_set allows many settings for the same option.
|
||||
@ -327,7 +327,7 @@ const char *qemu_opt_get(QemuOpts *opts, const char *name)
|
||||
|
||||
/* Get a known option (or its default) and remove it from the list
|
||||
* all in one action. Return a malloced string of the option value.
|
||||
* Result must be freed by caller with g_free().
|
||||
* Result must be freed by caller with free().
|
||||
*/
|
||||
char *qemu_opt_get_del(QemuOpts *opts, const char *name)
|
||||
{
|
||||
@ -576,7 +576,7 @@ int qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val)
|
||||
opt->desc = find_desc_by_name(desc, name);
|
||||
if (!opt->desc && !opts_accepts_any(opts)) {
|
||||
qerror_report(QERR_INVALID_PARAMETER, name);
|
||||
g_free(opt);
|
||||
free(opt);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -598,7 +598,7 @@ int qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val)
|
||||
opt->desc = find_desc_by_name(desc, name);
|
||||
if (!opt->desc && !opts_accepts_any(opts)) {
|
||||
qerror_report(QERR_INVALID_PARAMETER, name);
|
||||
g_free(opt);
|
||||
free(opt);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -698,7 +698,7 @@ const char *qemu_opts_id(QemuOpts *opts)
|
||||
return opts->id;
|
||||
}
|
||||
|
||||
/* The id string will be g_free()d by qemu_opts_del */
|
||||
/* The id string will be free()d by qemu_opts_del */
|
||||
void qemu_opts_set_id(QemuOpts *opts, char *id)
|
||||
{
|
||||
opts->id = id;
|
||||
@ -719,8 +719,8 @@ void qemu_opts_del(QemuOpts *opts)
|
||||
qemu_opt_del(opt);
|
||||
}
|
||||
QTAILQ_REMOVE(&opts->list->head, opts, next);
|
||||
g_free(opts->id);
|
||||
g_free(opts);
|
||||
free(opts->id);
|
||||
free(opts);
|
||||
}
|
||||
|
||||
void qemu_opts_print(QemuOpts *opts)
|
||||
@ -1064,7 +1064,7 @@ static size_t count_opts_list(QemuOptsList *list)
|
||||
|
||||
void qemu_opts_free(QemuOptsList *list)
|
||||
{
|
||||
g_free(list);
|
||||
free(list);
|
||||
}
|
||||
|
||||
/* Realloc dst option list and append options from an option list (list)
|
||||
|
@ -277,7 +277,7 @@ static unsigned __stdcall win32_start_routine(void *arg)
|
||||
|
||||
if (data->mode == QEMU_THREAD_DETACHED) {
|
||||
data->uc->qemu_thread_data = NULL;
|
||||
g_free(data);
|
||||
free(data);
|
||||
data = NULL;
|
||||
}
|
||||
qemu_thread_exit(data->uc, start_routine(thread_arg));
|
||||
@ -323,7 +323,7 @@ void *qemu_thread_join(QemuThread *thread)
|
||||
ret = data->ret;
|
||||
assert(data->mode != QEMU_THREAD_DETACHED);
|
||||
DeleteCriticalSection(&data->cs);
|
||||
g_free(data);
|
||||
free(data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user