xref: /qemu/event-loop-base.c (revision 70ac26b9)
1 /*
2  * QEMU event-loop base
3  *
4  * Copyright (C) 2022 Red Hat Inc
5  *
6  * Authors:
7  *  Stefan Hajnoczi <stefanha@redhat.com>
8  *  Nicolas Saenz Julienne <nsaenzju@redhat.com>
9  *
10  * This work is licensed under the terms of the GNU GPL, version 2 or later.
11  * See the COPYING file in the top-level directory.
12  */
13 
14 #include "qemu/osdep.h"
15 #include "qom/object_interfaces.h"
16 #include "qapi/error.h"
17 #include "sysemu/event-loop-base.h"
18 
19 typedef struct {
20     const char *name;
21     ptrdiff_t offset; /* field's byte offset in EventLoopBase struct */
22 } EventLoopBaseParamInfo;
23 
24 static EventLoopBaseParamInfo aio_max_batch_info = {
25     "aio-max-batch", offsetof(EventLoopBase, aio_max_batch),
26 };
27 
28 static void event_loop_base_get_param(Object *obj, Visitor *v,
29         const char *name, void *opaque, Error **errp)
30 {
31     EventLoopBase *event_loop_base = EVENT_LOOP_BASE(obj);
32     EventLoopBaseParamInfo *info = opaque;
33     int64_t *field = (void *)event_loop_base + info->offset;
34 
35     visit_type_int64(v, name, field, errp);
36 }
37 
38 static void event_loop_base_set_param(Object *obj, Visitor *v,
39         const char *name, void *opaque, Error **errp)
40 {
41     EventLoopBaseClass *bc = EVENT_LOOP_BASE_GET_CLASS(obj);
42     EventLoopBase *base = EVENT_LOOP_BASE(obj);
43     EventLoopBaseParamInfo *info = opaque;
44     int64_t *field = (void *)base + info->offset;
45     int64_t value;
46 
47     if (!visit_type_int64(v, name, &value, errp)) {
48         return;
49     }
50 
51     if (value < 0) {
52         error_setg(errp, "%s value must be in range [0, %" PRId64 "]",
53                    info->name, INT64_MAX);
54         return;
55     }
56 
57     *field = value;
58 
59     if (bc->update_params) {
60         bc->update_params(base, errp);
61     }
62 
63     return;
64 }
65 
66 static void event_loop_base_complete(UserCreatable *uc, Error **errp)
67 {
68     EventLoopBaseClass *bc = EVENT_LOOP_BASE_GET_CLASS(uc);
69     EventLoopBase *base = EVENT_LOOP_BASE(uc);
70 
71     if (bc->init) {
72         bc->init(base, errp);
73     }
74 }
75 
76 static bool event_loop_base_can_be_deleted(UserCreatable *uc)
77 {
78     EventLoopBaseClass *bc = EVENT_LOOP_BASE_GET_CLASS(uc);
79     EventLoopBase *backend = EVENT_LOOP_BASE(uc);
80 
81     if (bc->can_be_deleted) {
82         return bc->can_be_deleted(backend);
83     }
84 
85     return true;
86 }
87 
88 static void event_loop_base_class_init(ObjectClass *klass, void *class_data)
89 {
90     UserCreatableClass *ucc = USER_CREATABLE_CLASS(klass);
91     ucc->complete = event_loop_base_complete;
92     ucc->can_be_deleted = event_loop_base_can_be_deleted;
93 
94     object_class_property_add(klass, "aio-max-batch", "int",
95                               event_loop_base_get_param,
96                               event_loop_base_set_param,
97                               NULL, &aio_max_batch_info);
98 }
99 
100 static const TypeInfo event_loop_base_info = {
101     .name = TYPE_EVENT_LOOP_BASE,
102     .parent = TYPE_OBJECT,
103     .instance_size = sizeof(EventLoopBase),
104     .class_size = sizeof(EventLoopBaseClass),
105     .class_init = event_loop_base_class_init,
106     .abstract = true,
107     .interfaces = (InterfaceInfo[]) {
108         { TYPE_USER_CREATABLE },
109         { }
110     }
111 };
112 
113 static void register_types(void)
114 {
115     type_register_static(&event_loop_base_info);
116 }
117 type_init(register_types);
118