static void nchan_output_reserve_message_queue(ngx_http_request_t *r, nchan_msg_t *msg) { nchan_request_ctx_t *ctx = ngx_http_get_module_ctx(r, ngx_nchan_module); ngx_http_cleanup_t *cln; if(msg->storage != NCHAN_MSG_SHARED) { if((msg = nchan_msg_derive_alloc(msg)) == NULL) { ERR("Coudln't alloc derived msg for output_reserve_message_queue"); return; } } if(!ctx->reserved_msg_queue) { if((ctx->reserved_msg_queue = ngx_palloc(r->pool, sizeof(*ctx->reserved_msg_queue))) == NULL) { ERR("Coudln't palloc reserved_msg_queue"); return; } nchan_reuse_queue_init(ctx->reserved_msg_queue, offsetof(rsvmsg_queue_t, prev), offsetof(rsvmsg_queue_t, next), rsvmsg_queue_palloc, rsvmsg_queue_release, r); if((cln = ngx_http_cleanup_add(r, 0)) == NULL) { ERR("Unable to add request cleanup for reserved_msg_queue queue"); assert(0); return; } cln->data = ctx; cln->handler = nchan_reserve_msg_cleanup; } rsvmsg_queue_t *qmsg = nchan_reuse_queue_push(ctx->reserved_msg_queue); qmsg->msg = msg; msg_reserve(msg, "output reservation"); }
static ngx_int_t longpoll_multipart_add(full_subscriber_t *fsub, nchan_msg_t *msg, char **err) { nchan_longpoll_multimsg_t *mmsg; if((mmsg = ngx_palloc(fsub->sub.request->pool, sizeof(*mmsg))) == NULL) { *err = "can't allocate multipart msg link"; return NGX_ERROR; } if(msg->shared) { msg_reserve(msg, "longpoll multipart"); } else if(msg->id.tagcount > 1) { //msg from a multiplexed channel assert(!msg->shared && !msg->temp_allocd); nchan_msg_copy_t *cmsg; if((cmsg = ngx_palloc(fsub->sub.request->pool, sizeof(*cmsg))) == NULL) { *err = "can't allocate msgcopy for message from multiplexed channel"; return NGX_ERROR; } // multiplexed channel message should have been created as a nchan_msg_copy_t *cmsg = *(nchan_msg_copy_t *)msg; cmsg->copy.temp_allocd = 1; assert(cmsg->original->shared); msg_reserve(cmsg->original, "longpoll multipart for multiplexed channel"); msg = &cmsg->copy; } else { assert(0); //this is not yet an expected scenario; } mmsg->msg = msg; mmsg->next = NULL; if(fsub->data.multimsg_first == NULL) { fsub->data.multimsg_first = mmsg; } if(fsub->data.multimsg_last) { fsub->data.multimsg_last->next = mmsg; } fsub->data.multimsg_last = mmsg; return NGX_OK; }
static void send_uframe(layer2_t *l2, msg_t *msg, u_char cmd, u_char cr) { u_char tmp[MAX_HEADER_LEN]; int i; i = sethdraddr(l2, tmp, cr); tmp[i++] = cmd; if (msg) msg_trim(msg, 0); else if ((msg = alloc_msg(i + mISDNUSER_HEAD_SIZE))) msg_reserve(msg, mISDNUSER_HEAD_SIZE); else { dprint(DBGM_L2, l2->nst->cardnr,"%s: can't alloc msguff\n", __FUNCTION__); return; } memcpy(msg_put(msg, i), tmp, i); msg_push(msg, mISDNUSER_HEAD_SIZE); enqueue_super(l2, msg); }
ngx_int_t memstore_ipc_send_publish_message(ngx_int_t dst, ngx_str_t *chid, nchan_msg_t *shm_msg, nchan_loc_conf_t *cf, callback_pt callback, void *privdata) { publish_data_t data; DEBUG_MEMZERO(&data); DBG("IPC: send publish message to %i ch %V", dst, chid); assert(shm_msg->shared == 1); assert(shm_msg->temp_allocd == 0); assert(chid->data != NULL); data.shm_chid = str_shm_copy(chid); if(data.shm_chid == NULL) { return NGX_DECLINED; } data.shm_msg = shm_msg; data.cf = cf; data.callback = callback; data.callback_privdata = privdata; assert(data.shm_chid->data != NULL); assert(msg_reserve(shm_msg, "publish_message") == NGX_OK); return ipc_cmd(publish_message, dst, &data); }
void enquiry_cr(layer2_t *l2, u_char typ, u_char cr, u_char pf) { msg_t *msg; u_char tmp[MAX_HEADER_LEN]; int i; i = sethdraddr(l2, tmp, cr); if (test_bit(FLG_MOD128, &l2->flag)) { tmp[i++] = typ; tmp[i++] = (l2->vr << 1) | (pf ? 1 : 0); } else tmp[i++] = (l2->vr << 5) | typ | (pf ? 0x10 : 0); if (!(msg = alloc_msg(i + mISDNUSER_HEAD_SIZE))) { dprint(DBGM_L2, l2->nst->cardnr, "isdnl2 can't alloc sbbuff for enquiry_cr\n"); return; } else msg_reserve(msg, mISDNUSER_HEAD_SIZE); memcpy(msg_put(msg, i), tmp, i); msg_push(msg, mISDNUSER_HEAD_SIZE); enqueue_super(l2, msg); }
static void receive_get_message(ngx_int_t sender, getmessage_data_t *d) { memstore_channel_head_t *head; store_message_t *msg = NULL; assert(d->shm_chid->len>1); assert(d->shm_chid->data!=NULL); DBG("IPC: received get_message request for channel %V privdata %p", d->shm_chid, d->privdata); head = nchan_memstore_find_chanhead(d->shm_chid); if(head == NULL) { //no such thing here. reply. d->d.resp.getmsg_code = MSG_NOTFOUND; d->d.resp.shm_msg = NULL; } else { nchan_msg_status_t status; msg = chanhead_find_next_message(head, &d->d.req.msgid, &status); if(msg == NULL && head->cf && head->cf->redis.enabled) { //messages from redis are not requested explicitly, but are delivered from oldest to newest //by the memmstore-redis subscriber. getmessage_data_rsub_pd_t rdata = {sender, *d}; nchan_memstore_redis_subscriber_notify_on_MSG_EXPECTED(head->redis_sub, &d->d.req.msgid, ipc_handler_notify_on_MSG_EXPECTED_callback, sizeof(rdata), &rdata); return; } d->d.resp.getmsg_code = status; d->d.resp.shm_msg = msg == NULL ? NULL : msg->msg; } if(d->d.resp.shm_msg) { assert(msg_reserve(d->d.resp.shm_msg, "get_message_reply") == NGX_OK); } DBG("IPC: send get_message_reply for channel %V msg %p, privdata: %p", d->shm_chid, msg, d->privdata); ipc_cmd(get_message_reply, sender, d); }
ngx_int_t msg_reserve(nchan_msg_t *msg, char *lbl) { if(msg->parent) { assert(msg->storage != NCHAN_MSG_SHARED); msg->refcount++; #if NCHAN_MSG_RESERVE_DEBUG nchan_msg_reserve_debug(msg, lbl); #endif return msg_reserve(msg->parent, lbl); } assert(!msg->parent); ngx_atomic_fetch_add((ngx_atomic_uint_t *)&msg->refcount, 1); assert(msg->refcount >= 0); if(msg->refcount < 0) { msg->refcount = MSG_REFCOUNT_INVALID; return NGX_ERROR; } #if NCHAN_MSG_RESERVE_DEBUG nchan_msg_reserve_debug(msg, lbl); #endif //DBG("msg %p reserved (%i) %s", msg, msg->refcount, lbl); return NGX_OK; }