diff options
author | Ray Strode <rstrode@redhat.com> | 2007-05-03 23:30:32 -0400 |
---|---|---|
committer | Ray Strode <rstrode@redhat.com> | 2007-05-03 23:30:32 -0400 |
commit | b4b75d8c01aa0664c3f039879cec9136dc6c74a8 (patch) | |
tree | 0c58ab65c700f97b02c70c70d4798b661378509e | |
parent | 619d7087f32cd6634f1f70fa1a78581ee1de1624 (diff) |
add untested support for transactions within transactions and
a pile of new public api to be able to support it
-rw-r--r-- | src/pop-transaction.c | 342 | ||||
-rw-r--r-- | src/pop-transaction.h | 40 |
2 files changed, 279 insertions, 103 deletions
diff --git a/src/pop-transaction.c b/src/pop-transaction.c index 7d52723..8c073ad 100644 --- a/src/pop-transaction.c +++ b/src/pop-transaction.c @@ -40,6 +40,10 @@ struct _PopTransactionPrivate { PopTransactionState state; PopTransactionStatus status; + + /* FIXME: might be better to keep this as a tree to + * catch dependencies when one action adds another + */ GQueue *actions; GList *current_action_node; @@ -57,6 +61,8 @@ typedef struct { PopActionProcessFunc process_func; PopActionRollbackFunc rollback_func; + gpointer user_data; + GDestroyNotify free_func; } PopAction; typedef gboolean (* PopTransactionIdleFunc) (PopTransaction *transaction); @@ -78,11 +84,13 @@ static void pop_transaction_fail (PopTransaction *transaction); static void pop_transaction_process_on_idle (PopTransaction *transaction); static void pop_transaction_rollback_on_idle (PopTransaction *transaction); static gboolean pop_transaction_rewind (PopTransaction *transaction); +static void pop_action_free (PopAction *action); +static gboolean pop_transaction_is_committed (PopTransaction *transaction); enum { PROP_0 = 0, - PROP_COMPLETION_CLOSURE, + PROP_STATUS, }; enum @@ -90,6 +98,9 @@ enum PROCESS = 0, WAIT, RESUME, + CANCEL, + FINISH, + ROLLBACK, NUMBER_OF_SIGNALS }; @@ -141,6 +152,27 @@ pop_transaction_class_install_signals (PopTransactionClass * G_STRUCT_OFFSET (PopTransactionClass, resume), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); transaction_class->resume = NULL; + + pop_transaction_signals[CANCEL] = + g_signal_new ("cancel", G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (PopTransactionClass, cancel), + NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + transaction_class->cancel = NULL; + + pop_transaction_signals[FINISH] = + g_signal_new ("finish", G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (PopTransactionClass, finish), + NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); + transaction_class->finish = NULL; + + pop_transaction_signals[ROLLBACK] = + g_signal_new ("rollback", G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (PopTransactionClass, rollback), + NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + transaction_class->rollback = NULL; } static void @@ -153,10 +185,15 @@ pop_transaction_class_install_properties (PopTransactionClass *transaction_class object_class->set_property = pop_transaction_set_property; object_class->get_property = pop_transaction_get_property; - param_spec = g_param_spec_pointer ("completion-closure", _("Completion Closure"), - _("Closure to invoke when transaction is complete"), - G_PARAM_READWRITE | G_PARAM_CONSTRUCT); - g_object_class_install_property (object_class, PROP_COMPLETION_CLOSURE, param_spec); + /* FIXME: do the whole enum gtype song and dance + */ + param_spec = g_param_spec_int ("status", _("Status"), + _("Current status of the transaction"), + POP_TRANSACTION_STATUS_NOT_FINISHED, + POP_TRANSACTION_STATUS_SUCCEEDED, + POP_TRANSACTION_STATUS_NOT_FINISHED, + G_PARAM_READABLE); + g_object_class_install_property (object_class, PROP_STATUS, param_spec); } static void @@ -168,6 +205,7 @@ pop_transaction_init (PopTransaction *transaction) POP_TYPE_TRANSACTION, PopTransactionPrivate); transaction->priv->actions = g_queue_new (); + transaction->priv->status = POP_TRANSACTION_STATUS_NOT_FINISHED; } @@ -182,6 +220,7 @@ pop_transaction_finalize (GObject *object) parent_class = G_OBJECT_CLASS (pop_transaction_parent_class); + g_queue_foreach (transaction->priv->actions, (GFunc) pop_action_free, NULL); g_queue_free (transaction->priv->actions); if (parent_class->finalize != NULL) @@ -189,18 +228,6 @@ pop_transaction_finalize (GObject *object) } static void -pop_transaction_set_completion_closure (PopTransaction *transaction, - GClosure *closure) -{ - g_assert (POP_IS_TRANSACTION (transaction)); - g_assert (closure != NULL); - g_assert (transaction->priv->completion_closure == NULL); - - transaction->priv->completion_closure = g_closure_ref (closure); - g_closure_sink (closure); -} - -static void pop_transaction_set_property (GObject *object, guint prop_id, const GValue *value, @@ -214,12 +241,6 @@ pop_transaction_set_property (GObject *object, switch (prop_id) { - case PROP_COMPLETION_CLOSURE: - pop_transaction_set_completion_closure (transaction, - (GClosure *) - g_value_get_pointer (value)); - break; - default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -239,8 +260,8 @@ pop_transaction_get_property (GObject *object, switch (prop_id) { - case PROP_COMPLETION_CLOSURE: - g_value_set_pointer (value, g_closure_ref (transaction->priv->completion_closure)); + case PROP_STATUS: + g_value_set_int (value, pop_transaction_get_status (transaction)); break; default: @@ -249,25 +270,42 @@ pop_transaction_get_property (GObject *object, } PopTransaction * -pop_transaction_new (PopTransactionCompleteFunc complete_func, - gpointer user_data) +pop_transaction_new (void) { PopTransaction *transaction; - GClosure *closure; - - closure = g_cclosure_new (G_CALLBACK (complete_func), user_data, NULL); - g_closure_set_marshal (closure, g_cclosure_marshal_VOID__INT); - transaction = g_object_new (POP_TYPE_TRANSACTION, - "completion-closure", closure, - NULL); + transaction = g_object_new (POP_TYPE_TRANSACTION, NULL); return transaction; } +PopTransactionStatus +pop_transaction_get_status (PopTransaction *transaction) +{ + g_return_val_if_fail (POP_IS_TRANSACTION (transaction), + POP_TRANSACTION_STATUS_FAILED); + + return transaction->priv->status; +} + +static void +pop_transaction_set_status (PopTransaction *transaction, + PopTransactionStatus status) +{ + g_return_if_fail (POP_IS_TRANSACTION (transaction)); + + if (transaction->priv->status != status) + { + transaction->priv->status = status; + g_object_notify (G_OBJECT (transaction), "status"); + } +} + static PopAction * pop_action_new (PopActionProcessFunc action_process_func, - PopActionRollbackFunc action_rollback_func) + PopActionRollbackFunc action_rollback_func, + gpointer user_data, + GDestroyNotify free_func) { PopAction *action; @@ -275,6 +313,8 @@ pop_action_new (PopActionProcessFunc action_process_func, action->process_func = action_process_func; action->rollback_func = action_rollback_func; + action->user_data = user_data; + action->free_func = free_func; return action; } @@ -284,19 +324,24 @@ pop_action_free (PopAction *action) { g_assert (action != NULL); + if (action->free_func != NULL) + action->free_func (action->user_data); + g_slice_free (PopAction, action); } void -pop_transaction_add_action (PopTransaction *transaction, - PopActionProcessFunc action_process_func, - PopActionRollbackFunc action_rollback_func) +pop_transaction_add_action_full (PopTransaction *transaction, + PopActionProcessFunc action_process_func, + PopActionRollbackFunc action_rollback_func, + gpointer user_data, + GDestroyNotify free_func) { PopAction *action; g_return_if_fail (POP_IS_TRANSACTION (transaction)); - action = pop_action_new (action_process_func, action_rollback_func); + action = pop_action_new (action_process_func, action_rollback_func, user_data, free_func); if (transaction->priv->current_action_node == NULL) g_queue_push_tail (transaction->priv->actions, action); @@ -313,7 +358,107 @@ pop_transaction_add_action (PopTransaction *transaction, } } -static void +void +pop_transaction_add_action (PopTransaction *transaction, + PopActionProcessFunc action_process_func, + PopActionRollbackFunc action_rollback_func, + gpointer user_data) +{ + pop_transaction_add_action_full (transaction, action_process_func, + action_rollback_func, + user_data, NULL); +} + +static PopActionProcessStatus +pop_transaction_process_subtransaction (PopTransaction *transaction, + PopTransaction *subtransaction) +{ + PopTransactionStatus status; + + g_assert (POP_IS_TRANSACTION (transaction)); + g_assert (POP_IS_TRANSACTION (subtransaction)); + + if (!pop_transaction_is_committed (transaction)) + { + pop_transaction_wait (transaction); + g_signal_connect_swapped (G_OBJECT (subtransaction), + "finish", G_CALLBACK (pop_transaction_resume), + transaction); + + pop_transaction_commit (transaction); + + return POP_ACTION_PROCESS_STATUS_NOT_FINISHED; + } + + status = pop_transaction_get_status (subtransaction); + + g_assert (status != POP_TRANSACTION_STATUS_NOT_FINISHED); + g_assert (status == POP_TRANSACTION_STATUS_CANCELED || + status == POP_TRANSACTION_STATUS_FAILED || + status == POP_TRANSACTION_STATUS_SUCCEEDED); + + if ((status == POP_TRANSACTION_STATUS_CANCELED) || + (status == POP_TRANSACTION_STATUS_FAILED)) + return POP_ACTION_PROCESS_STATUS_FAILED; + + return POP_ACTION_PROCESS_STATUS_SUCCEEDED; +} + +static PopActionRollbackStatus +pop_transaction_rollback_subtransaction (PopTransaction *transaction, + PopTransaction *subtransaction) +{ + PopTransactionStatus status; + + status = pop_transaction_get_status (subtransaction); + + /* FIXME: things are a little confusing here. when you + * rollback a transaction it puts the status in NOT_FINISHED + * and emits a "finish" signal. That's pretty counter-intuitive. + * + * Maybe we need to change the wording a bit, or use a separate signal + * for when the rollback completes + */ + + g_assert ((status == POP_TRANSACTION_STATUS_SUCCEEDED) || + (status == POP_TRANSACTION_STATUS_NOT_FINISHED)); + + /* not rolled back yet + */ + if (status == POP_TRANSACTION_STATUS_SUCCEEDED) + { + pop_transaction_wait (transaction); + pop_transaction_rollback (subtransaction); + g_signal_connect_swapped (G_OBJECT (subtransaction), + "finish", G_CALLBACK (pop_transaction_resume), + transaction); + return POP_ACTION_ROLLBACK_STATUS_NOT_FINISHED; + } + + /* the second time we've been called. After the pop_transaction_resume() + */ + + return POP_ACTION_ROLLBACK_STATUS_FINISHED; +} + +void +pop_transaction_add_subtransaction (PopTransaction *transaction, + PopTransaction *subtransaction) +{ + g_return_if_fail (POP_IS_TRANSACTION (transaction)); + g_return_if_fail (POP_IS_TRANSACTION (subtransaction)); + g_return_if_fail (!pop_transaction_is_committed (subtransaction)); + + pop_transaction_add_action_full (transaction, + (PopActionProcessFunc) + pop_transaction_process_subtransaction, + (PopActionRollbackFunc) + pop_transaction_rollback_subtransaction, + g_object_ref (subtransaction), + (GDestroyNotify) g_object_unref); +} + +void pop_transaction_resume (PopTransaction *transaction) { g_assert (POP_IS_TRANSACTION (transaction)); @@ -353,8 +498,8 @@ pop_transaction_is_in_action (PopTransaction *transaction) return FALSE; } -static void -pop_transaction_pause (PopTransaction *transaction) +void +pop_transaction_wait (PopTransaction *transaction) { g_return_if_fail (POP_IS_TRANSACTION (transaction)); g_return_if_fail (pop_transaction_is_in_action (transaction)); @@ -409,7 +554,7 @@ pop_transaction_wait_for_fd (PopTransaction *transaction, g_return_if_fail (POP_IS_TRANSACTION (transaction)); g_return_if_fail (pop_transaction_is_in_action (transaction)); - pop_transaction_pause (transaction); + pop_transaction_wait (transaction); channel = g_io_channel_unix_new (fd); source = g_io_create_watch (channel, condition); @@ -444,7 +589,7 @@ pop_transaction_wait_a_while (PopTransaction *transaction, g_return_if_fail (POP_IS_TRANSACTION (transaction)); g_return_if_fail (pop_transaction_is_in_action (transaction)); - pop_transaction_pause (transaction); + pop_transaction_wait (transaction); source = g_timeout_source_new (milliseconds); g_source_set_callback (source, (GSourceFunc) pop_transaction_on_timeout_resume, @@ -514,27 +659,14 @@ pop_transaction_seek_forward (PopTransaction *transaction) } static void -pop_transaction_complete (PopTransaction *transaction) +pop_transaction_finish (PopTransaction *transaction) { - GValue arguments[2] = { { 0 } }; - g_assert (POP_IS_TRANSACTION (transaction)); transaction->priv->state = POP_TRANSACTION_STATE_FINISHED; - /* The below is a cryptic way of saying - * transaction_complete_func (transaction, transaction->priv->status, user_data); - */ - g_value_init (&arguments[0], POP_TYPE_TRANSACTION); - g_value_set_instance (&arguments[0], transaction); - - g_value_init (&arguments[1], G_TYPE_INT); - g_value_set_int (&arguments[1], transaction->priv->status); - - g_object_ref (transaction); - g_closure_invoke (transaction->priv->completion_closure, - NULL, G_N_ELEMENTS (arguments), arguments, NULL); - g_object_unref (transaction); + g_signal_emit (transaction, pop_transaction_signals[FINISH], 0, + transaction->priv->status); } static gboolean @@ -559,9 +691,9 @@ pop_transaction_process_current_action_and_seek_forward (PopTransaction *transac transaction->priv->is_in_action = TRUE; if (action->process_func != NULL) - status = action->process_func (transaction); + status = action->process_func (transaction, action->user_data); else - status = POP_ACTION_PROCESS_STATUS_FINISHED; + status = POP_ACTION_PROCESS_STATUS_SUCCEEDED; transaction->priv->is_in_action = FALSE; switch (status) @@ -570,11 +702,12 @@ pop_transaction_process_current_action_and_seek_forward (PopTransaction *transac should_continue = TRUE; break; - case POP_ACTION_PROCESS_STATUS_FINISHED: + case POP_ACTION_PROCESS_STATUS_SUCCEEDED: if (!pop_transaction_seek_forward (transaction)) { - transaction->priv->status = POP_TRANSACTION_STATUS_FINISHED; - pop_transaction_complete (transaction); + pop_transaction_set_status (transaction, + POP_TRANSACTION_STATUS_SUCCEEDED); + pop_transaction_finish (transaction); should_continue = FALSE; } else @@ -593,7 +726,6 @@ pop_transaction_process_current_action_and_seek_forward (PopTransaction *transac break; } - if (!should_continue) { g_source_remove (transaction->priv->process_idle_id); @@ -635,7 +767,7 @@ pop_transaction_rollback_current_action_and_rewind (PopTransaction *transaction) transaction->priv->is_in_action = TRUE; if (action->rollback_func != NULL) - status = action->rollback_func (transaction); + status = action->rollback_func (transaction, action->user_data); else status = POP_ACTION_ROLLBACK_STATUS_FINISHED; transaction->priv->is_in_action = FALSE; @@ -665,7 +797,7 @@ pop_transaction_rollback_current_action_and_rewind (PopTransaction *transaction) g_source_remove (transaction->priv->rollback_idle_id); transaction->priv->rollback_idle_id = 0; - pop_transaction_complete (transaction); + pop_transaction_finish (transaction); } return should_continue; @@ -684,13 +816,13 @@ pop_transaction_rollback_on_idle (PopTransaction *transaction) } static void -pop_transaction_rollback_and_complete (PopTransaction *transaction) +pop_transaction_rollback_and_finish (PopTransaction *transaction) { g_assert (POP_IS_TRANSACTION (transaction)); if (pop_transaction_is_at_first_action (transaction)) { - pop_transaction_complete (transaction); + pop_transaction_finish (transaction); return; } @@ -702,8 +834,9 @@ pop_transaction_fail (PopTransaction *transaction) { g_assert (POP_IS_TRANSACTION (transaction)); - transaction->priv->status = POP_TRANSACTION_STATUS_FAILED; - pop_transaction_rollback_and_complete (transaction); + pop_transaction_set_status (transaction, + POP_TRANSACTION_STATUS_FAILED); + pop_transaction_rollback_and_finish (transaction); } static gboolean @@ -752,18 +885,40 @@ pop_transaction_commit (PopTransaction *transaction) transaction->priv->state = POP_TRANSACTION_STATE_COMMITED; } -gboolean +static gboolean +pop_transaction_is_finished (PopTransaction *transaction) +{ + return transaction->priv->state == POP_TRANSACTION_STATE_FINISHED; +} + +void pop_transaction_cancel (PopTransaction *transaction) { - g_return_val_if_fail (POP_IS_TRANSACTION (transaction), FALSE); + g_return_if_fail (POP_IS_TRANSACTION (transaction)); + g_return_if_fail (!pop_transaction_is_finished (transaction)); - if (transaction->priv->status != POP_TRANSACTION_STATUS_NOT_FINISHED) - return FALSE; + pop_transaction_set_status (transaction, + POP_TRANSACTION_STATUS_CANCELED); - transaction->priv->status = POP_TRANSACTION_STATUS_CANCELED; - pop_transaction_rollback_and_complete (transaction); - - return TRUE; + g_signal_emit (transaction, pop_transaction_signals[CANCEL], 0); + + pop_transaction_rollback_and_finish (transaction); +} + +void +pop_transaction_rollback (PopTransaction *transaction) +{ + g_return_if_fail (POP_IS_TRANSACTION (transaction)); + g_return_if_fail (pop_transaction_is_finished (transaction)); + g_return_if_fail (pop_transaction_get_status (transaction) == + POP_TRANSACTION_STATUS_SUCCEEDED); + + pop_transaction_set_status (transaction, + POP_TRANSACTION_STATUS_NOT_FINISHED); + + g_signal_emit (transaction, pop_transaction_signals[ROLLBACK], 0); + + pop_transaction_rollback_and_finish (transaction); } #ifdef POP_TRANSACTION_ENABLE_TEST @@ -772,7 +927,7 @@ pop_transaction_cancel (PopTransaction *transaction) #include <glib.h> static void -on_transaction_complete (PopTransaction *transaction, +on_transaction_finish (PopTransaction *transaction, PopTransactionStatus status, gpointer data) { @@ -785,15 +940,17 @@ on_transaction_complete (PopTransaction *transaction, } static PopActionProcessStatus -preemptive_action (PopTransaction *transaction) +preemptive_action (PopTransaction *transaction, + gpointer user_data) { g_print ("Hello World! should get printed I guess before " "the transaction continues...so Hello World!\n"); - return POP_ACTION_PROCESS_STATUS_FINISHED; + return POP_ACTION_PROCESS_STATUS_SUCCEEDED; } static PopActionProcessStatus -test_action (PopTransaction *transaction) +test_action (PopTransaction *transaction, + gpointer user_data) { PopActionProcessStatus status; @@ -819,13 +976,13 @@ test_action (PopTransaction *transaction) case 2: g_print ("5 seconds elapsed, finishing first action...\n"); - status = POP_ACTION_PROCESS_STATUS_FINISHED; + status = POP_ACTION_PROCESS_STATUS_SUCCEEDED; break; case 3: g_print ("Second instance of test action\n"); g_print ("waiting on blocking action before continuing.\n"); - pop_transaction_add_action (transaction, preemptive_action, NULL); + pop_transaction_add_action (transaction, preemptive_action, NULL, NULL); status = POP_ACTION_PROCESS_STATUS_NOT_FINISHED; break; @@ -843,7 +1000,8 @@ test_action (PopTransaction *transaction) } static PopActionRollbackStatus -test_action_cleanup (PopTransaction *transaction) +test_action_cleanup (PopTransaction *transaction, + gpointer user_data) { g_print ("cleaning up!\n"); return POP_ACTION_ROLLBACK_STATUS_FINISHED; @@ -864,15 +1022,19 @@ main (int argc, char **argv) loop = g_main_loop_new (NULL, FALSE); g_message ("creating instance of 'transaction' object..."); - transaction = pop_transaction_new (on_transaction_complete, loop); + transaction = pop_transaction_new (); g_message ("'transaction' object created successfully"); + g_signal_connect (G_OBJECT (transaction), "finish", + G_CALLBACK (on_transaction_finish), + loop); + g_message ("adding simple test action..."); - pop_transaction_add_action (transaction, test_action, test_action_cleanup); + pop_transaction_add_action (transaction, test_action, test_action_cleanup, NULL); g_message ("done adding simple test action..."); g_message ("adding duplicate test action..."); - pop_transaction_add_action (transaction, test_action, NULL); + pop_transaction_add_action (transaction, test_action, NULL, NULL); g_message ("done adding test action..."); g_message ("committing transaction to be processed..."); diff --git a/src/pop-transaction.h b/src/pop-transaction.h index a5f9dfc..ae2ca15 100644 --- a/src/pop-transaction.h +++ b/src/pop-transaction.h @@ -35,15 +35,14 @@ typedef struct _PopTransactionClass PopTransactionClass; typedef struct _PopTransactionPrivate PopTransactionPrivate; typedef enum _PopTransactionStatus PopTransactionStatus; -typedef void (* PopTransactionCompleteFunc) (PopTransaction *transaction, - PopTransactionStatus status, - gpointer user_data); typedef enum _PopActionProcessStatus PopActionProcessStatus; -typedef PopActionProcessStatus (* PopActionProcessFunc) (PopTransaction *transaction); +typedef PopActionProcessStatus (* PopActionProcessFunc) (PopTransaction *transaction, + gpointer user_data); typedef enum _PopActionRollbackStatus PopActionRollbackStatus; -typedef PopActionRollbackStatus (* PopActionRollbackFunc) (PopTransaction *transaction); +typedef PopActionRollbackStatus (* PopActionRollbackFunc) (PopTransaction *transaction, + gpointer user_data); struct _PopTransaction { @@ -61,21 +60,24 @@ struct _PopTransactionClass void (* process) (PopTransaction *transaction); void (* wait) (PopTransaction *transaction); void (* resume) (PopTransaction *transaction); + void (* cancel) (PopTransaction *transaction); + void (* finish) (PopTransaction *transaction); + void (* rollback) (PopTransaction *transaction); }; enum _PopTransactionStatus { POP_TRANSACTION_STATUS_NOT_FINISHED = 100, - POP_TRANSACTION_STATUS_FINISHED, POP_TRANSACTION_STATUS_CANCELED, - POP_TRANSACTION_STATUS_FAILED + POP_TRANSACTION_STATUS_FAILED, + POP_TRANSACTION_STATUS_SUCCEEDED, }; enum _PopActionProcessStatus { POP_ACTION_PROCESS_STATUS_NOT_FINISHED = 200, - POP_ACTION_PROCESS_STATUS_FINISHED, - POP_ACTION_PROCESS_STATUS_FAILED + POP_ACTION_PROCESS_STATUS_FAILED, + POP_ACTION_PROCESS_STATUS_SUCCEEDED, }; enum _PopActionRollbackStatus @@ -87,11 +89,22 @@ enum _PopActionRollbackStatus #ifndef POP_HIDE_FUNCTION_DECLARATIONS GType pop_transaction_get_type (void); -PopTransaction *pop_transaction_new (PopTransactionCompleteFunc complete_func, - gpointer user_data); +PopTransaction *pop_transaction_new (void); +PopTransactionStatus pop_transaction_get_status (PopTransaction *transaction); void pop_transaction_add_action (PopTransaction *transaction, PopActionProcessFunc action_process_func, - PopActionRollbackFunc action_rollback_func); + PopActionRollbackFunc action_rollback_func, + gpointer user_data); +void pop_transaction_add_action_full (PopTransaction *transaction, + PopActionProcessFunc action_process_func, + PopActionRollbackFunc action_rollback_func, + gpointer user_data, + GDestroyNotify free_func); + +void pop_transaction_add_subtransaction (PopTransaction *transaction, + PopTransaction *subtransaction); +void pop_transaction_wait (PopTransaction *transaction); +void pop_transaction_resume (PopTransaction *transaction); void pop_transaction_wait_for_fd (PopTransaction *transaction, int fd, GIOCondition condition, GDestroyNotify destroy_notify); @@ -102,7 +115,8 @@ void pop_transaction_wait_a_while (PopTransaction *transaction, void pop_transaction_attach (PopTransaction *transaction, GMainContext *context); void pop_transaction_commit (PopTransaction *transaction); -gboolean pop_transaction_cancel (PopTransaction *transaction); +void pop_transaction_cancel (PopTransaction *transaction); +void pop_transaction_rollback (PopTransaction *transaction); #endif G_END_DECLS |