Exemplo n.º 1
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;
}
Exemplo n.º 2
0
/*
 * Arguments: filename (string) | function_dump (string),
 *	[arguments (string | number | boolean | lightuserdata) ...]
 * Returns: [thread_ludata]
 */
static int
thread_runvm (lua_State *L)
{
    const char *path = luaL_checkstring(L, 1);
    lua_State *NL = NULL;
    struct sys_vmthread *vmtd = (struct sys_vmthread *) sys_get_thread();
#ifndef _WIN32
    pthread_attr_t attr;
#else
    HANDLE hThr;
#endif
    int res = 0;

    if (!vmtd) luaL_argerror(L, 0, "Threading not initialized");

    NL = luaL_newstate();
    if (!NL) goto err;

    thread_openlibs(NL);

    if (path[0] == LUA_SIGNATURE[0]
     ? luaL_loadbuffer(NL, path, lua_rawlen(L, 1), "thread")
     : luaL_loadfile(NL, path)) {
	lua_pushstring(L, lua_tostring(NL, -1));  /* error message */
	lua_close(NL);
	lua_error(L);
    }

    /* Arguments */
    lua_pushlightuserdata(NL, vmtd);  /* master */
    {
	int i, top = lua_gettop(L);

	for (i = 2; i <= top; ++i) {
	    switch (lua_type(L, i)) {
	    case LUA_TSTRING:
		lua_pushstring(NL, lua_tostring(L, i));
		break;
	    case LUA_TNUMBER:
		lua_pushnumber(NL, lua_tonumber(L, i));
		break;
	    case LUA_TBOOLEAN:
		lua_pushboolean(NL, lua_toboolean(L, i));
		break;
	    case LUA_TLIGHTUSERDATA:
	    case LUA_TUSERDATA:
		lua_pushlightuserdata(NL, lua_touserdata(L, i));
		break;
	    default:
		luaL_argerror(L, i, "primitive type expected");
	    }
	}
    }

    if (vmthread_new(NL, &vmtd))
	goto err_clean;

#ifndef _WIN32
    res = pthread_attr_init(&attr);
    if (res) goto err_clean;
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

    res = pthread_create(&vmtd->td.tid, &attr,
     (thread_func_t) thread_startvm, vmtd);
    pthread_attr_destroy(&attr);
    if (!res) {
#else
    hThr = (HANDLE) _beginthreadex(NULL, 0,
     (thread_func_t) thread_startvm, vmtd, 0, &vmtd->td.tid);
    if (hThr) {
	CloseHandle(hThr);
#endif
	lua_pushlightuserdata(L, vmtd);
	return 1;
    }
 err_clean:
    lua_close(NL);
 err:
    return sys_seterror(L, res);
}

/*
 * Arguments: thread_ludata
 */
static int
thread_interrupt (lua_State *L)
{
    struct sys_thread *td = lua_touserdata(L, 1);

    td->interrupted = 1;
#ifndef _WIN32
    pthread_kill(td->tid, SYS_SIGINTR);
#endif
    return 0;
}

static int
thread_yield (lua_State *L)
{
    (void) L;

    sys_vm_leave();
#ifndef _WIN32
    sched_yield();
#else
    Sleep(0);
#endif
    sys_vm_enter();
    return 0;
}