static void receive_subscribe(ngx_int_t sender, subscribe_data_t *d) { memstore_channel_head_t *head; subscriber_t *ipc_sub = NULL; DBG("received subscribe request for channel %V", d->shm_chid); head = nchan_memstore_get_chanhead(d->shm_chid, d->cf); if(head == NULL) { ERR("couldn't get chanhead while receiving subscribe ipc msg"); d->shared_channel_data = NULL; d->d.subscriber = NULL; } else { ipc_sub = memstore_ipc_subscriber_create(sender, &head->id, d->cf, d->d.origin_chanhead); d->d.subscriber = ipc_sub; d->shared_channel_data = head->shared; assert(d->shared_channel_data); } ipc_cmd(subscribe_reply, sender, d); DBG("sent subscribe reply for channel %V to %i", d->shm_chid, sender); if(ipc_sub) { head->spooler.fn->add(&head->spooler, ipc_sub); } }
subscriber_t *memstore_multi_subscriber_create(nchan_store_channel_head_t *chanhead, uint8_t n) { static nchan_msg_id_t latest_msgid = NCHAN_NEWEST_MSGID; sub_data_t *d; nchan_store_channel_head_t *target_ch; ngx_int_t multi_subs; nchan_loc_conf_t cf; cf.use_redis = chanhead->use_redis; d = ngx_alloc(sizeof(*d), ngx_cycle->log); if(d == NULL) { ERR("couldn't allocate memstore-multi subscriber data"); return NULL; } subscriber_t *sub = internal_subscriber_create(&sub_name, d); internal_subscriber_set_enqueue_handler(sub, (callback_pt )sub_enqueue); internal_subscriber_set_dequeue_handler(sub, (callback_pt )sub_dequeue); internal_subscriber_set_respond_message_handler(sub, (callback_pt )sub_respond_message); internal_subscriber_set_respond_status_handler(sub, (callback_pt )sub_respond_status); internal_subscriber_set_notify_handler(sub, (callback_pt )sub_notify_handler); sub->last_msgid = latest_msgid; sub->destroy_after_dequeue = 1; sub->dequeue_after_response = 0; d->multi = &chanhead->multi[n]; d->multi->sub = sub; d->multi_chanhead = chanhead; d->n = n; chanhead->multi_waiting++; target_ch = nchan_memstore_get_chanhead(&d->multi->id, &cf); assert(target_ch); target_ch->spooler.fn->add(&target_ch->spooler, sub); multi_subs = chanhead->shared->sub_count; d->target_chanhead = target_ch; change_sub_count(target_ch, multi_subs); DBG("%p created with privdata %p", d->multi->sub, d); return sub; }
static void receive_publish_message(ngx_int_t sender, publish_data_t *d) { publish_callback_data cd_data; publish_callback_data *cd; memstore_channel_head_t *head; assert(d->shm_chid->data != NULL); DBG("IPC: received publish request for channel %V msg %p", d->shm_chid, d->shm_msg); if(memstore_channel_owner(d->shm_chid) == memstore_slot()) { if(d->cf->redis.enabled) { cd = ngx_alloc(sizeof(*cd) + sizeof(*d), ngx_cycle->log); cd->allocd=1; cd->d = (publish_data_t *)&cd[1]; *cd->d = *d; } else { cd = &cd_data; cd->allocd=0; cd->d = d; } cd->sender = sender; nchan_store_publish_message_generic(d->shm_chid, d->shm_msg, 1, d->cf, publish_message_generic_callback, cd); //string will be freed on publish response } else { if((head = nchan_memstore_get_chanhead(d->shm_chid, d->cf))) { nchan_memstore_publish_generic(head, d->shm_msg, 0, NULL); } else { ERR("Unable to get chanhead for publishing"); } //don't deallocate shm_msg } msg_release(d->shm_msg, "publish_message"); str_shm_free(d->shm_chid); d->shm_chid=NULL; }