3 #include "string-visitor.h"
5 #define MAX_NAME (32 + 1)
6 #define MAX_TYPENAME (32 + 1)
11 char typename
[MAX_TYPENAME
];
14 PlugPropertyAccessor
*getter
;
17 PlugPropertyAccessor
*setter
;
25 void plug_add_property_full(Plug
*plug
, const char *name
,
26 PlugPropertyAccessor
*getter
, void *getter_opaque
,
27 PlugPropertyAccessor
*setter
, void *setter_opaque
,
28 const char *typename
, int flags
)
30 PlugProperty
*prop
= qemu_mallocz(sizeof(*prop
));
32 snprintf(prop
->name
, sizeof(prop
->name
), "%s", name
);
33 snprintf(prop
->typename
, sizeof(prop
->typename
), "%s", typename
);
35 prop
->getter
= getter
;
36 prop
->getter_opaque
= getter_opaque
;
38 prop
->setter
= setter
;
39 prop
->setter_opaque
= setter_opaque
;
43 prop
->next
= plug
->first_prop
;
44 plug
->first_prop
= prop
;
47 static PlugProperty
*plug_find_property(Plug
*plug
, const char *name
)
51 for (prop
= plug
->first_prop
; prop
; prop
= prop
->next
) {
52 if (strcmp(prop
->name
, name
) == 0) {
60 void plug_set_property(Plug
*plug
, const char *name
, Visitor
*v
, Error
**errp
)
62 PlugProperty
*prop
= plug_find_property(plug
, name
);
65 error_set(errp
, QERR_PROPERTY_NOT_FOUND
, type_get_id(TYPE_INSTANCE(plug
)), name
);
69 if (!(prop
->flags
& PROP_F_WRITE
) || (prop
->flags
& PROP_F_LOCKED
)) {
70 error_set(errp
, QERR_PROPERTY_READ_ONLY
, type_get_id(TYPE_INSTANCE(plug
)), name
);
74 prop
->setter(plug
, name
, v
, prop
->setter_opaque
, errp
);
77 void plug_get_property(Plug
*plug
, const char *name
, Visitor
*v
, Error
**errp
)
79 PlugProperty
*prop
= plug_find_property(plug
, name
);
82 error_set(errp
, QERR_PROPERTY_NOT_FOUND
, type_get_id(TYPE_INSTANCE(plug
)), name
);
83 printf("property not found\n");
87 if (!(prop
->flags
& PROP_F_READ
)) {
88 error_set(errp
, QERR_PROPERTY_READ_ONLY
, type_get_id(TYPE_INSTANCE(plug
)), name
);
89 printf("property read only\n");
94 prop
->getter(plug
, name
, v
, prop
->getter_opaque
, errp
);
97 void plug_lock_property(Plug
*plug
, const char *name
)
99 PlugProperty
*prop
= plug_find_property(plug
, name
);
101 assert(prop
!= NULL
);
103 prop
->flags
|= PROP_F_LOCKED
;
106 void plug_unlock_property(Plug
*plug
, const char *name
)
108 PlugProperty
*prop
= plug_find_property(plug
, name
);
110 assert(prop
!= NULL
);
112 prop
->flags
&= ~PROP_F_LOCKED
;
115 void plug_lock_all_properties(Plug
*plug
)
119 for (prop
= plug
->first_prop
; prop
; prop
= prop
->next
) {
120 prop
->flags
|= PROP_F_LOCKED
;
124 void plug_unlock_all_properties(Plug
*plug
)
128 for (prop
= plug
->first_prop
; prop
; prop
= prop
->next
) {
129 prop
->flags
&= ~PROP_F_LOCKED
;
133 void plug_foreach_property(Plug
*plug
, PropertyEnumerator
*enumfn
, void *opaque
)
137 for (prop
= plug
->first_prop
; prop
; prop
= prop
->next
) {
138 enumfn(plug
, prop
->name
, prop
->typename
, prop
->flags
, opaque
);
142 void plug_set_realized(Plug
*plug
, bool realized
)
144 PlugClass
*class = PLUG_GET_CLASS(plug
);
145 bool old_value
= plug
->realized
;
147 plug
->realized
= realized
;
149 if (plug
->realized
&& !old_value
) {
150 if (class->realize
) {
151 class->realize(plug
);
153 } else if (!plug
->realized
&& old_value
) {
154 if (class->unrealize
) {
155 class->unrealize(plug
);
160 bool plug_get_realized(Plug
*plug
)
162 return plug
->realized
;
165 char *plug_get_property_str(Plug
*plug
, const char *name
, Error
**errp
)
167 StringOutputVisitor sov
;
169 string_output_visitor_init(&sov
);
170 plug_get_property(plug
, name
, &sov
.parent
, errp
);
172 return qemu_strdup(sov
.value
);
175 static void plug_propagate_realized(Plug
*plug
, const char *name
,
176 const char *typename
, int flags
,
179 if (strstart(typename
, "plug<", NULL
)) {
183 child_name
= plug_get_property_str(plug
, name
, NULL
);
184 child_plug
= PLUG(type_find_by_id(child_name
));
186 plug_set_realized(child_plug
, plug_get_realized(plug
));
188 qemu_free(child_name
);
192 void plug_realize_all(Plug
*plug
)
194 /* This doesn't loop infinitely because the callbacks are only called when
195 * the state changes. */
196 plug_set_realized(plug
, true);
197 plug_lock_all_properties(plug
);
198 plug_foreach_property(plug
, plug_propagate_realized
, NULL
);
201 void plug_unrealize_all(Plug
*plug
)
203 /* This doesn't loop infinitely because the callbacks are only called when
204 * the state changes. */
205 plug_set_realized(plug
, false);
206 plug_unlock_all_properties(plug
);
207 plug_foreach_property(plug
, plug_propagate_realized
, NULL
);
210 static void plug_class_initfn(TypeClass
*base_class
)
212 PlugClass
*class = PLUG_CLASS(base_class
);
214 class->realize
= plug_realize_all
;
215 class->unrealize
= plug_unrealize_all
;
218 void plug_initialize(Plug
*plug
, const char *id
)
220 type_initialize(plug
, TYPE_PLUG
, id
);
223 void plug_finalize(Plug
*plug
)
228 static void plug_initfn(TypeInstance
*inst
)
230 Plug
*obj
= PLUG(inst
);
232 plug_add_property_bool(obj
, "realized",
238 static const TypeInfo plug_type_info
= {
240 .instance_size
= sizeof(Plug
),
241 .class_size
= sizeof(PlugClass
),
242 .instance_init
= plug_initfn
,
243 .class_init
= plug_class_initfn
,
246 static void register_devices(void)
248 type_register_static(&plug_type_info
);
251 device_init(register_devices
);