Пример #1
0
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");
}
Пример #2
0
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;
}
Пример #3
0
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);
}
Пример #4
0
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);
}
Пример #5
0
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);
}
Пример #6
0
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);
}
Пример #7
0
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;
}