diff options
author | Takashi Sakamoto <o-takashi@sakamocchi.jp> | 2022-05-05 16:16:39 +0900 |
---|---|---|
committer | 坂本 貴史 <o-takashi@sakamocchi.jp> | 2022-05-05 20:51:53 +0900 |
commit | 72a2dda64080c419056c9f89a05a68edd42faf47 (patch) | |
tree | 6fc9b7f009e6d3352c364c21e98a48c1c6b2668f | |
parent | 02b890b12bdb04b7265e6f9dba80291b683c3efe (diff) | |
download | libhinoko-72a2dda64080c419056c9f89a05a68edd42faf47.tar.gz |
fw_iso_ctx: add generation property
This commit adds "generation" property to object classes which implement
Hinoko.FwIsoResource interface. The change of property is notified by
GObject property notification mechanism.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
-rwxr-xr-x | samples/iso-resource | 8 | ||||
-rw-r--r-- | src/fw_iso_resource.c | 12 | ||||
-rw-r--r-- | src/fw_iso_resource_auto.c | 41 | ||||
-rw-r--r-- | src/fw_iso_resource_once.c | 30 | ||||
-rw-r--r-- | src/fw_iso_resource_private.c | 19 | ||||
-rw-r--r-- | src/fw_iso_resource_private.h | 12 | ||||
-rw-r--r-- | tests/fw-iso-resource-auto | 1 | ||||
-rw-r--r-- | tests/fw-iso-resource-once | 4 |
8 files changed, 103 insertions, 24 deletions
diff --git a/samples/iso-resource b/samples/iso-resource index 0a415c2..939f0f9 100755 --- a/samples/iso-resource +++ b/samples/iso-resource @@ -21,7 +21,7 @@ th.start() def handle_event(res, channel, bandwidth, exception, ev_name): print('event:', ev_name) if exception is None: - print(' ', channel, bandwidth) + print(' ', channel, bandwidth, res.get_property('generation')) elif exception.matches(Hinoko.fw_iso_resource_error_quark(), Hinoko.FwIsoResourceError.EVENT): print(' ', exception) @@ -43,7 +43,7 @@ for i in range(2): print(e) else: print('result: allocate') - print(' ', use_channel, use_bandwidth) + print(' ', use_channel, use_bandwidth, res.get_property('generation')) sleep(2) @@ -54,7 +54,7 @@ for i in range(2): print(e) else: print('result: deallocate') - print(' ', use_channel, use_bandwidth) + print(' ', use_channel, use_bandwidth, res.get_property('generation')) sleep(2) @@ -73,7 +73,7 @@ src = res.create_source() src.attach(ctx) def print_props(res): - for prop in ('is-allocated', 'channel', 'bandwidth'): + for prop in ('is-allocated', 'channel', 'bandwidth', 'generation'): print(' {}: {}'.format(prop, res.get_property(prop))) for i in range(2): diff --git a/src/fw_iso_resource.c b/src/fw_iso_resource.c index 60b1cb9..0d2e2e8 100644 --- a/src/fw_iso_resource.c +++ b/src/fw_iso_resource.c @@ -26,6 +26,18 @@ G_DEFINE_QUARK(hinoko-fw-iso-resource-error-quark, hinoko_fw_iso_resource_error) static void hinoko_fw_iso_resource_default_init(HinokoFwIsoResourceInterface *iface) { /** + * HinokoFwIsoResource::generation: + * + * The numeric value of current generation for bus topology. + */ + g_object_interface_install_property(iface, + g_param_spec_uint(GENERATION_PROP_NAME, "generation", + "The numeric value of current generation for bus topology", + 0, G_MAXUINT, + 0, + G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY)); + + /** * HinokoFwIsoResource::allocated: * @self: A [iface@FwIsoResource]. * @channel: The deallocated channel number. diff --git a/src/fw_iso_resource_auto.c b/src/fw_iso_resource_auto.c index 870996e..9445b93 100644 --- a/src/fw_iso_resource_auto.c +++ b/src/fw_iso_resource_auto.c @@ -47,12 +47,11 @@ static const char *const err_msgs[] = { g_set_error_literal(error, HINOKO_FW_ISO_RESOURCE_AUTO_ERROR, code, err_msgs[code]) enum fw_iso_resource_auto_prop_type { - FW_ISO_RESOURCE_AUTO_PROP_IS_ALLOCATED = 1, + FW_ISO_RESOURCE_AUTO_PROP_IS_ALLOCATED = FW_ISO_RESOURCE_PROP_TYPE_COUNT, FW_ISO_RESOURCE_AUTO_PROP_CHANNEL, FW_ISO_RESOURCE_AUTO_PROP_BANDWIDTH, FW_ISO_RESOURCE_AUTO_PROP_COUNT, }; -static GParamSpec *fw_iso_resource_auto_props[FW_ISO_RESOURCE_AUTO_PROP_COUNT] = { NULL, }; static void fw_iso_resource_auto_get_property(GObject *obj, guint id, GValue *val, GParamSpec *spec) @@ -74,7 +73,7 @@ static void fw_iso_resource_auto_get_property(GObject *obj, guint id, g_value_set_uint(val, priv->bandwidth); break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, id, spec); + fw_iso_resource_state_get_property(&priv->state, obj, id, val, spec); break; } @@ -99,26 +98,24 @@ static void hinoko_fw_iso_resource_auto_class_init(HinokoFwIsoResourceAutoClass gobject_class->get_property = fw_iso_resource_auto_get_property; gobject_class->finalize = fw_iso_resource_auto_finalize; - fw_iso_resource_auto_props[FW_ISO_RESOURCE_AUTO_PROP_IS_ALLOCATED] = + fw_iso_resource_class_override_properties(gobject_class); + + g_object_class_install_property(gobject_class, FW_ISO_RESOURCE_AUTO_PROP_IS_ALLOCATED, g_param_spec_boolean("is-allocated", "is-allocated", "Whether to allocated or not.", - FALSE, G_PARAM_READABLE); + FALSE, G_PARAM_READABLE)); - fw_iso_resource_auto_props[FW_ISO_RESOURCE_AUTO_PROP_CHANNEL] = + g_object_class_install_property(gobject_class, FW_ISO_RESOURCE_AUTO_PROP_CHANNEL, g_param_spec_uint("channel", "channel", "The allocated channel number.", 0, G_MAXUINT, 0, - G_PARAM_READABLE); + G_PARAM_READABLE)); - fw_iso_resource_auto_props[FW_ISO_RESOURCE_AUTO_PROP_BANDWIDTH] = + g_object_class_install_property(gobject_class, FW_ISO_RESOURCE_AUTO_PROP_BANDWIDTH, g_param_spec_uint("bandwidth", "bandwidth", "The allocated amount of bandwidth.", 0, G_MAXUINT, 0, - G_PARAM_READABLE); - - g_object_class_install_properties(gobject_class, - FW_ISO_RESOURCE_AUTO_PROP_COUNT, - fw_iso_resource_auto_props); + G_PARAM_READABLE)); } static void hinoko_fw_iso_resource_auto_init(HinokoFwIsoResourceAuto *self) @@ -188,8 +185,12 @@ static void handle_bus_reset_event(HinokoFwIsoResourceAuto *self, { HinokoFwIsoResourceAutoPrivate *priv = hinoko_fw_iso_resource_auto_get_instance_private(self); + gboolean need_notify = (priv->state.bus_state.generation != ev->generation); memcpy(&priv->state.bus_state, ev, sizeof(*ev)); + + if (need_notify) + g_object_notify(G_OBJECT(self), GENERATION_PROP_NAME); } void fw_iso_resource_auto_handle_event(HinokoFwIsoResource *inst, const union fw_cdev_event *event) @@ -217,14 +218,22 @@ static gboolean fw_iso_resource_auto_create_source(HinokoFwIsoResource *inst, GS { HinokoFwIsoResourceAuto *self; HinokoFwIsoResourceAutoPrivate *priv; + guint generation; g_return_val_if_fail(HINOKO_IS_FW_ISO_RESOURCE_AUTO(inst), FALSE); self = HINOKO_FW_ISO_RESOURCE_AUTO(inst); priv = hinoko_fw_iso_resource_auto_get_instance_private(self); - return fw_iso_resource_state_create_source(&priv->state, inst, - fw_iso_resource_auto_handle_event, source, - error); + generation = priv->state.bus_state.generation; + + if (!fw_iso_resource_state_create_source(&priv->state, inst, + fw_iso_resource_auto_handle_event, source, error)) + return FALSE; + + if (generation != priv->state.bus_state.generation) + g_object_notify(G_OBJECT(self), GENERATION_PROP_NAME); + + return TRUE; } static void fw_iso_resource_iface_init(HinokoFwIsoResourceInterface *iface) diff --git a/src/fw_iso_resource_once.c b/src/fw_iso_resource_once.c index c126435..c1788cf 100644 --- a/src/fw_iso_resource_once.c +++ b/src/fw_iso_resource_once.c @@ -20,6 +20,15 @@ G_DEFINE_TYPE_WITH_CODE(HinokoFwIsoResourceOnce, hinoko_fw_iso_resource_once, G_ G_ADD_PRIVATE(HinokoFwIsoResourceOnce) G_IMPLEMENT_INTERFACE(HINOKO_TYPE_FW_ISO_RESOURCE, fw_iso_resource_iface_init)) +static void fw_iso_resource_once_get_property(GObject *obj, guint id, GValue *val, GParamSpec *spec) +{ + HinokoFwIsoResourceOnce *self = HINOKO_FW_ISO_RESOURCE_ONCE(obj); + HinokoFwIsoResourceOncePrivate *priv = + hinoko_fw_iso_resource_once_get_instance_private(self); + + fw_iso_resource_state_get_property(&priv->state, obj, id, val, spec); +} + static void fw_iso_resource_once_finalize(GObject *obj) { HinokoFwIsoResourceOnce *self = HINOKO_FW_ISO_RESOURCE_ONCE(obj); @@ -35,7 +44,10 @@ static void hinoko_fw_iso_resource_once_class_init(HinokoFwIsoResourceOnceClass { GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + gobject_class->get_property = fw_iso_resource_once_get_property; gobject_class->finalize = fw_iso_resource_once_finalize; + + fw_iso_resource_class_override_properties(gobject_class); } static void hinoko_fw_iso_resource_once_init(HinokoFwIsoResourceOnce *self) @@ -80,8 +92,12 @@ static void handle_bus_reset_event(HinokoFwIsoResourceOnce *self, { HinokoFwIsoResourceOncePrivate *priv = hinoko_fw_iso_resource_once_get_instance_private(self); + gboolean need_notify = (priv->state.bus_state.generation != ev->generation); memcpy(&priv->state.bus_state, ev, sizeof(*ev)); + + if (need_notify) + g_object_notify(G_OBJECT(self), GENERATION_PROP_NAME); } void fw_iso_resource_once_handle_event(HinokoFwIsoResource *inst, const union fw_cdev_event *event) @@ -109,14 +125,22 @@ static gboolean fw_iso_resource_once_create_source(HinokoFwIsoResource *inst, GS { HinokoFwIsoResourceOnce *self; HinokoFwIsoResourceOncePrivate *priv; + guint generation; g_return_val_if_fail(HINOKO_IS_FW_ISO_RESOURCE_ONCE(inst), FALSE); self = HINOKO_FW_ISO_RESOURCE_ONCE(inst); priv = hinoko_fw_iso_resource_once_get_instance_private(self); - return fw_iso_resource_state_create_source(&priv->state, inst, - fw_iso_resource_once_handle_event, source, - error); + generation = priv->state.bus_state.generation; + + if (!fw_iso_resource_state_create_source(&priv->state, inst, + fw_iso_resource_once_handle_event, source, error)) + return FALSE; + + if (generation != priv->state.bus_state.generation) + g_object_notify(G_OBJECT(self), GENERATION_PROP_NAME); + + return TRUE; } static void fw_iso_resource_iface_init(HinokoFwIsoResourceInterface *iface) diff --git a/src/fw_iso_resource_private.c b/src/fw_iso_resource_private.c index 98f9294..cf5513d 100644 --- a/src/fw_iso_resource_private.c +++ b/src/fw_iso_resource_private.c @@ -35,6 +35,25 @@ typedef struct { void (*handle_event)(HinokoFwIsoResource *self, const union fw_cdev_event *event); } FwIsoResourceSource; +void fw_iso_resource_class_override_properties(GObjectClass *gobject_class) +{ + g_object_class_override_property(gobject_class, FW_ISO_RESOURCE_PROP_TYPE_GENERATION, + GENERATION_PROP_NAME); +} + +void fw_iso_resource_state_get_property(const struct fw_iso_resource_state *state, GObject *obj, + guint id, GValue *val, GParamSpec *spec) +{ + switch (id) { + case FW_ISO_RESOURCE_PROP_TYPE_GENERATION: + g_value_set_uint(val, state->bus_state.generation); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, id, spec); + break; + } +} + void fw_iso_resource_state_init(struct fw_iso_resource_state *state) { state->fd = -1; diff --git a/src/fw_iso_resource_private.h b/src/fw_iso_resource_private.h index 5e9fa9a..2ee8357 100644 --- a/src/fw_iso_resource_private.h +++ b/src/fw_iso_resource_private.h @@ -8,6 +8,8 @@ #include <errno.h> #include <sys/ioctl.h> +#define GENERATION_PROP_NAME "generation" + #define ALLOCATED_SIGNAL_NAME "allocated" #define DEALLOCATED_SIGNAL_NAME "deallocated" @@ -21,6 +23,16 @@ struct fw_iso_resource_state { struct fw_cdev_event_bus_reset bus_state; }; +enum fw_iso_resource_prop_type { + FW_ISO_RESOURCE_PROP_TYPE_GENERATION = 1, + FW_ISO_RESOURCE_PROP_TYPE_COUNT, +}; + +void fw_iso_resource_class_override_properties(GObjectClass *gobject_class); + +void fw_iso_resource_state_get_property(const struct fw_iso_resource_state *state, GObject *obj, + guint id, GValue *val, GParamSpec *spec); + void fw_iso_resource_state_init(struct fw_iso_resource_state *state); void fw_iso_resource_state_release(struct fw_iso_resource_state *state); diff --git a/tests/fw-iso-resource-auto b/tests/fw-iso-resource-auto index 82517d6..9f0835f 100644 --- a/tests/fw-iso-resource-auto +++ b/tests/fw-iso-resource-auto @@ -14,6 +14,7 @@ props = ( 'is-allocated', 'channel', 'bandwidth', + 'generation', ) methods = ( 'new', diff --git a/tests/fw-iso-resource-once b/tests/fw-iso-resource-once index 62d2800..cc0ce28 100644 --- a/tests/fw-iso-resource-once +++ b/tests/fw-iso-resource-once @@ -10,7 +10,9 @@ gi.require_version('Hinoko', '0.0') from gi.repository import Hinoko target = Hinoko.FwIsoResourceOnce() -props = () +props = ( + 'generation', +) methods = ( 'new', 'open', |