70ac26b9e5
'event-loop-base' 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. 'EventLoopBaseClass' learns a new callback, 'can_be_deleted()' so as to mark 'MainLoop' as non-deletable. [1] For example: -object main-loop,id=main-loop,aio-max-batch=<value> Signed-off-by: Nicolas Saenz Julienne <nsaenzju@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Acked-by: Markus Armbruster <armbru@redhat.com> Message-id: 20220425075723.20019-3-nsaenzju@redhat.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
118 lines
3.1 KiB
C
118 lines
3.1 KiB
C
/*
|
|
* QEMU event-loop base
|
|
*
|
|
* Copyright (C) 2022 Red Hat Inc
|
|
*
|
|
* Authors:
|
|
* Stefan Hajnoczi <stefanha@redhat.com>
|
|
* Nicolas Saenz Julienne <nsaenzju@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.
|
|
*/
|
|
|
|
#include "qemu/osdep.h"
|
|
#include "qom/object_interfaces.h"
|
|
#include "qapi/error.h"
|
|
#include "sysemu/event-loop-base.h"
|
|
|
|
typedef struct {
|
|
const char *name;
|
|
ptrdiff_t offset; /* field's byte offset in EventLoopBase struct */
|
|
} EventLoopBaseParamInfo;
|
|
|
|
static EventLoopBaseParamInfo aio_max_batch_info = {
|
|
"aio-max-batch", offsetof(EventLoopBase, aio_max_batch),
|
|
};
|
|
|
|
static void event_loop_base_get_param(Object *obj, Visitor *v,
|
|
const char *name, void *opaque, Error **errp)
|
|
{
|
|
EventLoopBase *event_loop_base = EVENT_LOOP_BASE(obj);
|
|
EventLoopBaseParamInfo *info = opaque;
|
|
int64_t *field = (void *)event_loop_base + info->offset;
|
|
|
|
visit_type_int64(v, name, field, errp);
|
|
}
|
|
|
|
static void event_loop_base_set_param(Object *obj, Visitor *v,
|
|
const char *name, void *opaque, Error **errp)
|
|
{
|
|
EventLoopBaseClass *bc = EVENT_LOOP_BASE_GET_CLASS(obj);
|
|
EventLoopBase *base = EVENT_LOOP_BASE(obj);
|
|
EventLoopBaseParamInfo *info = opaque;
|
|
int64_t *field = (void *)base + info->offset;
|
|
int64_t value;
|
|
|
|
if (!visit_type_int64(v, name, &value, errp)) {
|
|
return;
|
|
}
|
|
|
|
if (value < 0) {
|
|
error_setg(errp, "%s value must be in range [0, %" PRId64 "]",
|
|
info->name, INT64_MAX);
|
|
return;
|
|
}
|
|
|
|
*field = value;
|
|
|
|
if (bc->update_params) {
|
|
bc->update_params(base, errp);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
static void event_loop_base_complete(UserCreatable *uc, Error **errp)
|
|
{
|
|
EventLoopBaseClass *bc = EVENT_LOOP_BASE_GET_CLASS(uc);
|
|
EventLoopBase *base = EVENT_LOOP_BASE(uc);
|
|
|
|
if (bc->init) {
|
|
bc->init(base, errp);
|
|
}
|
|
}
|
|
|
|
static bool event_loop_base_can_be_deleted(UserCreatable *uc)
|
|
{
|
|
EventLoopBaseClass *bc = EVENT_LOOP_BASE_GET_CLASS(uc);
|
|
EventLoopBase *backend = EVENT_LOOP_BASE(uc);
|
|
|
|
if (bc->can_be_deleted) {
|
|
return bc->can_be_deleted(backend);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static void event_loop_base_class_init(ObjectClass *klass, void *class_data)
|
|
{
|
|
UserCreatableClass *ucc = USER_CREATABLE_CLASS(klass);
|
|
ucc->complete = event_loop_base_complete;
|
|
ucc->can_be_deleted = event_loop_base_can_be_deleted;
|
|
|
|
object_class_property_add(klass, "aio-max-batch", "int",
|
|
event_loop_base_get_param,
|
|
event_loop_base_set_param,
|
|
NULL, &aio_max_batch_info);
|
|
}
|
|
|
|
static const TypeInfo event_loop_base_info = {
|
|
.name = TYPE_EVENT_LOOP_BASE,
|
|
.parent = TYPE_OBJECT,
|
|
.instance_size = sizeof(EventLoopBase),
|
|
.class_size = sizeof(EventLoopBaseClass),
|
|
.class_init = event_loop_base_class_init,
|
|
.abstract = true,
|
|
.interfaces = (InterfaceInfo[]) {
|
|
{ TYPE_USER_CREATABLE },
|
|
{ }
|
|
}
|
|
};
|
|
|
|
static void register_types(void)
|
|
{
|
|
type_register_static(&event_loop_base_info);
|
|
}
|
|
type_init(register_types);
|