Ejemplo n.º 1
0
/*
 * Arguments: [buffer_max_size (number), buffer_min_size (number)]
 * Returns: [pipe_udata]
 */
static int
pipe_new (lua_State *L)
{
    const unsigned int max_size = (unsigned int)
     luaL_optinteger(L, 1, PIPE_BUF_MAXSIZE);
    const unsigned int min_size = (unsigned int)
     luaL_optinteger(L, 2, PIPE_BUF_MINSIZE);
    struct pipe_ref *pr;
    struct pipe *pp;

    if (min_size > max_size
     || min_size < PIPE_BUF_MINSIZE
     || max_size > PIPE_BUF_MAXSIZE
     /* (max_size / min_size) should be power of 2 */
     || ((max_size / min_size) & (max_size / min_size - 1)) != 0)
	luaL_argerror(L, 1, "invalid size");

    pr = lua_newuserdata(L, sizeof(struct pipe_ref));
    pp = calloc(sizeof(struct pipe), 1);
    if (!pp) goto err;

    pr->pipe = pp;
    pr->put_timeout = TIMEOUT_INFINITE;

    luaL_getmetatable(L, PIPE_TYPENAME);
    lua_setmetatable(L, -2);

    if (thread_critsect_new(&pp->cs)
     || thread_cond_new(&pp->put_cond)
     || thread_cond_new(&pp->get_cond))
	goto err;

    /* allocate initial buffer */
    {
	struct pipe_buf *pb = malloc(min_size);

	if (!pb) goto err;

	memset(pb, 0, sizeof(struct pipe_buf));
	pb->len = min_size - PIPE_BUF_EXTRASIZE;
	pb->next_buf = pb;

	pp->rbuf = pp->wbuf = pb;
	pp->buf_size = min_size;
    }
    pp->buf_max_size = max_size;

    return 1;
 err:
    return sys_seterror(L, 0);
}
Ejemplo n.º 2
0
static int
thread_channel (lua_State *L)
{
    struct channel *chan = lua_newuserdata(L, sizeof(struct channel));
    memset(chan, 0, sizeof(struct channel));
    chan->max = (unsigned int) -1;

    if (!thread_cond_new(&chan->put) && !thread_cond_new(&chan->get)) {
        thread_critsect_new(&chan->mutex);
	luaL_getmetatable(L, CHANNEL_TYPENAME);
	lua_setmetatable(L, -2);

	lua_newtable(L);  /* data storage */
	lua_setfenv(L, -2);
	return 1;
    }
    return sys_seterror(L, 0);
}
Ejemplo n.º 3
0
static struct sys_thread *
thread_newvm (lua_State *L, struct sys_thread *reftd,
              unsigned int loadlibs)
{
  struct sys_vmthread *vmtd;
  lua_State *NL;

  if (L) {
    NL = lua_newthread(L);
    if (!NL) return NULL;
  } else {
    NL = luaL_newstate();
    if (!NL) return NULL;

    L = NL;
    thread_openlibs(L, loadlibs);
    thread_createmeta(L);

    lua_pushthread(L);
  }

  vmtd = lua_newuserdata(L, sizeof(struct sys_vmthread));
  memset(vmtd, 0, sizeof(struct sys_vmthread));
  vmtd->td.L = NL;
  vmtd->td.vmtd = vmtd;
  luaL_getmetatable(L, THREAD_TYPENAME);
  lua_setmetatable(L, -2);

  if (reftd) {
    struct sys_vmthread *vmref = reftd->vmtd;

    vmtd->td.reftd = reftd;
    vmtd->cpu = vmref->cpu;
    vmtd->stack_size = vmref->stack_size;
  }

  if (thread_critsect_new(&vmtd->vmcs))
    return NULL;
  vmtd->td.vmcsp = &vmtd->vmcs;

  if (thread_cond_new(&vmtd->td.cond))
    return NULL;

  thread_settable(L, &vmtd->td);  /* save thread to avoid GC */
  return &vmtd->td;
}
Ejemplo n.º 4
0
/*
 * Returns: [thread_udata]
 */
struct sys_thread *
sys_thread_new (lua_State *L, struct sys_thread *vmtd,
                struct sys_thread *vmtd2, const int push_udata)
{
  struct sys_vmthread *vmref = vmtd->vmtd;
  struct sys_thread *td;
  lua_State *NL;

  if (vmtd2) {
    NL = vmref->td.L;
    lua_pushnil(L);
  } else {
    NL = lua_newthread(L);
    if (!NL) return NULL;
  }

  td = lua_newuserdata(L, sizeof(struct sys_thread));
  memset(td, 0, sizeof(struct sys_thread));
  td->vmcsp = vmtd->vmcsp;
  td->L = NL;
  td->vmtd = vmref;
  luaL_getmetatable(L, THREAD_TYPENAME);
  lua_setmetatable(L, -2);

  td->reftd = vmtd2 ? vmtd2 : &vmref->td;
  vmref->nref++;

  if (thread_cond_new(&td->cond))
    return NULL;

  if (push_udata) {
    lua_pushvalue(L, -1);
    lua_insert(L, -3);  /* thread_udata */
  }

  thread_settable(L, td);  /* save thread to avoid GC */
  return td;
}