aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2022-05-05 11:37:24 +0900
committer坂本 貴史 <o-takashi@sakamocchi.jp>2022-05-05 16:09:50 +0900
commit11f1294466b534fa1dbd456809e939d4ca138d52 (patch)
treebe60268d9efd8ce2214a9a85b93601e8b8d4237c
parent7180a9a1accdfcbf1dacdf9a747493640a51ea6b (diff)
downloadlibhinoko-11f1294466b534fa1dbd456809e939d4ca138d52.tar.gz
fw_iso_ctx: add class virtual function for future use
It's planned to make Hinoko.FwIsoCtx as interface. It will provide some virtual functions. This commit adds and implements virtual functions. At present, they are added to base abstraction class. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
-rw-r--r--src/fw_iso_ctx.h9
-rw-r--r--src/fw_iso_rx_multiple.c73
-rw-r--r--src/fw_iso_rx_single.c73
-rw-r--r--src/fw_iso_tx.c72
4 files changed, 227 insertions, 0 deletions
diff --git a/src/fw_iso_ctx.h b/src/fw_iso_ctx.h
index dd28b05..6b41369 100644
--- a/src/fw_iso_ctx.h
+++ b/src/fw_iso_ctx.h
@@ -17,6 +17,15 @@ GQuark hinoko_fw_iso_ctx_error_quark();
struct _HinokoFwIsoCtxClass {
GObjectClass parent_class;
+ void (*stop)(HinokoFwIsoCtx *self);
+
+ gboolean (*get_cycle_timer)(HinokoFwIsoCtx *self, gint clock_id,
+ HinokoCycleTimer *const *cycle_timer, GError **error);
+
+ gboolean (*flush_completions)(HinokoFwIsoCtx *self, GError **error);
+
+ gboolean (*create_source)(HinokoFwIsoCtx *self, GSource **source, GError **error);
+
/**
* HinokoFwIsoCtxClass::stopped:
* @self: A [class@FwIsoCtx].
diff --git a/src/fw_iso_rx_multiple.c b/src/fw_iso_rx_multiple.c
index bbe8e91..88fc809 100644
--- a/src/fw_iso_rx_multiple.c
+++ b/src/fw_iso_rx_multiple.c
@@ -13,6 +13,8 @@ struct ctx_payload {
unsigned int length;
};
typedef struct {
+ struct fw_iso_ctx_state state;
+
GByteArray *channels;
guint prev_offset;
@@ -24,6 +26,9 @@ typedef struct {
guint chunks_per_irq;
guint accumulated_chunk_count;
} HinokoFwIsoRxMultiplePrivate;
+
+static void fw_iso_ctx_class_init(HinokoFwIsoCtxClass *parent_class);
+
G_DEFINE_TYPE_WITH_PRIVATE(HinokoFwIsoRxMultiple, hinoko_fw_iso_rx_multiple, HINOKO_TYPE_FW_ISO_CTX)
enum fw_iso_rx_multiple_prop_type {
@@ -73,11 +78,14 @@ static void fw_iso_rx_multiple_set_property(GObject *obj, guint id,
static void hinoko_fw_iso_rx_multiple_class_init(HinokoFwIsoRxMultipleClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+ HinokoFwIsoCtxClass *parent_class = HINOKO_FW_ISO_CTX_CLASS(klass);
gobject_class->finalize = fw_iso_rx_multiple_finalize;
gobject_class->get_property = fw_iso_rx_multiple_get_property;
gobject_class->set_property = fw_iso_rx_multiple_set_property;
+ fw_iso_ctx_class_init(parent_class);
+
fw_iso_rx_multiple_props[FW_ISO_RX_MULTIPLE_PROP_TYPE_CHANNELS] =
g_param_spec_boxed("channels", "channels",
"The array with elements to represent "
@@ -120,6 +128,50 @@ static void hinoko_fw_iso_rx_multiple_init(HinokoFwIsoRxMultiple *self)
return;
}
+static void fw_iso_rx_multiple_stop(HinokoFwIsoCtx *inst)
+{
+ HinokoFwIsoRxMultiple *self;
+ HinokoFwIsoRxMultiplePrivate *priv;
+ gboolean running;
+
+ g_return_if_fail(HINOKO_IS_FW_ISO_RX_MULTIPLE(inst));
+ self = HINOKO_FW_ISO_RX_MULTIPLE(inst);
+ priv = hinoko_fw_iso_rx_multiple_get_instance_private(self);
+
+ running = priv->state.running;
+
+ fw_iso_ctx_state_stop(&priv->state);
+
+ if (priv->state.running != running)
+ g_signal_emit_by_name(G_OBJECT(inst), "stopped", NULL);
+}
+
+static gboolean fw_iso_rx_multiple_get_cycle_timer(HinokoFwIsoCtx *inst, gint clock_id,
+ HinokoCycleTimer *const *cycle_timer,
+ GError **error)
+{
+ HinokoFwIsoRxMultiple *self;
+ HinokoFwIsoRxMultiplePrivate *priv;
+
+ g_return_val_if_fail(HINOKO_IS_FW_ISO_RX_MULTIPLE(inst), FALSE);
+ self = HINOKO_FW_ISO_RX_MULTIPLE(inst);
+ priv = hinoko_fw_iso_rx_multiple_get_instance_private(self);
+
+ return fw_iso_ctx_state_get_cycle_timer(&priv->state, clock_id, cycle_timer, error);
+}
+
+static gboolean fw_iso_rx_multiple_flush_completions(HinokoFwIsoCtx *inst, GError **error)
+{
+ HinokoFwIsoRxMultiple *self;
+ HinokoFwIsoRxMultiplePrivate *priv;
+
+ g_return_val_if_fail(HINOKO_IS_FW_ISO_RX_MULTIPLE(inst), FALSE);
+ self = HINOKO_FW_ISO_RX_MULTIPLE(inst);
+ priv = hinoko_fw_iso_rx_multiple_get_instance_private(self);
+
+ return fw_iso_ctx_state_flush_completions(&priv->state, error);
+}
+
static gboolean fw_iso_rx_multiple_register_chunk(HinokoFwIsoRxMultiple *self, GError **error)
{
HinokoFwIsoRxMultiplePrivate *priv = hinoko_fw_iso_rx_multiple_get_instance_private(self);
@@ -232,6 +284,27 @@ gboolean fw_iso_rx_multiple_handle_event(HinokoFwIsoCtx *inst, const union fw_cd
return TRUE;
}
+gboolean fw_iso_rx_multiple_create_source(HinokoFwIsoCtx *inst, GSource **source, GError **error)
+{
+ HinokoFwIsoRxMultiple *self;
+ HinokoFwIsoRxMultiplePrivate *priv;
+
+ g_return_val_if_fail(HINOKO_IS_FW_ISO_RX_MULTIPLE(inst), FALSE);
+ self = HINOKO_FW_ISO_RX_MULTIPLE(inst);
+ priv = hinoko_fw_iso_rx_multiple_get_instance_private(self);
+
+ return fw_iso_ctx_state_create_source(&priv->state, inst, fw_iso_rx_multiple_handle_event,
+ source, error);
+}
+
+static void fw_iso_ctx_class_init(HinokoFwIsoCtxClass *parent_class)
+{
+ parent_class->stop = fw_iso_rx_multiple_stop;
+ parent_class->get_cycle_timer = fw_iso_rx_multiple_get_cycle_timer;
+ parent_class->flush_completions = fw_iso_rx_multiple_flush_completions;
+ parent_class->create_source = fw_iso_rx_multiple_create_source;
+}
+
/**
* hinoko_fw_iso_rx_multiple_new:
*
diff --git a/src/fw_iso_rx_single.c b/src/fw_iso_rx_single.c
index 7642a1e..ccacfaf 100644
--- a/src/fw_iso_rx_single.c
+++ b/src/fw_iso_rx_single.c
@@ -12,11 +12,16 @@
*
*/
typedef struct {
+ struct fw_iso_ctx_state state;
+
guint header_size;
guint chunk_cursor;
const struct fw_cdev_event_iso_interrupt *ev;
} HinokoFwIsoRxSinglePrivate;
+
+static void fw_iso_ctx_class_init(HinokoFwIsoCtxClass *parent_class);
+
G_DEFINE_TYPE_WITH_PRIVATE(HinokoFwIsoRxSingle, hinoko_fw_iso_rx_single, HINOKO_TYPE_FW_ISO_CTX)
static void fw_iso_rx_single_finalize(GObject *obj)
@@ -37,9 +42,12 @@ static guint fw_iso_rx_single_sigs[FW_ISO_RX_SINGLE_SIG_TYPE_COUNT] = { 0 };
static void hinoko_fw_iso_rx_single_class_init(HinokoFwIsoRxSingleClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+ HinokoFwIsoCtxClass *parent_class = HINOKO_FW_ISO_CTX_CLASS(klass);
gobject_class->finalize = fw_iso_rx_single_finalize;
+ fw_iso_ctx_class_init(parent_class);
+
/**
* HinokoFwIsoRxSingle::interrupted:
* @self: A [class@FwIsoRxSingle]
@@ -79,6 +87,50 @@ static void hinoko_fw_iso_rx_single_init(HinokoFwIsoRxSingle *self)
return;
}
+static void fw_iso_rx_single_stop(HinokoFwIsoCtx *inst)
+{
+ HinokoFwIsoRxSingle *self;
+ HinokoFwIsoRxSinglePrivate *priv;
+ gboolean running;
+
+ g_return_if_fail(HINOKO_IS_FW_ISO_RX_SINGLE(inst));
+ self = HINOKO_FW_ISO_RX_SINGLE(inst);
+ priv = hinoko_fw_iso_rx_single_get_instance_private(self);
+
+ running = priv->state.running;
+
+ fw_iso_ctx_state_stop(&priv->state);
+
+ if (priv->state.running != running)
+ g_signal_emit_by_name(G_OBJECT(inst), "stopped", NULL);
+}
+
+static gboolean fw_iso_rx_single_get_cycle_timer(HinokoFwIsoCtx *inst, gint clock_id,
+ HinokoCycleTimer *const *cycle_timer,
+ GError **error)
+{
+ HinokoFwIsoRxSingle *self;
+ HinokoFwIsoRxSinglePrivate *priv;
+
+ g_return_val_if_fail(HINOKO_IS_FW_ISO_RX_SINGLE(inst), FALSE);
+ self = HINOKO_FW_ISO_RX_SINGLE(inst);
+ priv = hinoko_fw_iso_rx_single_get_instance_private(self);
+
+ return fw_iso_ctx_state_get_cycle_timer(&priv->state, clock_id, cycle_timer, error);
+}
+
+static gboolean fw_iso_rx_single_flush_completions(HinokoFwIsoCtx *inst, GError **error)
+{
+ HinokoFwIsoRxSingle *self;
+ HinokoFwIsoRxSinglePrivate *priv;
+
+ g_return_val_if_fail(HINOKO_IS_FW_ISO_RX_SINGLE(inst), FALSE);
+ self = HINOKO_FW_ISO_RX_SINGLE(inst);
+ priv = hinoko_fw_iso_rx_single_get_instance_private(self);
+
+ return fw_iso_ctx_state_flush_completions(&priv->state, error);
+}
+
gboolean fw_iso_rx_single_handle_event(HinokoFwIsoCtx *inst, const union fw_cdev_event *event,
GError **error)
{
@@ -120,6 +172,27 @@ gboolean fw_iso_rx_single_handle_event(HinokoFwIsoCtx *inst, const union fw_cdev
return TRUE;
}
+gboolean fw_iso_rx_single_create_source(HinokoFwIsoCtx *inst, GSource **source, GError **error)
+{
+ HinokoFwIsoRxSingle *self;
+ HinokoFwIsoRxSinglePrivate *priv;
+
+ g_return_val_if_fail(HINOKO_IS_FW_ISO_RX_SINGLE(inst), FALSE);
+ self = HINOKO_FW_ISO_RX_SINGLE(inst);
+ priv = hinoko_fw_iso_rx_single_get_instance_private(self);
+
+ return fw_iso_ctx_state_create_source(&priv->state, inst, fw_iso_rx_single_handle_event,
+ source, error);
+}
+
+static void fw_iso_ctx_class_init(HinokoFwIsoCtxClass *parent_class)
+{
+ parent_class->stop = fw_iso_rx_single_stop;
+ parent_class->get_cycle_timer = fw_iso_rx_single_get_cycle_timer;
+ parent_class->flush_completions = fw_iso_rx_single_flush_completions;
+ parent_class->create_source = fw_iso_rx_single_create_source;
+}
+
/**
* hinoko_fw_iso_rx_single_new:
*
diff --git a/src/fw_iso_tx.c b/src/fw_iso_tx.c
index 4f0d4f1..f682fee 100644
--- a/src/fw_iso_tx.c
+++ b/src/fw_iso_tx.c
@@ -10,8 +10,12 @@
* Linux FireWire subsystem.
*/
typedef struct {
+ struct fw_iso_ctx_state state;
guint offset;
} HinokoFwIsoTxPrivate;
+
+static void fw_iso_ctx_class_init(HinokoFwIsoCtxClass *parent_class);
+
G_DEFINE_TYPE_WITH_PRIVATE(HinokoFwIsoTx, hinoko_fw_iso_tx, HINOKO_TYPE_FW_ISO_CTX)
static void fw_iso_tx_finalize(GObject *obj)
@@ -32,9 +36,12 @@ static guint fw_iso_tx_sigs[FW_ISO_TX_SIG_TYPE_COUNT] = { 0 };
static void hinoko_fw_iso_tx_class_init(HinokoFwIsoTxClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+ HinokoFwIsoCtxClass *parent_class = HINOKO_FW_ISO_CTX_CLASS(klass);
gobject_class->finalize = fw_iso_tx_finalize;
+ fw_iso_ctx_class_init(parent_class);
+
/**
* HinokoFwIsoTx::interrupted:
* @self: A [class@FwIsoTx].
@@ -71,6 +78,50 @@ static void hinoko_fw_iso_tx_init(HinokoFwIsoTx *self)
return;
}
+static void fw_iso_tx_stop(HinokoFwIsoCtx *inst)
+{
+ HinokoFwIsoTx *self;
+ HinokoFwIsoTxPrivate *priv;
+ gboolean running;
+
+ g_return_if_fail(HINOKO_IS_FW_ISO_TX(inst));
+ self = HINOKO_FW_ISO_TX(inst);
+ priv = hinoko_fw_iso_tx_get_instance_private(self);
+
+ running = priv->state.running;
+
+ fw_iso_ctx_state_stop(&priv->state);
+
+ if (priv->state.running != running)
+ g_signal_emit_by_name(G_OBJECT(inst), "stopped", NULL);
+}
+
+static gboolean fw_iso_tx_get_cycle_timer(HinokoFwIsoCtx *inst, gint clock_id,
+ HinokoCycleTimer *const *cycle_timer,
+ GError **error)
+{
+ HinokoFwIsoTx *self;
+ HinokoFwIsoTxPrivate *priv;
+
+ g_return_val_if_fail(HINOKO_IS_FW_ISO_TX(inst), FALSE);
+ self = HINOKO_FW_ISO_TX(inst);
+ priv = hinoko_fw_iso_tx_get_instance_private(self);
+
+ return fw_iso_ctx_state_get_cycle_timer(&priv->state, clock_id, cycle_timer, error);
+}
+
+static gboolean fw_iso_tx_flush_completions(HinokoFwIsoCtx *inst, GError **error)
+{
+ HinokoFwIsoTx *self;
+ HinokoFwIsoTxPrivate *priv;
+
+ g_return_val_if_fail(HINOKO_IS_FW_ISO_TX(inst), FALSE);
+ self = HINOKO_FW_ISO_TX(inst);
+ priv = hinoko_fw_iso_tx_get_instance_private(self);
+
+ return fw_iso_ctx_state_flush_completions(&priv->state, error);
+}
+
gboolean fw_iso_tx_handle_event(HinokoFwIsoCtx *inst, const union fw_cdev_event *event,
GError **error)
{
@@ -91,6 +142,27 @@ gboolean fw_iso_tx_handle_event(HinokoFwIsoCtx *inst, const union fw_cdev_event
return TRUE;
}
+gboolean fw_iso_tx_create_source(HinokoFwIsoCtx *inst, GSource **source, GError **error)
+{
+ HinokoFwIsoTx *self;
+ HinokoFwIsoTxPrivate *priv;
+
+ g_return_val_if_fail(HINOKO_IS_FW_ISO_TX(inst), FALSE);
+ self = HINOKO_FW_ISO_TX(inst);
+ priv = hinoko_fw_iso_tx_get_instance_private(self);
+
+ return fw_iso_ctx_state_create_source(&priv->state, inst, fw_iso_tx_handle_event, source,
+ error);
+}
+
+static void fw_iso_ctx_class_init(HinokoFwIsoCtxClass *parent_class)
+{
+ parent_class->stop = fw_iso_tx_stop;
+ parent_class->get_cycle_timer = fw_iso_tx_get_cycle_timer;
+ parent_class->flush_completions = fw_iso_tx_flush_completions;
+ parent_class->create_source = fw_iso_tx_create_source;
+}
+
/**
* hinoko_fw_iso_tx_new:
*