static void command_unsubscribe(char * token, Channel * c) { char type[256]; int err = 0; Subscription * s = NULL; LINK * l; json_read_string(&c->inp, type, sizeof(type)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); for (l = subscriptions.next; l != &subscriptions;) { Subscription * h = all2subscription(l); l = l->next; if (h->channel == c && strcmp(type, h->type) == 0) { s = h; break; } } if (s == NULL) err = ERR_INV_CONTEXT; if (err == 0) delete_subscription(s); write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); write_stream(&c->out, MARKER_EOM); }
static void command_subscribe(char * token, Channel * c) { char type[256]; int err = 0; LINK * l; json_read_string(&c->inp, type, sizeof(type)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); for (l = subscriptions.next; l != &subscriptions;) { Subscription * h = all2subscription(l); l = l->next; if (h->channel == c && strcmp(type, h->type) == 0) { err = ERR_OTHER; break; } } if (err == 0) { Subscription * s = loc_alloc_zero(sizeof(Subscription)); list_init(&s->link_all); list_add_first(&s->link_all, &subscriptions); strncpy(s->type, type, sizeof(s->type) - 1); s->channel = c; } write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); write_stream(&c->out, MARKER_EOM); }
void virtual_stream_create(const char * type, const char * context_id, size_t buf_len, unsigned access, VirtualStreamCallBack * callback, void * callback_args, VirtualStream ** res) { LINK * l; VirtualStream * stream = loc_alloc_zero(sizeof(VirtualStream)); buf_len++; list_init(&stream->clients); strncpy(stream->type, type, sizeof(stream->type) - 1); stream->magic = STREAM_MAGIC; stream->id = id_cnt++; stream->access = access; stream->callback = callback; stream->callback_args = callback_args; stream->ref_cnt = 1; stream->buf = loc_alloc(buf_len); stream->buf_len = buf_len; for (l = subscriptions.next; l != &subscriptions; l = l->next) { Subscription * h = all2subscription(l); if (strcmp(type, h->type) == 0) { Trap trap; create_client(stream, h->channel); if (set_trap(&trap)) { send_event_stream_created(&h->channel->out, stream, context_id); clear_trap(&trap); } else { trace(LOG_ALWAYS, "Exception sending stream created event: %d %s", trap.error, errno_to_str(trap.error)); } } } list_add_first(&stream->link_all, &streams); *res = stream; }
int virtual_stream_unsubscribe(Channel * c, const char * type) { LINK * l; int err = 0; Subscription * s = NULL; for (l = subscriptions.next; l != &subscriptions;) { Subscription * h = all2subscription(l); l = l->next; if (h->channel == c && strcmp(type, h->type) == 0) { s = h; break; } } if (s == NULL) err = ERR_INV_CONTEXT; if (err == 0) delete_subscription(s); else errno = err; return err == 0 ? 0 : -1; }
static void channel_close_listener(Channel * c) { LINK * l = NULL; for (l = clients.next; l != &clients;) { StreamClient * client = all2client(l); l = l->next; if (client->channel == c) { trace(LOG_ALWAYS, "Stream is left connected by client: VS%d", client->stream->id); delete_client(client); } } for (l = subscriptions.next; l != &subscriptions;) { Subscription * h = all2subscription(l); l = l->next; if (h->channel == c) { delete_subscription(h); } } }
int virtual_stream_subscribe(Channel * c, const char * type) { LINK * l; int err = 0; for (l = subscriptions.next; l != &subscriptions;) { Subscription * h = all2subscription(l); l = l->next; if (h->channel == c && strcmp(type, h->type) == 0) { err = set_errno(ERR_OTHER, "Already subscribed"); break; } } if (err == 0) { Subscription * s = (Subscription *)loc_alloc_zero(sizeof(Subscription)); list_init(&s->link_all); list_add_first(&s->link_all, &subscriptions); strlcpy(s->type, type, sizeof(s->type)); s->channel = c; } else errno = err; return err == 0 ? 0 : -1; }