mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2025-12-27 07:29:32 +00:00
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.
This commit is contained in:
parent
03cf66383c
commit
0f0bdb190b
@ -906,17 +906,17 @@ int red_channel_all_clients_serials_are_zero(RedChannel *channel)
|
||||
return (!channel->rcc || channel->rcc->send_data.serial == 0);
|
||||
}
|
||||
|
||||
void red_channel_apply_clients(RedChannel *channel, channel_client_visitor v)
|
||||
void red_channel_apply_clients(RedChannel *channel, channel_client_callback cb)
|
||||
{
|
||||
if (channel->rcc) {
|
||||
v(channel->rcc);
|
||||
cb(channel->rcc);
|
||||
}
|
||||
}
|
||||
|
||||
void red_channel_apply_clients_data(RedChannel *channel, channel_client_visitor_data v, void *data)
|
||||
void red_channel_apply_clients_data(RedChannel *channel, channel_client_callback_data cb, void *data)
|
||||
{
|
||||
if (channel->rcc) {
|
||||
v(channel->rcc, data);
|
||||
cb(channel->rcc, data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1071,3 +1071,54 @@ MainChannelClient *red_client_get_main(RedClient *client) {
|
||||
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);
|
||||
|
||||
static void red_channel_pipes_create_batch(RedChannel *channel,
|
||||
new_pipe_item_t creator, void *data,
|
||||
rcc_item_t callback)
|
||||
{
|
||||
RedChannelClient *rcc;
|
||||
PipeItem *item;
|
||||
int num = 0;
|
||||
|
||||
if (!(rcc = channel->rcc)) {
|
||||
return;
|
||||
}
|
||||
item = (*creator)(rcc, data, num++);
|
||||
if (callback) {
|
||||
(*callback)(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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -270,6 +270,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);
|
||||
@ -358,10 +368,10 @@ RedClient *red_channel_client_get_client(RedChannelClient *rcc);
|
||||
SpiceDataHeader *red_channel_client_get_header(RedChannelClient *rcc);
|
||||
|
||||
/* apply given function to all connected clients */
|
||||
typedef void (*channel_client_visitor)(RedChannelClient *rcc);
|
||||
typedef void (*channel_client_visitor_data)(RedChannelClient *rcc, void *data);
|
||||
void red_channel_apply_clients(RedChannel *channel, channel_client_visitor v);
|
||||
void red_channel_apply_clients_data(RedChannel *channel, channel_client_visitor_data v, void *data);
|
||||
typedef void (*channel_client_callback)(RedChannelClient *rcc);
|
||||
typedef void (*channel_client_callback_data)(RedChannelClient *rcc, void *data);
|
||||
void red_channel_apply_clients(RedChannel *channel, channel_client_callback v);
|
||||
void red_channel_apply_clients_data(RedChannel *channel, channel_client_callback_data v, void *data);
|
||||
|
||||
struct RedClient {
|
||||
RingItem link;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user