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
commit5f69175a9f16a633060f818bfde0c855074b0185 (patch)
treefca02562df43ee4f8c52f46563da93b4d46e0d76
parent985a21ca90edc350f043521d46f3499b631b40e5 (diff)
downloadlibhinoko-5f69175a9f16a633060f818bfde0c855074b0185.tar.gz
fw_iso_ctx: code refactoring to move GSource create function
This commit moves private implementation to create GSource into specific file. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
-rw-r--r--src/fw_iso_ctx.c121
-rw-r--r--src/fw_iso_ctx_private.c122
2 files changed, 122 insertions, 121 deletions
diff --git a/src/fw_iso_ctx.c b/src/fw_iso_ctx.c
index 591f6a7..cc3572a 100644
--- a/src/fw_iso_ctx.c
+++ b/src/fw_iso_ctx.c
@@ -37,17 +37,6 @@ const char *const fw_iso_ctx_err_msgs[7] = {
[HINOKO_FW_ISO_CTX_ERROR_CHUNK_UNREGISTERED] = "No chunk registered before starting",
};
-typedef struct {
- GSource src;
- gpointer tag;
- unsigned int len;
- void *buf;
- HinokoFwIsoCtx *self;
- int fd;
- gboolean (*handle_event)(HinokoFwIsoCtx *self, const union fw_cdev_event *event,
- GError **error);
-} FwIsoCtxSource;
-
enum fw_iso_ctx_sig_type {
FW_ISO_CTX_SIG_TYPE_STOPPED = 1,
FW_ISO_CTX_SIG_TYPE_COUNT,
@@ -128,116 +117,6 @@ void hinoko_fw_iso_ctx_get_cycle_timer(HinokoFwIsoCtx *self, gint clock_id,
HINOKO_FW_ISO_CTX_CLASS(self)->get_cycle_timer(self, clock_id, cycle_timer, error);
}
-static gboolean check_src(GSource *source)
-{
- FwIsoCtxSource *src = (FwIsoCtxSource *)source;
- GIOCondition condition;
-
- // Don't go to dispatch if nothing available. As an error, return
- // TRUE for POLLERR to call .dispatch for internal destruction.
- condition = g_source_query_unix_fd(source, src->tag);
- return !!(condition & (G_IO_IN | G_IO_ERR));
-}
-
-static gboolean dispatch_src(GSource *source, GSourceFunc cb, gpointer user_data)
-{
- FwIsoCtxSource *src = (FwIsoCtxSource *)source;
- GIOCondition condition;
- GError *error = NULL;
- int len;
- const union fw_cdev_event *event;
-
- condition = g_source_query_unix_fd(source, src->tag);
- if (condition & G_IO_ERR)
- return G_SOURCE_REMOVE;
-
- len = read(src->fd, src->buf, src->len);
- if (len < 0) {
- if (errno != EAGAIN) {
- generate_file_error(&error, g_file_error_from_errno(errno),
- "read %s", strerror(errno));
- goto error;
- }
-
- return G_SOURCE_CONTINUE;
- }
-
- event = (const union fw_cdev_event *)src->buf;
- if (!src->handle_event(src->self, event, &error))
- goto error;
-
- // Just be sure to continue to process this source.
- return G_SOURCE_CONTINUE;
-error:
- hinoko_fw_iso_ctx_stop(src->self);
- g_clear_error(&error);
- return G_SOURCE_REMOVE;
-}
-
-static void finalize_src(GSource *source)
-{
- FwIsoCtxSource *src = (FwIsoCtxSource *)source;
-
- g_free(src->buf);
- g_object_unref(src->self);
-}
-
-/**
- * fw_iso_ctx_state_create_source:
- * @state: A [struct@FwIsoCtxState].
- * @source: (out): A [struct@GLib.Source].
- * @error: A [struct@GLib.Error].
- *
- * Create [struct@GLib.Source] for [struct@GLib.MainContext] to dispatch events for isochronous
- * context.
- */
-gboolean fw_iso_ctx_state_create_source(struct fw_iso_ctx_state *state, HinokoFwIsoCtx *inst,
- gboolean (*handle_event)(HinokoFwIsoCtx *inst,
- const union fw_cdev_event *event,
- GError **error),
- GSource **source, GError **error)
-{
- static GSourceFuncs funcs = {
- .check = check_src,
- .dispatch = dispatch_src,
- .finalize = finalize_src,
- };
- FwIsoCtxSource *src;
-
- g_return_val_if_fail(HINOKO_IS_FW_ISO_CTX(inst), FALSE);
- g_return_val_if_fail(source != NULL, FALSE);
- g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
-
- if (state->fd < 0) {
- generate_local_error(error, HINOKO_FW_ISO_CTX_ERROR_NOT_ALLOCATED);
- return FALSE;
- }
-
- *source = g_source_new(&funcs, sizeof(FwIsoCtxSource));
-
- g_source_set_name(*source, "HinokoFwIsoCtx");
-
- src = (FwIsoCtxSource *)(*source);
-
- if (state->mode != HINOKO_FW_ISO_CTX_MODE_RX_MULTIPLE) {
- // MEMO: Linux FireWire subsystem queues isochronous event
- // independently of interrupt flag when the same number of
- // bytes as one page is stored in the buffer of header. To
- // avoid truncated read, keep enough size.
- src->len = sizeof(struct fw_cdev_event_iso_interrupt) +
- sysconf(_SC_PAGESIZE);
- } else {
- src->len = sizeof(struct fw_cdev_event_iso_interrupt_mc);
- }
- src->buf = g_malloc0(src->len);
-
- src->tag = g_source_add_unix_fd(*source, state->fd, G_IO_IN);
- src->fd = state->fd;
- src->self = g_object_ref(inst);
- src->handle_event = handle_event;
-
- return TRUE;
-}
/**
* hinoko_fw_iso_ctx_create_source:
* @self: A [class@FwIsoCtx].
diff --git a/src/fw_iso_ctx_private.c b/src/fw_iso_ctx_private.c
index cb97d5f..79c7b8c 100644
--- a/src/fw_iso_ctx_private.c
+++ b/src/fw_iso_ctx_private.c
@@ -6,6 +6,17 @@
#include <fcntl.h>
#include <sys/mman.h>
+typedef struct {
+ GSource src;
+ gpointer tag;
+ unsigned int len;
+ void *buf;
+ HinokoFwIsoCtx *self;
+ int fd;
+ gboolean (*handle_event)(HinokoFwIsoCtx *self, const union fw_cdev_event *event,
+ GError **error);
+} FwIsoCtxSource;
+
void fw_iso_ctx_class_override_properties(GObjectClass *gobject_class)
{
g_object_class_override_property(gobject_class, FW_ISO_CTX_PROP_TYPE_BYTES_PER_CHUNK,
@@ -593,3 +604,114 @@ gboolean fw_iso_ctx_state_get_cycle_timer(struct fw_iso_ctx_state *state, gint c
return TRUE;
}
+
+static gboolean check_src(GSource *source)
+{
+ FwIsoCtxSource *src = (FwIsoCtxSource *)source;
+ GIOCondition condition;
+
+ // Don't go to dispatch if nothing available. As an error, return
+ // TRUE for POLLERR to call .dispatch for internal destruction.
+ condition = g_source_query_unix_fd(source, src->tag);
+ return !!(condition & (G_IO_IN | G_IO_ERR));
+}
+
+static gboolean dispatch_src(GSource *source, GSourceFunc cb, gpointer user_data)
+{
+ FwIsoCtxSource *src = (FwIsoCtxSource *)source;
+ GIOCondition condition;
+ GError *error = NULL;
+ int len;
+ const union fw_cdev_event *event;
+
+ condition = g_source_query_unix_fd(source, src->tag);
+ if (condition & G_IO_ERR)
+ return G_SOURCE_REMOVE;
+
+ len = read(src->fd, src->buf, src->len);
+ if (len < 0) {
+ if (errno != EAGAIN) {
+ generate_file_error(&error, g_file_error_from_errno(errno),
+ "read %s", strerror(errno));
+ goto error;
+ }
+
+ return G_SOURCE_CONTINUE;
+ }
+
+ event = (const union fw_cdev_event *)src->buf;
+ if (!src->handle_event(src->self, event, &error))
+ goto error;
+
+ // Just be sure to continue to process this source.
+ return G_SOURCE_CONTINUE;
+error:
+ hinoko_fw_iso_ctx_stop(src->self);
+ g_clear_error(&error);
+ return G_SOURCE_REMOVE;
+}
+
+static void finalize_src(GSource *source)
+{
+ FwIsoCtxSource *src = (FwIsoCtxSource *)source;
+
+ g_free(src->buf);
+ g_object_unref(src->self);
+}
+
+/**
+ * fw_iso_ctx_state_create_source:
+ * @state: A [struct@FwIsoCtxState].
+ * @source: (out): A [struct@GLib.Source].
+ * @error: A [struct@GLib.Error].
+ *
+ * Create [struct@GLib.Source] for [struct@GLib.MainContext] to dispatch events for isochronous
+ * context.
+ */
+gboolean fw_iso_ctx_state_create_source(struct fw_iso_ctx_state *state, HinokoFwIsoCtx *inst,
+ gboolean (*handle_event)(HinokoFwIsoCtx *inst,
+ const union fw_cdev_event *event,
+ GError **error),
+ GSource **source, GError **error)
+{
+ static GSourceFuncs funcs = {
+ .check = check_src,
+ .dispatch = dispatch_src,
+ .finalize = finalize_src,
+ };
+ FwIsoCtxSource *src;
+
+ g_return_val_if_fail(HINOKO_IS_FW_ISO_CTX(inst), FALSE);
+ g_return_val_if_fail(source != NULL, FALSE);
+ g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
+
+ if (state->fd < 0) {
+ generate_local_error(error, HINOKO_FW_ISO_CTX_ERROR_NOT_ALLOCATED);
+ return FALSE;
+ }
+
+ *source = g_source_new(&funcs, sizeof(FwIsoCtxSource));
+
+ g_source_set_name(*source, "HinokoFwIsoCtx");
+
+ src = (FwIsoCtxSource *)(*source);
+
+ if (state->mode != HINOKO_FW_ISO_CTX_MODE_RX_MULTIPLE) {
+ // MEMO: Linux FireWire subsystem queues isochronous event
+ // independently of interrupt flag when the same number of
+ // bytes as one page is stored in the buffer of header. To
+ // avoid truncated read, keep enough size.
+ src->len = sizeof(struct fw_cdev_event_iso_interrupt) +
+ sysconf(_SC_PAGESIZE);
+ } else {
+ src->len = sizeof(struct fw_cdev_event_iso_interrupt_mc);
+ }
+ src->buf = g_malloc0(src->len);
+
+ src->tag = g_source_add_unix_fd(*source, state->fd, G_IO_IN);
+ src->fd = state->fd;
+ src->self = g_object_ref(inst);
+ src->handle_event = handle_event;
+
+ return TRUE;
+}