Ejemplo n.º 1
0
void ph_dns_channel_query_raw(
    ph_dns_channel_t *chan,
    const char *name,
    int dnsclass,
    int type,
    ph_dns_channel_raw_query_func func,
    void *arg)
{
  struct ph_dns_query *q;

  chan = fixup_chan(chan);

  q = ph_mem_alloc(mt.query);
  if (!q) {
    func(arg, ARES_ENOMEM, 0, NULL, 0);
    return;
  }

  q->chan = chan;
  q->arg = arg;
  q->qtype = PH_DNS_QUERY_NONE;
  q->func.raw = func;

  pthread_mutex_lock(&chan->chanlock);
  ares_search(chan->chan, name, dnsclass, type, result_cb, q);
  pthread_mutex_unlock(&chan->chanlock);
}
Ejemplo n.º 2
0
ph_hook_point_t *ph_hook_point_get(ph_string_t *name, bool create)
{
  ph_hook_point_t *hp = 0;

  ck_rwlock_read_lock(&rwlock);
  {
    ph_ht_lookup(&hook_hash, &name, &hp, false);
  }
  ck_rwlock_read_unlock(&rwlock);

  if (hp || !create) {
    return hp;
  }

  ck_rwlock_write_lock(&rwlock);
  {
    // Look again: someone may have populated while we were unlocked
    ph_ht_lookup(&hook_hash, &name, &hp, false);
    if (!hp) {
      hp = ph_mem_alloc(mt.hookpoint);
      if (hp) {
        if (ph_ht_set(&hook_hash, &name, &hp) != PH_OK) {
          ph_mem_free(mt.hookpoint, hp);
          hp = NULL;
        }
      }
    }
  }
  ck_rwlock_write_unlock(&rwlock);

  return hp;
}
Ejemplo n.º 3
0
ph_variant_t *ph_var_int(int64_t ival)
{
  ph_variant_t *var;

  var = ph_mem_alloc(mt.var);
  if (!var) {
    return NULL;
  }

  var->ref = 1;
  var->type = PH_VAR_INTEGER;
  var->u.ival = ival;

  return var;
}
Ejemplo n.º 4
0
ph_variant_t *ph_var_double(double dval)
{
  ph_variant_t *var;

  var = ph_mem_alloc(mt.var);
  if (!var) {
    return NULL;
  }

  var->ref = 1;
  var->type = PH_VAR_REAL;
  var->u.dval = dval;

  return var;
}
Ejemplo n.º 5
0
// Called each time the listener has accepted a client connection
static void acceptor(ph_listener_t *lstn, ph_sock_t *sock)
{
  ph_unused_parameter(lstn);

  // Allocate an echo_state instance and stash it.
  // This is set to be zero'd on creation and will show up as the
  // `arg` parameter in `echo_processor`
  sock->job.data = ph_mem_alloc(mt_state);

  // Tell it how to dispatch
  sock->callback = echo_processor;

  ph_log(PH_LOG_ERR, "accepted `P{sockaddr:%p}", (void*)&sock->peername);

  ph_sock_enable(sock, true);
}
Ejemplo n.º 6
0
ph_string_t *ph_string_make_slice(ph_string_t *str,
    uint32_t start, uint32_t len)
{
  ph_string_t *slice;

  if (start == 0 && len == str->len) {
    ph_string_addref(str);
    return str;
  }

  slice = ph_mem_alloc(mt_string);
  if (!slice) {
    return NULL;
  }

  ph_string_init_slice(slice, str, start, len);
  return slice;
}
Ejemplo n.º 7
0
void ph_dns_channel_query(
    ph_dns_channel_t *chan,
    const char *name,
    int query_type,
    ph_dns_channel_query_func func,
    void *arg)
{
  struct ph_dns_query *q;
  int dnsclass = ns_c_in, type;

  chan = fixup_chan(chan);

  q = ph_mem_alloc(mt.query);
  if (!q) {
    func(arg, ARES_ENOMEM, 0, NULL, 0, NULL);
    return;
  }

  q->chan = chan;
  q->arg = arg;
  q->qtype = query_type;
  q->func.func = func;

  switch (query_type) {
    case PH_DNS_QUERY_A:
      type = ns_t_a;
      break;
    case PH_DNS_QUERY_AAAA:
      type = ns_t_aaaa;
      break;
    case PH_DNS_QUERY_SRV:
      type = ns_t_srv;
      break;
    case PH_DNS_QUERY_MX:
      type = ns_t_mx;
      break;
    default:
      ph_panic("invalid query type %d", query_type);
  }

  pthread_mutex_lock(&chan->chanlock);
  ares_search(chan->chan, name, dnsclass, type, result_cb, q);
  pthread_mutex_unlock(&chan->chanlock);
}
Ejemplo n.º 8
0
ph_variant_t *ph_var_string_claim(ph_string_t *str)
{
  ph_variant_t *var;

  if (str == NULL) {
    return ph_var_null();
  }

  var = ph_mem_alloc(mt.var);
  if (!var) {
    return NULL;
  }

  var->ref = 1;
  var->type = PH_VAR_STRING;
  var->u.sval = str;

  return var;
}
Ejemplo n.º 9
0
ph_string_t *ph_string_make_claim(ph_memtype_t mt,
    char *buf, uint32_t len, uint32_t size)
{
  ph_string_t *str;

  str = ph_mem_alloc(mt_string);
  if (!str) {
    return NULL;
  }

  str->ref = 1;
  str->buf = buf;
  str->len = len;
  str->alloc = size;
  str->slice = 0;
  str->mt = mt;
  str->onstack = false;

  return str;
}
Ejemplo n.º 10
0
ph_variant_t *ph_var_object(uint32_t nelems)
{
  ph_variant_t *var;
  ph_result_t res;

  var = ph_mem_alloc(mt.var);
  if (!var) {
    return NULL;
  }

  var->ref = 1;
  var->type = PH_VAR_OBJECT;

  res = ph_ht_init(&var->u.oval, nelems, &ph_ht_string_key_def, &var_val_def);
  if (res != PH_OK) {
    ph_mem_free(mt.var, var);
    return 0;
  }

  return var;
}
Ejemplo n.º 11
0
ph_variant_t *ph_var_array(uint32_t nelems)
{
  ph_variant_t *var;

  var = ph_mem_alloc(mt.var);
  if (!var) {
    return NULL;
  }

  var->ref = 1;
  var->type = PH_VAR_ARRAY;
  var->u.aval.len = 0;
  var->u.aval.alloc = nelems;
  var->u.aval.arr = ph_mem_alloc_size(mt.arr, nelems * sizeof(ph_variant_t*));

  if (!var->u.aval.arr) {
    ph_mem_free(mt.var, var);
    return NULL;
  }

  return var;
}
Ejemplo n.º 12
0
/* called when ares creates a new socket */
static int sock_create_cb(ares_socket_t socket_fd, int type, void *data)
{
  ph_dns_channel_t *chan = data;
  ph_job_t *job = ph_mem_alloc(mt.job);

  ph_unused_parameter(type);

  if (!job) {
    return -1;
  }

  ph_job_init(job);
  job->callback = process_ares;
  job->data = chan;
  job->fd = socket_fd;

  if (ph_ht_set(&chan->sock_map, &socket_fd, &job) != PH_OK) {
    ph_mem_free(mt.job, job);
    return -1;
  }

  return 0;
}
Ejemplo n.º 13
0
static ph_dns_channel_t *create_chan(void)
{
  ph_dns_channel_t *chan;
  struct ares_options opts;
  int res;
  pthread_mutexattr_t attr;

  chan = ph_mem_alloc(mt.chan);
  if (!chan) {
    return NULL;
  }

  pthread_mutexattr_init(&attr);
  pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
  pthread_mutex_init(&chan->chanlock, &attr);
  pthread_mutexattr_destroy(&attr);

  if (ph_ht_init(&chan->sock_map, 4, &sock_key, &ph_ht_ptr_val_def) != PH_OK) {
    ph_panic("failed to init sock map");
  }

  memset(&opts, 0, sizeof(opts));
  opts.sock_state_cb_data = chan;
  opts.sock_state_cb = sock_state_cb;
  opts.flags = ARES_FLAG_STAYOPEN;

  res = ares_init_options(&chan->chan, &opts,
      ARES_OPT_SOCK_STATE_CB|ARES_OPT_FLAGS);

  if (res != ARES_SUCCESS) {
    ph_panic("failed to ares_init_options: %s", ares_strerror(res));
  }

  ares_set_socket_callback(chan->chan, sock_create_cb, chan);

  return chan;
}
Ejemplo n.º 14
0
static ph_result_t do_unregister(ph_hook_point_t *hp, ph_hook_func func,
    void *closure)
{
  ph_hook_point_head_t *old_head, *new_head;
  ph_result_t res = PH_ERR;
  uint16_t off = 0;
  bool found = false;
  struct ph_hook_item_free *unreg = 0;

  ck_rwlock_write_lock(&rwlock);
  {
    old_head = hp->head;

    if (!old_head) {
      goto done;
    }

    for (off = 0; off < old_head->nitems; off++) {
      if (old_head->items[off].func == func &&
          old_head->items[off].closure == closure) {
        found = true;
        break;
      }
    }

    if (!found) {
      goto done;
    }

    new_head = ph_mem_alloc_size(mt.head,
        sizeof(*new_head) + (sizeof(ph_hook_item_t) * (old_head->nitems-1)));

    if (!new_head) {
      goto done;
    }

    if (old_head->items[off].unreg) {
      unreg = ph_mem_alloc(mt.unreg);
      if (!unreg) {
        ph_mem_free(mt.head, new_head);
        goto done;
      }

      unreg->closure = old_head->items[off].closure;
      unreg->func = old_head->items[off].func;
      unreg->unreg = old_head->items[off].unreg;
    }

    new_head->nitems = old_head->nitems - 1;

    // Copy before the item
    if (off) {
      memcpy(new_head->items, old_head->items, off * sizeof(ph_hook_item_t));
    }
    // Copy after the item
    if (off + 1 <= old_head->nitems) {
      memcpy(new_head->items + off, old_head->items + off + 1,
          (old_head->nitems - (off+1)) * sizeof(ph_hook_item_t));
    }

    // Don't need to re-sort, since we simply removed that item

    hp->head = new_head;
    ph_thread_epoch_defer(&old_head->entry, free_head);

    // Arrange to unregister
    if (unreg) {
      ph_thread_epoch_defer(&unreg->entry, call_unreg);
    }

    res = PH_OK;
  }
done:
  ck_rwlock_write_unlock(&rwlock);

  return res;
}