summaryrefslogtreecommitdiff
path: root/src/pop-transaction.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pop-transaction.c')
-rw-r--r--src/pop-transaction.c100
1 files changed, 86 insertions, 14 deletions
diff --git a/src/pop-transaction.c b/src/pop-transaction.c
index 37a70a0..6a4556b 100644
--- a/src/pop-transaction.c
+++ b/src/pop-transaction.c
@@ -143,8 +143,8 @@ static gboolean pop_action_tree_is_at_first_action (PopActionTree *action_tree);
static gboolean pop_action_tree_is_empty (PopActionTree *action_tree);
static gboolean pop_action_tree_seek (PopActionTree *action_tree,
PopActionTreeWalkDirection direction);
-static void pop_action_tree_add_action (PopActionTree *action_tree,
- PopAction *action);
+static void pop_action_tree_add_action (PopActionTree *action_tree,
+ PopAction *action);
static PopAction *pop_action_tree_get_current_action (PopActionTree *tree);
static void pop_action_tree_foreach (PopActionTree *action_tree,
GFunc func,
@@ -159,6 +159,8 @@ struct _PopAction
PopActionRollbackFunc rollback_func;
PopActionRollbackStatus rollback_status;
+ GHashTable *state;
+
gpointer user_data;
GDestroyNotify free_func;
};
@@ -678,6 +680,7 @@ pop_action_new (PopActionProcessFunc action_process_func,
action->process_status = POP_ACTION_PROCESS_STATUS_NOT_FINISHED;
action->rollback_func = action_rollback_func;
action->rollback_status = POP_ACTION_ROLLBACK_STATUS_NOT_FINISHED;
+ action->state = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
action->user_data = user_data;
action->free_func = free_func;
@@ -694,9 +697,76 @@ pop_action_free (PopAction *action)
action->free_func (action->user_data);
}
+ g_hash_table_destroy (action->state);
g_slice_free (PopAction, action);
}
+void
+pop_transaction_set_action_data (PopTransaction *transaction,
+ const char *key,
+ gpointer data)
+{
+ PopAction *action;
+
+ g_return_if_fail (POP_IS_TRANSACTION (transaction));
+ g_return_if_fail (key != NULL);
+ g_return_if_fail (!pop_transaction_has_action_data (transaction, key));
+
+ action = pop_action_tree_get_current_action (transaction->priv->action_tree);
+
+ g_hash_table_insert (action->state, g_strdup (key), data);
+}
+
+void
+pop_transaction_unset_action_data (PopTransaction *transaction,
+ const gchar *key,
+ gpointer data)
+{
+ PopAction *action;
+ gboolean data_was_removed;
+
+ g_return_if_fail (POP_IS_TRANSACTION (transaction));
+ g_return_if_fail (key != NULL);
+ g_return_if_fail (!pop_transaction_has_action_data (transaction, key));
+
+ action = pop_action_tree_get_current_action (transaction->priv->action_tree);
+
+ data_was_removed = g_hash_table_remove (action->state, key);
+ g_assert (data_was_removed);
+}
+
+gpointer
+pop_transaction_get_action_data (PopTransaction *transaction,
+ const gchar *key)
+{
+ PopAction *action;
+ gpointer data;
+
+ g_return_val_if_fail (POP_IS_TRANSACTION (transaction), NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+
+ action = pop_action_tree_get_current_action (transaction->priv->action_tree);
+
+ data = NULL;
+ g_hash_table_lookup_extended (action->state, key, NULL, &data);
+
+ return data;
+}
+
+gboolean
+pop_transaction_has_action_data (PopTransaction *transaction,
+ const gchar *key)
+{
+ PopAction *action;
+
+ g_return_val_if_fail (POP_IS_TRANSACTION (transaction), FALSE);
+ g_return_val_if_fail (key != NULL, FALSE);
+
+ action = pop_action_tree_get_current_action (transaction->priv->action_tree);
+
+ return g_hash_table_lookup_extended (action->state, key, NULL, NULL);
+}
+
static PopActionProcessStatus
pop_transaction_process_subtransaction (PopTransaction *transaction,
PopTransaction *subtransaction)
@@ -1383,6 +1453,7 @@ proces_io_action (PopTransaction *transaction,
gboolean is_ready;
size_t bytes_left, bytes_done;
ssize_t bytes_done_this_time;
+ gpointer action_data;
g_assert (POP_IS_TRANSACTION (transaction));
g_return_val_if_fail (arguments->fd >= 0,
@@ -1395,18 +1466,20 @@ proces_io_action (PopTransaction *transaction,
if (!is_ready)
{
g_printerr ("waiting for fd %d to become ready.\n", arguments->fd);
+
/* pause transaction until fd is ready for reading (or writing
* depending on the io_func)
*/
pop_transaction_wait_for_fd (transaction, arguments->fd, condition,
NULL);
- g_object_set_data (G_OBJECT (transaction), "bytes-left-to-process",
- GINT_TO_POINTER (arguments->number_of_bytes_to_process));
+ action_data = GINT_TO_POINTER (arguments->number_of_bytes_to_process);
+ g_object_set_data (transaction, "bytes-left-to-process", action_data);
/* when the transaction gets unpaused we want to continue on
*/
- g_object_set_data (G_OBJECT (transaction), "is-ready",
- GINT_TO_POINTER (TRUE));
+ action_data = GINT_TO_POINTER (TRUE)
+ pop_transaction_set_action_data (G_OBJECT (transaction), "is-ready",
+ action_data);
return POP_ACTION_PROCESS_STATUS_NOT_FINISHED;
}
@@ -1476,8 +1549,8 @@ proces_io_action (PopTransaction *transaction,
g_object_set_data (G_OBJECT (transaction), "bytes-already-processed",
GINT_TO_POINTER (0));
- g_object_set_data (G_OBJECT (transaction), "is-ready",
- GINT_TO_POINTER (FALSE));
+ pop_transaction_set_action_data (G_OBJECT (transaction), "is-ready",
+ GINT_TO_POINTER (FALSE));
return POP_ACTION_PROCESS_STATUS_SUCCEEDED;
}
@@ -1527,8 +1600,8 @@ process_set_fd_nonblocking_action (PopTransaction *transaction,
return POP_ACTION_PROCESS_STATUS_FAILED;
}
- g_object_set_data (G_OBJECT (transaction), "file-flags",
- GINT_TO_POINTER (flags));
+ pop_transaction_set_action_data (G_OBJECT (transaction), "file-flags",
+ GINT_TO_POINTER (flags));
return POP_ACTION_PROCESS_STATUS_SUCCEEDED;
}
@@ -1538,11 +1611,12 @@ rollback_set_fd_nonblocking_action (PopTransaction *transaction,
gpointer data)
{
int fd, flags;
+ gpointer action_data;
fd = GPOINTER_TO_INT (data);
- flags = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (transaction),
- "file-flags"));
+ action_data = pop_transaction_get_action_data (transaction, "file-flags");
+ flags = GPOINTER_TO_INT (action_data);
fcntl (fd, F_SETFL, flags);
@@ -1658,12 +1732,10 @@ rollback_cat_action (PopTransaction *transaction,
input_arguments = g_object_get_data (G_OBJECT (transaction), "cat-input-args");
g_slice_free (InputOutputArguments, input_arguments);
- g_object_set_data (G_OBJECT (transaction), "cat-input-args", NULL);
output_arguments = g_object_get_data (G_OBJECT (transaction), "cat-output-args");
g_slice_free (InputOutputArguments, output_arguments);
g_free (output_arguments->buffer);
- g_object_set_data (G_OBJECT (transaction), "cat-input-args", NULL);
return POP_ACTION_ROLLBACK_STATUS_FINISHED;
}