static void ipc_read_handler(ngx_event_t *ev) {
  DBG("IPC channel handler");
  //copypasta from os/unix/ngx_process_cycle.c (ngx_channel_handler)
  ngx_int_t          n;
  ipc_alert_t        alert;
  ngx_connection_t  *c;
  if (ev->timedout) {
    ev->timedout = 0;
    return;
  }
  c = ev->data;
  
  while(1) {
    n = ipc_read_socket(c->fd, &alert, ev->log);
    if (n == NGX_ERROR) {
      ERR("IPC_READ_SOCKET failed: bad connection. This should never have happened, yet here we are...");
      assert(0);
      return;
    }
    if (n == NGX_AGAIN) {
      return;
    }
    //ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0, "nchan: channel command: %d", ch.command);
    
    assert(n == sizeof(alert));
    if(alert.worker_generation < memstore_worker_generation) {
      ERR("Got IPC alert for previous generation's worker. discarding.");
    }
    else {
#if DEBUG_DELAY_IPC_RECEIVE_ALERT_MSEC
      delayed_alert_glob_t   *glob = ngx_alloc(sizeof(*glob), ngx_cycle->log);
      if (NULL == glob) {
          ERR("Couldn't allocate memory for alert glob data.");
          return;
      }
      ngx_memzero(&glob->timer, sizeof(glob->timer));
      nchan_init_timer(&glob->timer, fake_ipc_alert_delay_handler, glob);
      
      glob->alert = alert;
      glob->ipc = (ipc_t *)c->data;
      ngx_add_timer(&glob->timer, DEBUG_DELAY_IPC_RECEIVE_ALERT_MSEC);
#else
      if(ngx_time() - alert.time_sent >= 2) {
        ipc_record_alert_receive_delay(ngx_time() - alert.time_sent);
      }
      nchan_update_stub_status(ipc_total_alerts_received, 1);
      ((ipc_t *)c->data)->handler(alert.src_slot, alert.code, alert.data);
#endif
    }
  }
}
ngx_int_t ipc_init(ipc_t *ipc) {
  int                             i = 0;
  ipc_process_t                  *proc;
  
  nchan_init_timer(&receive_alert_delay_log_timer, receive_alert_delay_log_timer_handler, NULL);
  nchan_init_timer(&send_alert_delay_log_timer, send_alert_delay_log_timer_handler, NULL);
  
  for(i=0; i< NGX_MAX_PROCESSES; i++) {
    proc = &ipc->process[i];
    proc->ipc = ipc;
    proc->pipe[0]=NGX_INVALID_FILE;
    proc->pipe[1]=NGX_INVALID_FILE;
    proc->c=NULL;
    proc->active = 0;
    ngx_memzero(proc->wbuf.alerts, sizeof(proc->wbuf.alerts));
    proc->wbuf.first = 0;
    proc->wbuf.n = 0;
    proc->wbuf.overflow_first = NULL;
    proc->wbuf.overflow_last = NULL;
    proc->wbuf.overflow_n = 0;
  }
  return NGX_OK;
}
Exemple #3
0
ngx_event_t *spooler_add_timer(channel_spooler_t *spl, ngx_msec_t timeout, void (*cb)(void *), void (*cancel)(void *), void *pd) {
  spooler_event_ll_t  *spl_ev = ngx_alloc(sizeof(*spl_ev), ngx_cycle->log);
  ngx_memzero(&spl_ev->ev, sizeof(spl_ev->ev));
  nchan_init_timer(&spl_ev->ev, spooler_timer_handler, pd);
  
  spl_ev->callback = cb;
  spl_ev->cancel = cancel;
  
  spl_ev->spooler = spl;
  spl_ev->next = spl->spooler_dependent_events;
  spl_ev->prev = NULL;
  if(spl->spooler_dependent_events) {
    spl->spooler_dependent_events->prev = spl_ev;
  }
  spl->spooler_dependent_events = spl_ev;
  
  ngx_add_timer(&spl_ev->ev, timeout);
  return &spl_ev->ev;
}
Exemple #4
0
void nchan_subscriber_init_timeout_timer(subscriber_t *sub, ngx_event_t *ev) {
  ngx_memzero(ev, sizeof(*ev));
  nchan_init_timer(ev, nchan_subscriber_timeout_ev_handler, sub);
}