diff options
author | Ray Strode <rstrode@redhat.com> | 2007-05-06 17:35:10 -0400 |
---|---|---|
committer | Ray Strode <rstrode@redhat.com> | 2007-05-06 17:35:10 -0400 |
commit | 3983a0759e2c822dfbca6290a48ee9860404a848 (patch) | |
tree | 6d90ae15ba9c8ea99d0bba13017b6915f0b57db7 | |
parent | 69803e10acc9851eae9fb02bd22909e2103104a6 (diff) |
repeat a node if child nodes get added to it
use common buffer for read and write action in test case
-rw-r--r-- | src/pop-transaction.c | 84 |
1 files changed, 52 insertions, 32 deletions
diff --git a/src/pop-transaction.c b/src/pop-transaction.c index 2672ce2..011828a 100644 --- a/src/pop-transaction.c +++ b/src/pop-transaction.c @@ -133,6 +133,8 @@ struct _PopActionTree { GNode *root; GNode *current_action_node; + GNode *last_action_node; + guint has_new_nodes : 1; }; static PopActionTree *pop_action_tree_new (void); @@ -436,7 +438,7 @@ pop_action_tree_new (void) { PopActionTree *action_tree; - action_tree = g_slice_new (PopActionTree); + action_tree = g_slice_new0 (PopActionTree); action_tree->root = g_node_new (NULL); pop_action_tree_reset (action_tree); @@ -448,6 +450,7 @@ static void pop_action_tree_reset (PopActionTree *action_tree) { action_tree->current_action_node = NULL; + action_tree->has_new_nodes = FALSE; } static gboolean @@ -519,14 +522,7 @@ pop_action_tree_walk_to_leaf (PopActionTree *action_tree, node = current_node; while (node->children != NULL) { - if (direction == POP_ACTION_TREE_WALK_DIRECTION_FORWARD) - { - node = g_node_first_child (node); - } - else - { - node = g_node_last_child (node); - } + node = g_node_first_child (node); } return node; @@ -541,6 +537,22 @@ pop_action_tree_seek (PopActionTree *action_tree, g_assert ((direction == POP_ACTION_TREE_WALK_DIRECTION_FORWARD) || (direction == POP_ACTION_TREE_WALK_DIRECTION_BACKWARD)); + /* we got to backtrack a little if the node hierarchy changed out + * from under us. Note by doing this, some nodes will get + * visited more than once, so the caller needs to check the + * action status and skip it if it's finished. We could color + * the nodes to prevent revisiting nodes, but there isn't much + * point. + */ + if (action_tree->has_new_nodes) + { + GNode *last_node; + last_node = action_tree->last_action_node; + action_tree->last_action_node = action_tree->current_action_node; + action_tree->current_action_node = last_node; + action_tree->has_new_nodes = FALSE; + } + /* if current_action_node is NULL then we haven't started yet, * so set node to a child of the root. Otherwise, walk node * one step in the tree (to the next sibling, or the parent @@ -576,6 +588,7 @@ pop_action_tree_seek (PopActionTree *action_tree, if (direction == POP_ACTION_TREE_WALK_DIRECTION_FORWARD) node = pop_action_tree_walk_to_leaf (action_tree, node, direction); + action_tree->last_action_node = action_tree->current_action_node; action_tree->current_action_node = node; return TRUE; @@ -593,6 +606,8 @@ pop_action_tree_add_action (PopActionTree *action_tree, { g_node_insert_data (action_tree->root, -1, action); } + + action_tree->has_new_nodes = TRUE; } static PopAction * @@ -862,13 +877,11 @@ pop_transaction_process_action_and_seek_forward (PopTransaction *transaction) action = pop_action_tree_get_current_action (transaction->priv->action_tree); - if (action->process_status != POP_ACTION_PROCESS_STATUS_NOT_FINISHED) - return FALSE; - transaction->priv->is_running_action = TRUE; if (action->process_func != NULL) { - action->process_status = action->process_func (transaction, action->user_data); + if (action->process_status == POP_ACTION_PROCESS_STATUS_NOT_FINISHED) + action->process_status = action->process_func (transaction, action->user_data); } else { @@ -947,13 +960,11 @@ pop_transaction_rollback_action_and_rewind (PopTransaction *transaction) action = pop_action_tree_get_current_action (transaction->priv->action_tree); - if (action->rollback_status != POP_ACTION_ROLLBACK_STATUS_NOT_FINISHED) - return FALSE; - transaction->priv->is_running_action = TRUE; if (action->rollback_func != NULL) { - action->rollback_status = action->rollback_func (transaction, action->user_data); + if (action->rollback_status == POP_ACTION_ROLLBACK_STATUS_NOT_FINISHED) + action->rollback_status = action->rollback_func (transaction, action->user_data); } else { @@ -1376,7 +1387,7 @@ proces_io_action (PopTransaction *transaction, "is-ready")); if (!is_ready) { - g_print ("waiting for fd %d to become ready.\n", arguments->fd); + 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) */ @@ -1392,7 +1403,7 @@ proces_io_action (PopTransaction *transaction, return POP_ACTION_PROCESS_STATUS_NOT_FINISHED; } - g_print ("fd %d is now ready!\n", arguments->fd); + g_printerr ("fd %d is now ready!\n", arguments->fd); bytes_done = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (transaction), "bytes-already-processed")); @@ -1405,18 +1416,26 @@ proces_io_action (PopTransaction *transaction, { GError *error; - if ((errno == EINTR) || (errno == EAGAIN)) + if (errno == EINTR) { return POP_ACTION_PROCESS_STATUS_NOT_FINISHED; } + else if (errno == EAGAIN) + { + pop_transaction_wait_for_fd (transaction, arguments->fd, condition, + NULL); + return POP_ACTION_PROCESS_STATUS_NOT_FINISHED; + } + else + { + error = g_error_new_literal (G_FILE_ERROR, + g_file_error_from_errno (errno), + g_strerror (errno)); - error = g_error_new_literal (G_FILE_ERROR, - g_file_error_from_errno (errno), - g_strerror (errno)); - - pop_transaction_set_error (transaction, error); - g_error_free (error); - return POP_ACTION_PROCESS_STATUS_FAILED; + pop_transaction_set_error (transaction, error); + g_error_free (error); + return POP_ACTION_PROCESS_STATUS_FAILED; + } } g_assert (bytes_done_this_time <= bytes_left); @@ -1456,7 +1475,7 @@ static PopActionProcessStatus process_read_action (PopTransaction *transaction, gpointer arguments) { - g_print ("processing read action\n"); + g_printerr ("processing read action\n"); return proces_io_action (transaction, (InputOutputFunc) read, arguments, G_IO_IN); } @@ -1465,7 +1484,7 @@ static PopActionProcessStatus process_write_action (PopTransaction *transaction, gpointer arguments) { - g_print ("processing write action\n"); + g_printerr ("processing write action\n"); return proces_io_action (transaction, (InputOutputFunc) write, arguments, G_IO_OUT); } @@ -1475,7 +1494,7 @@ process_cat_action (PopTransaction *transaction, gpointer data) { char *buffer; - static const size_t buffer_size = 4096 * 10; + static const size_t buffer_size = 10; InputOutputArguments *input_arguments, *output_arguments; fcntl (STDIN_FILENO, F_SETFL, O_NONBLOCK); @@ -1483,7 +1502,7 @@ process_cat_action (PopTransaction *transaction, input_arguments = g_slice_new (InputOutputArguments); input_arguments->fd = STDIN_FILENO; - input_arguments->buffer = g_malloc (buffer_size); + input_arguments->buffer = g_malloc0 (buffer_size); input_arguments->number_of_bytes_to_process = buffer_size; pop_transaction_add_action (transaction, process_read_action, @@ -1492,7 +1511,7 @@ process_cat_action (PopTransaction *transaction, output_arguments = g_slice_new (InputOutputArguments); output_arguments->fd = STDOUT_FILENO; - output_arguments->buffer = g_malloc (buffer_size); + output_arguments->buffer = input_arguments->buffer; output_arguments->number_of_bytes_to_process = buffer_size; pop_transaction_add_action (transaction, process_write_action, NULL, @@ -1514,6 +1533,7 @@ rollback_cat_action (PopTransaction *transaction, 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; |