Exemplo n.º 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");
}
Exemplo n.º 2
0
void
sxe_ring_buffer_join(void * base, SXE_RING_BUFFER_CONTEXT * context, bool replay_half)
{
    SXEE80("sxe_ring_buffer_join()");
    context->itteration     = SXE_RING_BUFFER_ITERATION;
    context->data_block     = SXE_RING_BUFFER_CURRENT;
    context->data_block_len = 0;

    if (replay_half) {
        if (SXE_RING_BUFFER_CURRENT - SXE_RING_BUFFER_ARRAY_BASE >= (int)(SXE_RING_BUFFER_SIZE / 2)) {
            // If the current pointer is over half way through
            SXEL90("Current pointer is more then half way through ring");
            context->data_block = SXE_RING_BUFFER_CURRENT - (unsigned)(SXE_RING_BUFFER_SIZE / 2);
        }
        else if (SXE_RING_BUFFER_ITERATION == 0) {
            // First iteration, and havn't writen a half ring yet, go to the start of the array
            context->data_block = SXE_RING_BUFFER_ARRAY_BASE;
        }
        else {
            // else we have to go back an itteration
            SXEL90("Current pointer is less then half way through ring");
            SXEL90("Going back an itteration");
            context->itteration--;
            context->data_block = SXE_RING_BUFFER_CURRENT + (int)((SXE_RING_BUFFER_WRITEN_END - SXE_RING_BUFFER_ARRAY_BASE + 1) / 2);
        }
    }
    SXEL92("context data_block: %p, itteration: %u", context->data_block, context->itteration);
    SXER80("return");
}
Exemplo n.º 3
0
void *
sxe_sync_ev_delete(void * sync_point)
{
    SXEE81("sxe_sync_ev_delete(sync_point=%p)", sync_point);
    sxe_pool_set_indexed_element_state(sxe_sync_ev_pool, (SXE_SYNC_EV *)sync_point - sxe_sync_ev_pool, 1, 0);
    SXER80("return NULL");
    return NULL;
}
Exemplo n.º 4
0
static void
test_pool_3_timeout(void * array, unsigned array_index, void * caller_info)
{
    SXEE82("test_pool_3_timeout(array=%p,array_index=%u)", array, array_index);
    SXE_UNUSED_PARAMETER(caller_info);
    sxe_pool_set_indexed_element_state(array, array_index, 0, 1);
    sxe_pool_set_indexed_element_state(array, array_index, 1, 0);
    SXER80("return");
}
Exemplo n.º 5
0
void
sxe_ring_buffer_force_ring_wrap(void * base)
{
    SXEE80("sxe_ring_buffer_force_ring_wrap()");
    SXE_RING_BUFFER_WRITEN_END = SXE_RING_BUFFER_CURRENT - 1;
    SXE_RING_BUFFER_CURRENT = SXE_RING_BUFFER_ARRAY_BASE;
    SXE_RING_BUFFER_ITERATION++;
    SXER80("return");
}
Exemplo n.º 6
0
void
sxe_ring_buffer_next_writable_block(void * base, SXE_RING_BUFFER_CONTEXT * context)
{
    SXEE80("sxe_ring_buffer_next_writable_block()");
    context->writable_block = SXE_RING_BUFFER_CURRENT;
    context->writable_block_len = SXE_RING_BUFFER_END - SXE_RING_BUFFER_CURRENT + 1;
    SXEA10(context->writable_block_len != 0, "The writable block length is not zero");
    SXEL92("Writable block: %p, Writable block length: %u", context->writable_block, context->writable_block_len);
    SXER80("return");
}
Exemplo n.º 7
0
void
sxe_sync_ev_post(void * sync_point)
{
    SXE_SYNC_EV * sync_ev = (SXE_SYNC_EV *)sync_point;

    SXEE81("sxe_sync_ev_post(sync_point=%p)", sync_point);
    SXEA11(sendto(sync_ev->sock, (MOCK_SOCKET_VOID *)&sync_point, sizeof(sync_point), 0, (struct sockaddr *)&sxe_sync_ev_addr,
                  sizeof(sxe_sync_ev_addr)) == sizeof(sync_point),
           "Can't send to sync_point listener port: %s", sxe_socket_get_last_error_as_str());
    SXER80("return");
}
Exemplo n.º 8
0
void
sxe_ring_buffer_next_writable_block_size(void * base, SXE_RING_BUFFER_CONTEXT * context, unsigned size)
{
    SXEE81("sxe_ring_buffer_next_writable_block_size(size=%u)", size);
    SXEA10(size <= SXE_RING_BUFFER_SIZE, "The requested size is equall or smaller then the ring");
    sxe_ring_buffer_next_writable_block(base, context);
    if (context->writable_block_len < size) {
        sxe_ring_buffer_force_ring_wrap(base);
        sxe_ring_buffer_next_writable_block(base, context);
    }
    SXER80("return");
}
Exemplo n.º 9
0
static void
test_pool_1_timeout(void * array, unsigned array_index, void * caller_info)
{
    SXEE83("test_pool_1_timeout(array=%p,array_index=%u,caller_info=%p)", array, array_index, caller_info);
    SXE_UNUSED_PARAMETER(caller_info);
    test_pool_1_timeout_call_count ++;

    if (1 == test_pool_1_timeout_call_count) {
        sxe_pool_set_indexed_element_state(array, array_index, TEST_STATE_ABUSED, TEST_STATE_FREE);
    }

    if (2 == test_pool_1_timeout_call_count) {
        sxe_pool_set_indexed_element_state(array, array_index, TEST_STATE_USED,   TEST_STATE_FREE);
    }

    SXER80("return");
}
Exemplo n.º 10
0
static SXE_THREAD_RETURN SXE_STDCALL
test_thread_main(void * lock)
{
    SXEE81("test_thread_main(lock=%p)", lock);

    SXEA10(lock                     == &ping,                     "Ping lock not passed to the thread");
    SXEA10(sxe_spinlock_take(&pong) == SXE_SPINLOCK_STATUS_TAKEN, "Pong lock not taken by thread");
    SXEA10(sxe_spinlock_take(&ping) == SXE_SPINLOCK_STATUS_TAKEN, "Ping lock not taken by thread");
    SXEL10("thread: about to pong the main thread");
    sxe_spinlock_give(&pong);

    for (;;) {
        sleep(1);
    }

    SXER80("return NULL");
    return (SXE_THREAD_RETURN)0;
}
Exemplo n.º 11
0
void
sxe_ring_buffer_add(void * base, const char * buf, unsigned len)
{
    unsigned available_space;

    SXEE82("sxe_ring_buffer_add(buf=%p,len=%u)", buf, len);
    SXEL92("Current: %p, Itteration: %u", SXE_RING_BUFFER_CURRENT, SXE_RING_BUFFER_ITERATION);

    SXEA10(len <= SXE_RING_BUFFER_SIZE, "The item we're will fit in the whole array");

    available_space = (SXE_RING_BUFFER_END - SXE_RING_BUFFER_CURRENT + 1);
    SXEL91("There is %u space between the current pointer and the end of the array", available_space);

    if (available_space >= len) { // Can we fit it on the end of the array?
        SXEL92("Adding %u bytes at %p", len, SXE_RING_BUFFER_CURRENT);
        memcpy(SXE_RING_BUFFER_CURRENT, buf, len);

        SXE_RING_BUFFER_CURRENT = SXE_RING_BUFFER_CURRENT + len;
        if (SXE_RING_BUFFER_CURRENT == (SXE_RING_BUFFER_END + 1)) {
            SXEL90("Wrote to the last byte in the array, wrapping pointer");
            SXE_RING_BUFFER_ITERATION++;
            SXE_RING_BUFFER_CURRENT = SXE_RING_BUFFER_ARRAY_BASE;
            SXE_RING_BUFFER_WRITEN_END = SXE_RING_BUFFER_END;
        }
        else {
            if (SXE_RING_BUFFER_WRITEN_END < SXE_RING_BUFFER_CURRENT) {
                SXE_RING_BUFFER_WRITEN_END = SXE_RING_BUFFER_CURRENT - 1;
            }
        }
    }
    else { // else we have to wrap around the ring
        memcpy(SXE_RING_BUFFER_CURRENT, buf, available_space);
        SXE_RING_BUFFER_WRITEN_END = SXE_RING_BUFFER_END;
        SXE_RING_BUFFER_ITERATION++;
        SXE_RING_BUFFER_CURRENT = SXE_RING_BUFFER_ARRAY_BASE;
        memcpy(SXE_RING_BUFFER_CURRENT, buf + available_space, (len - available_space));
        SXE_RING_BUFFER_CURRENT = SXE_RING_BUFFER_CURRENT + (len - available_space);
    }

    SXEL93("Current: %p, Writen End %p, Itteration: %u", SXE_RING_BUFFER_CURRENT, SXE_RING_BUFFER_WRITEN_END, SXE_RING_BUFFER_ITERATION);
    SXER80("return");
}
Exemplo n.º 12
0
static void
sxe_sync_ev_read(EV_P_ ev_io * io, int revents)
{
    SXE_SYNC_EV   * handle;

    SXEE82("sxe_sync_ev_read(io=%p,revents=%d)", io, revents);
#if EV_MULTIPLICITY
    SXE_UNUSED_ARGUMENT(loop);
#endif
    SXE_UNUSED_ARGUMENT(io);
    SXE_UNUSED_ARGUMENT(revents);

    while(recvfrom(sxe_sync_ev_sock, &handle, sizeof(handle), 0, NULL, NULL) == sizeof(handle)) {
        (*sxe_sync_generic_event)(handle, handle->user_data);
    }

    SXEA11(sxe_socket_get_last_error() == SXE_SOCKET_ERROR(EWOULDBLOCK), "Unexpected error receiving from sync socket: %s",
           sxe_socket_get_last_error_as_str());
    SXER80("return");
}
Exemplo n.º 13
0
/**
 * Construct a pool state walker (AKA iterator)
 *
 * @param walker Pointer to the walker
 * @param array  Pointer to the pool array
 * @param state  State to walk
 *
 * @exception If the pool is both locked and timed, it cannot be walked safely
 */
