summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Levy <alevy@redhat.com>2011-04-11 21:44:16 +0300
committerAlon Levy <alevy@redhat.com>2011-04-26 13:50:56 +0300
commit5b27e1b0b0b1be50caef3d3401b02b5f4b024a68 (patch)
tree94c6e1f6e1f050c6f079cf5c716cc0a48f6d17c0
parent144342fb3bfddfb3899db4846ab2d7c2ce100ff3 (diff)
server/red_channel: introduce pipes functions
Introduce functions to add (via producer method) the same item to multiple pipes, all for the same channel. Note: Right now there is only a single channel, but the next patches will do the per-channel breakdown to channel and channel_client before actually introducing a ring in RedChannel, this makes it easier to make smaller changes - the channel->rcc link will exist until removed in the ring introducing patch.
-rw-r--r--server/red_channel.c51
-rw-r--r--server/red_channel.h12
2 files changed, 62 insertions, 1 deletions
diff --git a/server/red_channel.c b/server/red_channel.c
index aff99ed5..7e1edbea 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -1051,4 +1051,55 @@ void red_client_set_main(RedClient *client, MainChannelClient *mcc) {
client->mcc = mcc;
}
+/*
+ * Functions to push the same item to multiple pipes.
+ */
+
+/*
+ * TODO: after convinced of correctness, add paths for single client
+ * that avoid the whole loop. perhaps even have a function pointer table
+ * later.
+ * TODO - inline? macro? right now this is the simplest from code amount
+ */
+
+typedef void (*rcc_item_t)(RedChannelClient *rcc, PipeItem *item);
+typedef int (*rcc_item_cond_t)(RedChannelClient *rcc, PipeItem *item);
+void __red_channel_pipes_create_batch(RedChannel *channel,
+ new_pipe_item_t creator, void *data,
+ rcc_item_t visitor)
+{
+ RedChannelClient *rcc;
+ PipeItem *item;
+ int num = 0;
+
+ if (!(rcc = channel->rcc)) {
+ return;
+ }
+ item = (*creator)(rcc, data, num++);
+ if (visitor) {
+ (*visitor)(rcc, item);
+ }
+}
+
+void red_channel_pipes_new_add_push(RedChannel *channel,
+ new_pipe_item_t creator, void *data)
+{
+ __red_channel_pipes_create_batch(channel, creator, data,
+ red_channel_client_pipe_add);
+ red_channel_push(channel);
+}
+
+void red_channel_pipes_new_add(RedChannel *channel, new_pipe_item_t creator, void *data)
+{
+ __red_channel_pipes_create_batch(channel, creator, data,
+ red_channel_client_pipe_add);
+}
+
+// despite the name, this should push (TODO: match function to name)
+void red_channel_pipes_new_add_tail(RedChannel *channel, new_pipe_item_t creator, void *data)
+{
+ __red_channel_pipes_create_batch(channel, creator, data,
+ red_channel_client_pipe_add_tail_no_push);
+ red_channel_push(channel);
+}
diff --git a/server/red_channel.h b/server/red_channel.h
index 877c5679..15d70b68 100644
--- a/server/red_channel.h
+++ b/server/red_channel.h
@@ -271,6 +271,16 @@ void red_channel_client_set_message_serial(RedChannelClient *channel, uint64_t);
void red_channel_client_begin_send_message(RedChannelClient *rcc);
void red_channel_pipe_item_init(RedChannel *channel, PipeItem *item, int type);
+
+// TODO: add back the channel_pipe_add functionality - by adding reference counting
+// to the PipeItem.
+
+// helper to push a new item to all channels
+typedef PipeItem *(*new_pipe_item_t)(RedChannelClient *rcc, void *data, int num);
+void red_channel_pipes_new_add_push(RedChannel *channel, new_pipe_item_t creator, void *data);
+void red_channel_pipes_new_add(RedChannel *channel, new_pipe_item_t creator, void *data);
+void red_channel_pipes_new_add_tail(RedChannel *channel, new_pipe_item_t creator, void *data);
+
void red_channel_client_pipe_add_push(RedChannelClient *rcc, PipeItem *item);
void red_channel_client_pipe_add(RedChannelClient *rcc, PipeItem *item);
void red_channel_client_pipe_add_after(RedChannelClient *rcc, PipeItem *item, PipeItem *pos);
@@ -374,4 +384,4 @@ void red_client_destroy(RedClient *client);
void red_client_set_main(RedClient *client, MainChannelClient *mcc);
MainChannelClient *red_client_get_main(RedClient *client);
-#endif
+#endif \ No newline at end of file