[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 2/3] util/main-loop: Introduce the main loop into QOM
From: |
Nicolas Saenz Julienne |
Subject: |
[PATCH 2/3] util/main-loop: Introduce the main loop into QOM |
Date: |
Mon, 21 Feb 2022 18:08:44 +0100 |
'event-loop-backend' provides basic property handling for all
'AioContext' based event loops. So let's define a new 'MainLoopClass'
that inherits from it. This will permit tweaking the main loop's
properties through qapi as well as through the command line using the
'-object' keyword[1]. Only one instance of 'MainLoopClass' might be
created at any time.
'EventLoopBackendClass' learns a new callback, 'can_be_deleted()' so as
to mark 'MainLoop' as non-deletable.
Signed-off-by: Nicolas Saenz Julienne <nsaenzju@redhat.com>
[1] For example:
-object main-loop,id=main-loop,poll-max-ns=<value>
---
include/qemu/main-loop.h | 11 ++++++++++
qapi/qom.json | 10 ++++++----
qga/meson.build | 2 +-
tests/unit/meson.build | 10 +++++-----
util/event-loop.c | 13 ++++++++++++
util/event-loop.h | 1 +
util/main-loop.c | 43 ++++++++++++++++++++++++++++++++++++++++
7 files changed, 80 insertions(+), 10 deletions(-)
diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h
index 8dbc6fcb89..fea5a3e9d4 100644
--- a/include/qemu/main-loop.h
+++ b/include/qemu/main-loop.h
@@ -26,9 +26,20 @@
#define QEMU_MAIN_LOOP_H
#include "block/aio.h"
+#include "qom/object.h"
+#include "util/event-loop.h"
#define SIG_IPI SIGUSR1
+#define TYPE_MAIN_LOOP "main-loop"
+
+struct MainLoop {
+ EventLoopBackend parent_obj;
+};
+typedef struct MainLoop MainLoop;
+
+DECLARE_INSTANCE_CHECKER(MainLoop, MAIN_LOOP, TYPE_MAIN_LOOP)
+
/**
* qemu_init_main_loop: Set up the process so that it can run the main loop.
*
diff --git a/qapi/qom.json b/qapi/qom.json
index eeb5395ff3..e7730ef62f 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -500,9 +500,9 @@
'*grab-toggle': 'GrabToggleKeys' } }
##
-# @IothreadProperties:
+# @EventLoopBackendProperties:
#
-# Properties for iothread objects.
+# Properties for iothread and main-loop objects.
#
# @poll-max-ns: the maximum number of nanoseconds to busy wait for events.
# 0 means polling is disabled (default: 32768 on POSIX hosts,
@@ -522,7 +522,7 @@
#
# Since: 2.0
##
-{ 'struct': 'IothreadProperties',
+{ 'struct': 'EventLoopBackendProperties',
'data': { '*poll-max-ns': 'int',
'*poll-grow': 'int',
'*poll-shrink': 'int',
@@ -818,6 +818,7 @@
{ 'name': 'input-linux',
'if': 'CONFIG_LINUX' },
'iothread',
+ 'main-loop',
{ 'name': 'memory-backend-epc',
'if': 'CONFIG_LINUX' },
'memory-backend-file',
@@ -882,7 +883,8 @@
'input-barrier': 'InputBarrierProperties',
'input-linux': { 'type': 'InputLinuxProperties',
'if': 'CONFIG_LINUX' },
- 'iothread': 'IothreadProperties',
+ 'iothread': 'EventLoopBackendProperties',
+ 'main-loop': 'EventLoopBackendProperties',
'memory-backend-epc': { 'type': 'MemoryBackendEpcProperties',
'if': 'CONFIG_LINUX' },
'memory-backend-file': 'MemoryBackendFileProperties',
diff --git a/qga/meson.build b/qga/meson.build
index 1ee9dca60b..3051473e04 100644
--- a/qga/meson.build
+++ b/qga/meson.build
@@ -52,7 +52,7 @@ qga_ss = qga_ss.apply(config_host, strict: false)
qga = executable('qemu-ga', qga_ss.sources(),
link_args: config_host['LIBS_QGA'].split(),
- dependencies: [qemuutil, libudev],
+ dependencies: [qemuutil, libudev, qom],
install: true)
all_qga = [qga]
diff --git a/tests/unit/meson.build b/tests/unit/meson.build
index 64a5e7bfde..7a1af584dd 100644
--- a/tests/unit/meson.build
+++ b/tests/unit/meson.build
@@ -51,7 +51,7 @@ tests = {
if have_system or have_tools
tests += {
- 'test-qmp-event': [testqapi],
+ 'test-qmp-event': [testqapi, qom],
}
endif
@@ -120,17 +120,17 @@ endif
if have_system
tests += {
'test-iov': [],
- 'test-qmp-cmds': [testqapi],
+ 'test-qmp-cmds': [testqapi, qom],
'test-xbzrle': [migration],
- 'test-timed-average': [],
- 'test-util-sockets': ['socket-helpers.c'],
+ 'test-timed-average': [qom],
+ 'test-util-sockets': ['socket-helpers.c', qom],
'test-base64': [],
'test-bufferiszero': [],
'test-vmstate': [migration, io],
'test-yank': ['socket-helpers.c', qom, io, chardev]
}
if config_host_data.get('CONFIG_INOTIFY1')
- tests += {'test-util-filemonitor': []}
+ tests += {'test-util-filemonitor': [qom]}
endif
# Some tests: test-char, test-qdev-global-props, and test-qga,
diff --git a/util/event-loop.c b/util/event-loop.c
index f3e50909a0..c0ddd61f20 100644
--- a/util/event-loop.c
+++ b/util/event-loop.c
@@ -98,10 +98,23 @@ event_loop_backend_complete(UserCreatable *uc, Error **errp)
}
}
+static bool event_loop_backend_can_be_deleted(UserCreatable *uc)
+{
+ EventLoopBackendClass *bc = EVENT_LOOP_BACKEND_GET_CLASS(uc);
+ EventLoopBackend *backend = EVENT_LOOP_BACKEND(uc);
+
+ if (bc->can_be_deleted) {
+ return bc->can_be_deleted(backend);
+ }
+
+ return true;
+}
+
static void event_loop_backend_class_init(ObjectClass *klass, void *class_data)
{
UserCreatableClass *ucc = USER_CREATABLE_CLASS(klass);
ucc->complete = event_loop_backend_complete;
+ ucc->can_be_deleted = event_loop_backend_can_be_deleted;
object_class_property_add(klass, "poll-max-ns", "int",
event_loop_backend_get_param,
diff --git a/util/event-loop.h b/util/event-loop.h
index 8883a0d086..34cf9309af 100644
--- a/util/event-loop.h
+++ b/util/event-loop.h
@@ -24,6 +24,7 @@ struct EventLoopBackendClass {
ObjectClass parent_class;
void (*init)(EventLoopBackend *backend, Error **errp);
+ bool (*can_be_deleted)(EventLoopBackend *backend);
};
struct EventLoopBackend {
diff --git a/util/main-loop.c b/util/main-loop.c
index 4d5a5b9943..395fd9bd3e 100644
--- a/util/main-loop.c
+++ b/util/main-loop.c
@@ -33,6 +33,7 @@
#include "qemu/error-report.h"
#include "qemu/queue.h"
#include "qemu/compiler.h"
+#include "qom/object.h"
#ifndef _WIN32
#include <sys/wait.h>
@@ -184,6 +185,48 @@ int qemu_init_main_loop(Error **errp)
return 0;
}
+MainLoop *mloop;
+
+static void main_loop_init(EventLoopBackend *bc, Error **errp)
+{
+ MainLoop *m = MAIN_LOOP(bc);
+
+ if (mloop) {
+ error_setg(errp, "only one main-loop instance allowed");
+ return;
+ }
+
+ mloop = m;
+ return;
+}
+
+static bool main_loop_can_be_deleted(EventLoopBackend *bc)
+{
+ return false;
+}
+
+static void main_loop_class_init(ObjectClass *oc, void *class_data)
+{
+ EventLoopBackendClass *bc = EVENT_LOOP_BACKEND_CLASS(oc);
+
+ bc->init = main_loop_init;
+ bc->can_be_deleted = main_loop_can_be_deleted;
+}
+
+static const TypeInfo main_loop_info = {
+ .name = TYPE_MAIN_LOOP,
+ .parent = TYPE_EVENT_LOOP_BACKEND,
+ .class_init = main_loop_class_init,
+ .instance_size = sizeof(MainLoop),
+};
+
+static void main_loop_register_types(void)
+{
+ type_register_static(&main_loop_info);
+}
+
+type_init(main_loop_register_types)
+
static int max_priority;
#ifndef _WIN32
--
2.35.1