summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2007-05-06 17:35:10 -0400
committerRay Strode <rstrode@redhat.com>2007-05-06 17:35:10 -0400
commit3983a0759e2c822dfbca6290a48ee9860404a848 (patch)
tree6d90ae15ba9c8ea99d0bba13017b6915f0b57db7
parent69803e10acc9851eae9fb02bd22909e2103104a6 (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.c84
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;