예제 #1
0
파일: log.c 프로젝트: atrmat/libphenom
void ph_logv(uint8_t level, const char *fmt, va_list ap)
{
  struct timeval now = ph_time_now();
  ph_thread_t *me;
  int len;
  va_list copy;
  char *buf;
  PH_STRING_DECLARE_STACK(mystr, 1024);
  void *args[] = { &level, &mystr };
  static ph_hook_point_t *hook = NULL;
  char tname[32];

  if (level > log_level) {
    return;
  }

  len = strlen(fmt);
  if (len == 0) {
    return;
  }

  me = ph_thread_self();
  get_tname(me, tname, sizeof(tname));
  va_copy(copy, ap);
  ph_string_printf(&mystr,
      "%" PRIi64 ".%03d %s: %s `Pv%s%p%s",
      (int64_t)now.tv_sec, (int)(now.tv_usec / 1000),
      log_labels[level], tname,
      fmt, ph_vaptr(copy),
      fmt[len-1] == '\n' ? "" : "\n");
  va_end(copy);

  if (ph_unlikely(hook == NULL)) {
    hook = ph_hook_point_get_cstr(PH_LOG_HOOK_NAME, true);
  }
  ph_hook_invoke_inner(hook, sizeof(args)/sizeof(args[0]), args);

  if (disable_stderr) {
    return;
  }

  pthread_mutex_lock(&log_lock);
  buf = mystr.buf;
  len = mystr.len;
  while (len) {
    int x = write(STDERR_FILENO, buf, len);
    if (x <= 0) {
      break;
    }
    buf += x;
    len -= x;
  }
  pthread_mutex_unlock(&log_lock);
}
예제 #2
0
파일: kqueue.c 프로젝트: DreamDuo/libphenom
ph_result_t ph_nbio_emitter_apply_io_mask(struct ph_nbio_emitter *emitter,
    ph_job_t *job, ph_iomask_t mask)
{
  struct ph_nbio_kq_set *set, local_set;
  int res;

  if (job->fd == -1) {
    return PH_OK;
  }

  if (mask == job->kmask) {
    return PH_OK;
  }

  if (emitter == ph_thread_self()->is_emitter) {
    set = &emitter->kqset;
  } else {
    init_kq_set(&local_set);
    set = &local_set;
  }

  if (mask & PH_IOMASK_READ) {
    add_kq_set(set, job->fd, EVFILT_READ, EV_ADD|EV_ONESHOT, 0, 0, job);
  }
  if (mask & PH_IOMASK_WRITE) {
    add_kq_set(set, job->fd, EVFILT_WRITE, EV_ADD|EV_ONESHOT, 0, 0, job);
  }
  if ((mask & (PH_IOMASK_READ|PH_IOMASK_WRITE)) == 0) {
    // Neither read nor write -> delete
    add_kq_set(set, job->fd, EVFILT_READ, EV_DELETE, 0, 0, job);
    add_kq_set(set, job->fd, EVFILT_WRITE, EV_DELETE, 0, 0, job);
  }

  job->kmask = mask;
  job->mask = mask;

  if (set == &local_set) {
    // Apply it immediately
    res = kevent(emitter->io_fd, set->events, set->used, NULL, 0, NULL);
    if (res != 0 && mask == 0 && errno == ENOENT) {
      // It's "OK" if we decided to delete it and it wasn't there
      res = 0;
    }
    if (res != 0) {
      ph_panic("kevent: setting mask to %02x on fd %d with %d slots -> `Pe%d",
          mask, job->fd, set->used, errno);
      return PH_ERR;
    }
  }
  return PH_OK;
}
예제 #3
0
파일: thread.c 프로젝트: 01BTC10/libphenom
void ph_thread_epoch_barrier(void)
{
  ph_thread_t *me = ph_thread_self();
  ck_epoch_barrier(&me->epoch_record);
}
예제 #4
0
파일: thread.c 프로젝트: 01BTC10/libphenom
bool ph_thread_epoch_poll(void)
{
  ph_thread_t *me = ph_thread_self();
  return ck_epoch_poll(&me->epoch_record);
}
예제 #5
0
파일: thread.c 프로젝트: 01BTC10/libphenom
void ph_thread_epoch_defer(ck_epoch_entry_t *entry, ck_epoch_cb_t *func)
{
  ph_thread_t *me = ph_thread_self();
  ck_epoch_call(&me->epoch_record, entry, func);
}
예제 #6
0
파일: thread.c 프로젝트: 01BTC10/libphenom
void ph_thread_epoch_end(void)
{
  ph_thread_t *me = ph_thread_self();
  ck_epoch_end(&me->epoch_record, NULL);
}
예제 #7
0
파일: thread.c 프로젝트: atrmat/libphenom
void ph_thread_epoch_end(void)
{
  ph_thread_t *me = ph_thread_self();
  ck_epoch_end(&misc_epoch, &me->epoch_record);
}