diff options
author | Takashi Sakamoto <o-takashi@sakamocchi.jp> | 2023-08-10 10:20:37 +0900 |
---|---|---|
committer | Takashi Sakamoto <o-takashi@sakamocchi.jp> | 2023-10-07 11:42:33 +0900 |
commit | 4c3729c97491ca6990ce3953f3b4bb8afb5d1287 (patch) | |
tree | 95dabcf2a27ff57b6259697be31b36e1b44b2244 | |
parent | 53b82c73c97b3f7ac4768d1cedc03ab1aaeaf97d (diff) | |
download | libhinawa-4c3729c97491ca6990ce3953f3b4bb8afb5d1287.tar.gz |
fw_fcp: maintain transaction in doubly-linked list
This is a preparation to operate response of transactions over the list,
instead of the pointer in stack.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
-rw-r--r-- | src/fw_fcp.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/src/fw_fcp.c b/src/fw_fcp.c index 9873c38..5218478 100644 --- a/src/fw_fcp.c +++ b/src/fw_fcp.c @@ -63,6 +63,9 @@ enum avc_status { typedef struct { HinawaFwNode *node; + + GList *transactions; + GMutex transactions_mutex; } HinawaFwFcpPrivate; G_DEFINE_TYPE_WITH_PRIVATE(HinawaFwFcp, hinawa_fw_fcp, HINAWA_TYPE_FW_RESP) @@ -92,9 +95,13 @@ static void fw_fcp_get_property(GObject *obj, guint id, GValue *val, static void fw_fcp_finalize(GObject *obj) { HinawaFwFcp *self = HINAWA_FW_FCP(obj); + HinawaFwFcpPrivate *priv = hinawa_fw_fcp_get_instance_private(self); hinawa_fw_fcp_unbind(self); + g_mutex_clear(&priv->transactions_mutex); + g_list_free(priv->transactions); + G_OBJECT_CLASS(hinawa_fw_fcp_parent_class)->finalize(obj); } @@ -170,7 +177,10 @@ static void hinawa_fw_fcp_class_init(HinawaFwFcpClass *klass) static void hinawa_fw_fcp_init(HinawaFwFcp *self) { - return; + HinawaFwFcpPrivate *priv = hinawa_fw_fcp_get_instance_private(self); + + g_mutex_init(&priv->transactions_mutex); + g_list_free(priv->transactions); } /** @@ -326,6 +336,7 @@ gboolean hinawa_fw_fcp_avc_transaction_with_tstamp(HinawaFwFcp *self, const guint8 *cmd, gsize cmd_size, guint8 **resp, gsize *resp_size, guint tstamp[3], guint timeout_ms, GError **error) { + HinawaFwFcpPrivate *priv; struct waiter w; gulong handler_id; gint64 expiration; @@ -339,6 +350,8 @@ gboolean hinawa_fw_fcp_avc_transaction_with_tstamp(HinawaFwFcp *self, g_return_val_if_fail(tstamp != NULL, FALSE); g_return_val_if_fail(error == NULL || *error == NULL, FALSE); + priv = hinawa_fw_fcp_get_instance_private(self); + w.frame = *resp; w.frame_size = *resp_size; w.tstamp = G_MAXUINT; @@ -350,11 +363,16 @@ gboolean hinawa_fw_fcp_avc_transaction_with_tstamp(HinawaFwFcp *self, // The two bytes are used to match response and request. w.frame[1] = cmd[1]; w.frame[2] = cmd[2]; + handler_id = g_signal_connect(self, "responded", (GCallback)handle_responded_signal, &w); expiration = g_get_monotonic_time() + timeout_ms * G_TIME_SPAN_MILLISECOND; g_mutex_lock(&w.mutex); + g_mutex_lock(&priv->transactions_mutex); + priv->transactions = g_list_append(priv->transactions, &w); + g_mutex_unlock(&priv->transactions_mutex); + // Finish transaction for command frame. result = hinawa_fw_fcp_command_with_tstamp(self, cmd, cmd_size, tstamp, timeout_ms, error); if (!result) { @@ -378,6 +396,10 @@ deferred: goto deferred; } + g_mutex_lock(&priv->transactions_mutex); + priv->transactions = g_list_remove(priv->transactions, &w); + g_mutex_unlock(&priv->transactions_mutex); + g_signal_handler_disconnect(self, handler_id); g_mutex_unlock(&w.mutex); |