void
sxe_pool_walker_construct(SXE_POOL_WALKER * walker, void * array, unsigned state)
{
    SXE_POOL_IMPL * pool = SXE_POOL_ARRAY_TO_IMPL(array);

    SXEE83("sxe_pool_walker_construct(walker=%p,pool=%s,state=%s)", walker, pool->name, (*pool->state_to_string)(state));
    SXEA11(!((pool->options & SXE_POOL_OPTION_LOCKED) && (pool->options & SXE_POOL_OPTION_TIMED)),
           "sxe_pool_walker_construct: Can't walk thread safe timed pool %s safely", pool->name);
    sxe_list_walker_construct(&walker->list_walker, &SXE_POOL_QUEUE(pool)[state]);
    walker->pool  = pool;
    walker->state = state;

    if (pool->options & SXE_POOL_OPTION_TIMED) {
        walker->last.time  = 0.0;
    }
    else {
        walker->last.count = 0;
    }

    SXER80("return");
}
Exemplo n.º 14
0
void
sxe_ring_buffer_wrote_block(void * base, SXE_RING_BUFFER_CONTEXT * context, unsigned len)
{
    SXEE81("sxe_ring_buffer_wrote_block(len=%u)", len);
    SXEA10(context->writable_block == SXE_RING_BUFFER_CURRENT, "The current pointer is still where it was when you asked for it");
    SXEA10(len <= (unsigned)(SXE_RING_BUFFER_END - SXE_RING_BUFFER_CURRENT + 1), "Did not overwrite end of buffer ring");

    SXE_RING_BUFFER_CURRENT = SXE_RING_BUFFER_CURRENT + len;

    if (SXE_RING_BUFFER_CURRENT == (SXE_RING_BUFFER_END + 1)) {
        SXEL90("Wrote to the last byte in the array, wrapping pointer");
        SXE_RING_BUFFER_ITERATION++;
        SXE_RING_BUFFER_CURRENT = SXE_RING_BUFFER_ARRAY_BASE;
        SXE_RING_BUFFER_WRITEN_END = SXE_RING_BUFFER_END;
    }
    else {
        if (SXE_RING_BUFFER_WRITEN_END < SXE_RING_BUFFER_CURRENT) {
            SXE_RING_BUFFER_WRITEN_END = SXE_RING_BUFFER_CURRENT - 1;
        }
    }

    SXEL93("Current: %p, Writen End %p, Itteration: %u", SXE_RING_BUFFER_CURRENT, SXE_RING_BUFFER_WRITEN_END, SXE_RING_BUFFER_ITERATION);
    SXER80("return");
}
Exemplo n.º 15
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");
}
Exemplo n.º 16
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");
}