diff options
Diffstat (limited to 'src/pop-transaction.c')
-rw-r--r-- | src/pop-transaction.c | 100 |
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; } |