示例#1
0
/* Here is the all important looping function that tells the event engine to
 * start up and begin processing events.  It will continue until all events have
 * been delivered (including new ones started from event handlers), or the
 * msec_timeout is reached, or a major error has occurred.  Use -1 if you don't
 * want to set a maximum time for it to run.  A timeout of 0 will return after 1
 * non-blocking loop.  The nsock loop can be restarted again after it returns.
 * For example you could do a series of 15 second runs, allowing you to do other
 * stuff between them */
enum nsock_loopstatus nsock_loop(nsock_pool nsp, int msec_timeout) {
  mspool *ms = (mspool *)nsp;
  struct timeval loop_timeout;
  int msecs_left;
  unsigned long loopnum = 0;
  enum nsock_loopstatus quitstatus = NSOCK_LOOP_ERROR;

  gettimeofday(&nsock_tod, NULL);

  if (msec_timeout < -1) {
    ms->errnum = EINVAL;
    return NSOCK_LOOP_ERROR;
  }
  TIMEVAL_MSEC_ADD(loop_timeout, nsock_tod, msec_timeout);
  msecs_left = msec_timeout;

  if (ms->tracelevel > 2) {
    if (msec_timeout >= 0)
      nsock_trace(ms, "nsock_loop() started (timeout=%dms). %d events pending",
                  msec_timeout, ms->events_pending);
    else
      nsock_trace(ms, "nsock_loop() started (no timeout). %d events pending",
                  ms->events_pending);
  }

  while (1) {
    if (ms->quit) {
      /* We've been asked to quit the loop through nsock_loop_quit. */
      ms->quit = 0;
      quitstatus = NSOCK_LOOP_QUIT;
      break;
    }

    if (ms->events_pending == 0) {
      /* if no events at all are pending, then none can be created until
       * we quit nsock_loop() -- so we do that now. */
      quitstatus = NSOCK_LOOP_NOEVENTS;
      break;
    }

    if (msec_timeout >= 0) {
      msecs_left = MAX(0, TIMEVAL_MSEC_SUBTRACT(loop_timeout, nsock_tod));
      if (msecs_left == 0 && loopnum > 0) {
        quitstatus = NSOCK_LOOP_TIMEOUT;
        break;
      }
    }

    if (ms->engine->loop(ms, msecs_left) == -1) {
      quitstatus = NSOCK_LOOP_ERROR;
      break;
    }

    gettimeofday(&nsock_tod, NULL); /* we do this at end because there is one
                                     * at beginning of function */
    loopnum++;
  }

  return quitstatus;
}
示例#2
0
/* Create a new event structure -- must be deleted later with msevent_delete,
 * unless it returns NULL (failure).  NULL can be passed in for the msiod and
 * the userdata if not available */
msevent *msevent_new(mspool *nsp, enum nse_type type, msiod *msiod, int timeout_msecs,
                     nsock_ev_handler handler, void *userdata) {
  msevent *nse;

  /* Bring us up to date for the timeout calculation. */
  gettimeofday(&nsock_tod, NULL);

  if (msiod) {
    msiod->events_pending++;
    assert(msiod->state != NSIOD_STATE_DELETED);
  }

  /* First we check if one is available from the free list ... */
  nse = (msevent *)gh_list_pop(&nsp->free_events);
  if (!nse)
    nse = (msevent *)safe_malloc(sizeof(msevent));
  memset(nse, 0, sizeof(msevent));

  nse->id = get_new_event_id(nsp, type);
  nse->type = type;
  nse->status = NSE_STATUS_NONE;
#if HAVE_OPENSSL
  nse->sslinfo.ssl_desire = SSL_ERROR_NONE;
#endif
  if (type == NSE_TYPE_READ || type ==  NSE_TYPE_WRITE)
    filespace_init(&(nse->iobuf), 1024);
#if HAVE_PCAP

  if (type == NSE_TYPE_PCAP_READ) {
    mspcap *mp;
    int sz;

    assert(msiod != NULL);
    mp = (mspcap *)msiod->pcap;
    assert(mp);

    sz = mp->snaplen+1 + sizeof(nsock_pcap);
    filespace_init(&(nse->iobuf), sz);
  }
#endif

  if (timeout_msecs != -1) {
    assert(timeout_msecs >= 0);
    TIMEVAL_MSEC_ADD(nse->timeout, nsock_tod, timeout_msecs);
  }

  nse->iod = msiod;
  nse->handler = handler;
  nse->userdata = userdata;

  if (nse->iod == NULL)
    nsock_log_debug(nsp, "msevent_new (IOD #NULL) (EID #%li)", nse->id);
  else
    nsock_log_debug(nsp, "msevent_new (IOD #%li) (EID #%li)", nse->iod->id,
                    nse->id);
  return nse;
}