aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2023-08-10 10:20:37 +0900
committerTakashi Sakamoto <o-takashi@sakamocchi.jp>2023-10-07 11:42:33 +0900
commit4c3729c97491ca6990ce3953f3b4bb8afb5d1287 (patch)
tree95dabcf2a27ff57b6259697be31b36e1b44b2244
parent53b82c73c97b3f7ac4768d1cedc03ab1aaeaf97d (diff)
downloadlibhinawa-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.c24
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);