Esempio n. 1
0
int32_t connector_start(connector_t* con)
{
    if (!con || con->h.fd < 0) return -1;
    sock_set_nonblock(con->h.fd);
    sock_set_nodelay(con->h.fd);
    return reactor_register(con->r, &con->h, EVENT_IN);
}
Esempio n. 2
0
eager_reader_t *eager_reader_new(
    int fd_to_read,
    const allocator_t *allocator,
    size_t buffer_size,
    size_t max_buffer_count,
    const char *thread_name) {

  assert(fd_to_read != INVALID_FD);
  assert(allocator != NULL);
  assert(buffer_size > 0);
  assert(max_buffer_count > 0);
  assert(thread_name != NULL && *thread_name != '\0');

  eager_reader_t *ret = osi_calloc(sizeof(eager_reader_t));
  if (!ret) {
    LOG_ERROR(LOG_TAG, "%s unable to allocate memory for new eager_reader.", __func__);
    goto error;
  }

  ret->allocator = allocator;
  ret->inbound_fd = fd_to_read;

  ret->bytes_available_fd = eventfd(0, 0);
  if (ret->bytes_available_fd == INVALID_FD) {
    LOG_ERROR(LOG_TAG, "%s unable to create output reading semaphore.", __func__);
    goto error;
  }

  ret->buffer_size = buffer_size;

  ret->buffers = fixed_queue_new(max_buffer_count);
  if (!ret->buffers) {
    LOG_ERROR(LOG_TAG, "%s unable to create buffers queue.", __func__);
    goto error;
  }

  ret->inbound_read_thread = thread_new(thread_name);
  if (!ret->inbound_read_thread) {
    LOG_ERROR(LOG_TAG, "%s unable to make reading thread.", __func__);
    goto error;
  }

  ret->inbound_read_object = reactor_register(
    thread_get_reactor(ret->inbound_read_thread),
    fd_to_read,
    ret,
    inbound_data_waiting,
    NULL
  );

  return ret;

error:;
  eager_reader_free(ret);
  return NULL;
}
Esempio n. 3
0
void eager_reader_register(eager_reader_t *reader, reactor_t *reactor, eager_reader_cb read_cb, void *context) {
  assert(reader != NULL);
  assert(reactor != NULL);
  assert(read_cb != NULL);

  // Make sure the reader isn't currently registered.
  eager_reader_unregister(reader);

  reader->outbound_read_ready = read_cb;
  reader->outbound_context = context;
  reader->outbound_registration = reactor_register(reactor, reader->bytes_available_fd, reader, internal_outbound_read_ready, NULL);
}
Esempio n. 4
0
void socket_register(socket_t *socket, reactor_t *reactor, void *context, socket_cb read_cb, socket_cb write_cb) {
  assert(socket != NULL);

  // Make sure the socket isn't currently registered.
  socket_unregister(socket);

  socket->read_ready = read_cb;
  socket->write_ready = write_cb;
  socket->context = context;

  void (*read_fn)(void *) = (read_cb != NULL) ? internal_read_ready : NULL;
  void (*write_fn)(void *) = (write_cb != NULL) ? internal_write_ready : NULL;

  socket->reactor_object = reactor_register(reactor, socket->fd, socket, read_fn, write_fn);
}
static void *run_thread(void *start_arg) {
  assert(start_arg != NULL);

  struct start_arg *start = start_arg;
  thread_t *thread = start->thread;

  assert(thread != NULL);

  if (prctl(PR_SET_NAME, (unsigned long)thread->name) == -1) {
    ALOGE("%s unable to set thread name: %s", __func__, strerror(errno));
    start->error = errno;
    semaphore_post(start->start_sem);
    return NULL;
  }
  thread->tid = gettid();

  semaphore_post(start->start_sem);

  reactor_object_t work_queue_object;
  work_queue_object.context = thread->work_queue;
  work_queue_object.fd = fixed_queue_get_dequeue_fd(thread->work_queue);
  work_queue_object.interest = REACTOR_INTEREST_READ;
  work_queue_object.read_ready = work_queue_read_cb;

  reactor_register(thread->reactor, &work_queue_object);
  reactor_start(thread->reactor);

  // Make sure we dispatch all queued work items before exiting the thread.
  // This allows a caller to safely tear down by enqueuing a teardown
  // work item and then joining the thread.
  size_t count = 0;
  work_item_t *item = fixed_queue_try_dequeue(thread->work_queue);
  while (item && count <= WORK_QUEUE_CAPACITY) {
    item->func(item->context);
    free(item);
    item = fixed_queue_try_dequeue(thread->work_queue);
    ++count;
  }

  if (count > WORK_QUEUE_CAPACITY)
    ALOGD("%s growing event queue on shutdown.", __func__);

  return NULL;
}
Esempio n. 6
0
static void *run_thread(void *start_arg) {
  assert(start_arg != NULL);

  struct start_arg *start = start_arg;
  thread_t *thread = start->thread;

  assert(thread != NULL);

  if (prctl(PR_SET_NAME, (unsigned long)thread->name) == -1) {
    LOG_ERROR("%s unable to set thread name: %s", __func__, strerror(errno));
    start->error = errno;
    semaphore_post(start->start_sem);
    return NULL;
  }
  thread->tid = gettid();

  semaphore_post(start->start_sem);

  int fd = fixed_queue_get_dequeue_fd(thread->work_queue);
  void *context = thread->work_queue;

  reactor_object_t *work_queue_object = reactor_register(thread->reactor, fd, context, work_queue_read_cb, NULL);
  reactor_start(thread->reactor);
  reactor_unregister(work_queue_object);

  // Make sure we dispatch all queued work items before exiting the thread.
  // This allows a caller to safely tear down by enqueuing a teardown
  // work item and then joining the thread.
  size_t count = 0;
  work_item_t *item = fixed_queue_try_dequeue(thread->work_queue);
  while (item && count <= fixed_queue_capacity(thread->work_queue)) {
    item->func(item->context);
    osi_free(item);
    item = fixed_queue_try_dequeue(thread->work_queue);
    ++count;
  }

  if (count > fixed_queue_capacity(thread->work_queue))
    LOG_DEBUG("%s growing event queue on shutdown.", __func__);

  return NULL;
}