Пример #1
0
void
sxe_sync_ev_init(unsigned concurrency, void (*send_event)(void * sync, void * user_data))
{
    unsigned short port;

    SXEE82("sxe_sync_ev_init(concurrency=%u,send_event=%p)", concurrency, send_event);
    sxe_sync_ev_pool                 = sxe_pool_new("http_sync_ev", concurrency, sizeof(SXE_SYNC_EV), 2);
    sxe_sync_ev_sock                 = sxe_sync_ev_socket();
    sxe_sync_generic_event           = send_event;
    sxe_sync_ev_addr.sin_family      = AF_INET;
    sxe_sync_ev_addr.sin_addr.s_addr = inet_addr("127.0.0.1");

    for (port = 1025; ; port++) {
        sxe_sync_ev_addr.sin_port = htons(port);

        if (bind(sxe_sync_ev_sock, (struct sockaddr *)&sxe_sync_ev_addr, sizeof(sxe_sync_ev_addr)) >= 0) {
            break;
        }

        SXEA12(port < USHRT_MAX, "Not able to bind any port between 1024 and %hu: %s", port,   /* Coverage Exclusion - Assert      */
               sxe_socket_get_last_error_as_str());
    }                                                                                          /* Coverage Exclusion - Not Reached */

    SXEL81("Listening on port %hu", port);
    ev_io_init(&sxe_sync_ev_io, sxe_sync_ev_read, _open_osfhandle(sxe_sync_ev_sock, 0), EV_READ);
    ev_io_start(ev_default_loop(0), &sxe_sync_ev_io);
    SXER80("return");
}
Пример #2
0
static void
select_modify (EV_P_ int fd, int oev, int nev)
{
  SXEE83("select_modify(fd=%p, oev=%d, nev=%d)", fd, oev, nev);

  if (oev == nev) {
    SXER80("return // oev == nev");
    return;
  }

  {
#if EV_SELECT_USE_FD_SET
    #if EV_SELECT_IS_WINSOCKET
    SOCKET handle = anfds [fd].handle;
    #else
    int handle = fd;
    #endif

    SXEL80("#if EV_SELECT_USE_FD_SET");
    SXEL81("handle = %d", handle);

    assert (("libev: fd >= FD_SETSIZE passed to fd_set-based select backend", fd < FD_SETSIZE));

    /* FD_SET is broken on windows (it adds the fd to a set twice or more,
     * which eventually leads to overflows). Need to call it only on changes.
     */
    #if EV_SELECT_IS_WINSOCKET
    if ((oev ^ nev) & EV_READ) {
      SXEL80("EV_SELECT_IS_WINSOCKET => (oev ^ nev) & EV_READ == TRUE");
    #endif
      if (nev & EV_READ) {
        SXEL82("FD_SET(handle=%d, vec_ri=%p)", handle, vec_ri);
        FD_SET (handle, (fd_set *)vec_ri);
      }
      else {
        SXEL82("FD_CLR(handle=%d, vec_ri=%p)", handle, vec_ri);
        FD_CLR (handle, (fd_set *)vec_ri);
      }
    #if EV_SELECT_IS_WINSOCKET
    }
    #endif

    #if EV_SELECT_IS_WINSOCKET
    if ((oev ^ nev) & EV_WRITE) {
      SXEL80("EV_SELECT_IS_WINSOCKET => (oev ^ nev) & EV_WRITE == TRUE");
    #endif
      if (nev & EV_WRITE) {
        SXEL82("FD_SET(handle=%d, vec_wi=%p)", handle, vec_wi);
        FD_SET (handle, (fd_set *)vec_wi);
      }
      else {
        SXEL82("FD_CLR(handle=%d, vec_wi=%p)", handle, vec_wi);
        FD_CLR (handle, (fd_set *)vec_wi);
      }
    #if EV_SELECT_IS_WINSOCKET
    }
    #endif

    SXEL80("#endif // EV_SELECT_USE_FD_SET");

#else

    SXEL80("#if *NOT* EV_SELECT_USE_FD_SET");

    int     word = fd / NFDBITS;
    fd_mask mask = 1UL << (fd % NFDBITS);

    if (expect_false (vec_max <= word))
      {
        int new_max = word + 1;

        vec_ri = ev_realloc (vec_ri, new_max * NFDBYTES);
        vec_ro = ev_realloc (vec_ro, new_max * NFDBYTES); /* could free/malloc */
        vec_wi = ev_realloc (vec_wi, new_max * NFDBYTES);
        vec_wo = ev_realloc (vec_wo, new_max * NFDBYTES); /* could free/malloc */
        #ifdef _WIN32
        vec_eo = ev_realloc (vec_eo, new_max * NFDBYTES); /* could free/malloc */
        #endif

        for (; vec_max < new_max; ++vec_max)
          ((fd_mask *)vec_ri) [vec_max] =
          ((fd_mask *)vec_wi) [vec_max] = 0;
      }

    ((fd_mask *)vec_ri) [word] |= mask;
    if (!(nev & EV_READ))
      ((fd_mask *)vec_ri) [word] &= ~mask;

    ((fd_mask *)vec_wi) [word] |= mask;
    if (!(nev & EV_WRITE))
      ((fd_mask *)vec_wi) [word] &= ~mask;

    SXEL80("#endif // *NOT* EV_SELECT_USE_FD_SET");
#endif
  }
  SXER80("return");
}
Пример #3
0
static void
select_poll (EV_P_ ev_tstamp timeout)
{
  struct timeval tv;
  int res;
  int fd_setsize;

  EV_RELEASE_CB;
  tv.tv_sec  = (long)timeout;
  tv.tv_usec = (long)((timeout - (ev_tstamp)tv.tv_sec) * 1e6);

#if EV_SELECT_USE_FD_SET
  fd_setsize = sizeof (fd_set);
#else
  fd_setsize = vec_max * NFDBYTES;
#endif

  SXEE81("select_poll(timeout=%f)", timeout);

  memcpy (vec_ro, vec_ri, fd_setsize);
  memcpy (vec_wo, vec_wi, fd_setsize);

#ifdef _WIN32
  SXEL80("Using select() on Windows");
  /* pass in the write set as except set.
   * the idea behind this is to work around a windows bug that causes
   * errors to be reported as an exception and not by setting
   * the writable bit. this is so uncontrollably lame.
   */
  memcpy (vec_eo, vec_wi, fd_setsize);
  res = select (vec_max * NFDBITS, (fd_set *)vec_ro, (fd_set *)vec_wo, (fd_set *)vec_eo, &tv);
#elif EV_SELECT_USE_FD_SET
  SXEL80("Using select() with fd_set...");
  fd_setsize = anfdmax < FD_SETSIZE ? anfdmax : FD_SETSIZE;
  res = select (fd_setsize, (fd_set *)vec_ro, (fd_set *)vec_wo, 0, &tv);
#else
  SXEL80("Using select() without fd_set...");
  res = select (vec_max * NFDBITS, (fd_set *)vec_ro, (fd_set *)vec_wo, 0, &tv);
#endif
  EV_ACQUIRE_CB;

  if (expect_false (res < 0))
    {
      SXEL81("expect_false (res < 0) // res=%d", res);
      #if EV_SELECT_IS_WINSOCKET
      errno = WSAGetLastError ();
      SXEL81("errno=%d", errno);
      #endif
      #ifdef WSABASEERR
      /* on windows, select returns incompatible error codes, fix this */
      if (errno >= WSABASEERR && errno < WSABASEERR + 1000)
        if (errno == WSAENOTSOCK)
          errno = EBADF;
        else
          errno -= WSABASEERR;
      SXEL81("errno=%d // after fixing error code", errno);
      #endif

      #ifdef _WIN32
      /* select on windows errornously returns EINVAL when no fd sets have been
       * provided (this is documented). what microsoft doesn't tell you that this bug
       * exists even when the fd sets _are_ provided, so we have to check for this bug
       * here and emulate by sleeping manually.
       * we also get EINVAL when the timeout is invalid, but we ignore this case here
       * and assume that EINVAL always means: you have to wait manually.
       */
      if (errno == EINVAL)
        {
          SXEL81("ev_sleep(timeout=%f)", timeout);
          ev_sleep (timeout);
          SXER80("return // errno == EINVAL");
          return;
        }
      #endif

      if (errno == EBADF)
        fd_ebadf (EV_A);
      else if (errno == ENOMEM && !syserr_cb)
        fd_enomem (EV_A);
      else if (errno != EINTR)
        ev_syserr ("(libev) select");

      SXER80("return // expect_false (res < 0)");
      return;
    }

#if EV_SELECT_USE_FD_SET

  {
    int fd;

    SXEL80("#if EV_SELECT_USE_FD_SET");

    for (fd = 0; fd < anfdmax; ++fd)
      if (anfds [fd].events)
        {
          int events = 0;
          #if EV_SELECT_IS_WINSOCKET
          SOCKET handle = anfds [fd].handle;
          #else
          int handle = fd;
          #endif

          if (FD_ISSET (handle, (fd_set *)vec_ro)) events |= EV_READ;
          if (FD_ISSET (handle, (fd_set *)vec_wo)) events |= EV_WRITE;
          #ifdef _WIN32
          if (FD_ISSET (handle, (fd_set *)vec_eo)) events |= EV_WRITE;
          #endif

          if (expect_true (events))
            fd_event (EV_A_ fd, events);
        }

    SXEL80("#endif // EV_SELECT_USE_FD_SET");
  }

#else

  {
    int word, bit;

    SXEL80("#if *not* EV_SELECT_USE_FD_SET");

    for (word = vec_max; word--; )
      {
        fd_mask word_r = ((fd_mask *)vec_ro) [word];
        fd_mask word_w = ((fd_mask *)vec_wo) [word];
        #ifdef _WIN32
        word_w |= ((fd_mask *)vec_eo) [word];
        #endif

        if (word_r || word_w)
          for (bit = NFDBITS; bit--; )
            {
              fd_mask mask = 1UL << bit;
              int events = 0;

              events |= word_r & mask ? EV_READ  : 0;
              events |= word_w & mask ? EV_WRITE : 0;

              if (expect_true (events))
                fd_event (EV_A_ word * NFDBITS + bit, events);
            }
      }

      SXEL80("#endif // *not* EV_SELECT_USE_FD_SET");
  }

#endif
  SXER80("return");
}