Beispiel #1
0
static int
vmthread_new (lua_State *L, struct sys_vmthread **vmtdp)
{
    struct sys_vmthread *vmtd;

    lua_pushthread(L);

    vmtd = lua_newuserdata(L, sizeof(struct sys_vmthread));
    memset(vmtd, 0, sizeof(struct sys_vmthread));
    vmtd->td.L = L;
    vmtd->td.tid = thread_getid();
    vmtd->td.vmtd = vmtd;

    /* vm-mutex destructor */
    lua_pushlightuserdata(L, &g_TLSIndex);
    lua_rawget(L, LUA_REGISTRYINDEX);
    lua_pushvalue(L, -1);
    lua_setmetatable(L, -3);
    lua_pushlightuserdata(L, vmtd);
    lua_pushvalue(L, -3);  /* thread_udata */
    lua_rawset(L, -3);
    lua_pop(L, 1);

    if (thread_event_new(&vmtd->bufev))
	return -1;

#ifndef _WIN32
    vmtd->td.mutex = &vmtd->vmmutex;
    if (thread_critsect_new(vmtd->td.mutex)) {
	thread_event_del(&vmtd->bufev);
	return -1;
    }
#else
    if (thread_critsect_new(&vmtd->bufcs)) {
	thread_event_del(&vmtd->bufev);
	return -1;
    }

    vmtd->td.mutex = CreateMutex(NULL, FALSE, NULL);
    if (!vmtd->td.mutex) {
	thread_event_del(&vmtd->bufev);
	thread_critsect_del(&vmtd->bufcs);
	return -1;
    }
#endif

    *vmtdp = vmtd;
    return 0;
}
Beispiel #2
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);
}
Beispiel #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;
}
Beispiel #4
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);
}