1
0
forked from Mirror/wren
Files
wren/src/module/scheduler.c

75 lines
2.0 KiB
C
Raw Normal View History

#include <stdlib.h>
#include <string.h>
#include "uv.h"
#include "scheduler.h"
#include "wren.h"
#include "vm.h"
// This method resumes a fiber that is suspended waiting on an asynchronous
// operation. The first resumes it with zero arguments, and the second passes
// one.
static WrenValue* resume;
static WrenValue* resumeWithArg;
static WrenValue* resumeError;
void schedulerCaptureMethods(WrenVM* vm)
{
resume = wrenGetMethod(vm, "scheduler", "Scheduler", "resume_(_)");
resumeWithArg = wrenGetMethod(vm, "scheduler", "Scheduler", "resume_(_,_)");
resumeError = wrenGetMethod(vm, "scheduler", "Scheduler", "resumeError_(_,_)");
}
static void callResume(WrenValue* resumeMethod, WrenValue* fiber,
const char* argTypes, ...)
{
va_list args;
va_start(args, argTypes);
WrenInterpretResult result = wrenCallVarArgs(getVM(), resumeMethod, NULL,
argTypes, args);
va_end(args);
wrenReleaseValue(getVM(), fiber);
// If a runtime error occurs in response to an async operation and nothing
// catches the error in the fiber, then exit the CLI.
if (result == WREN_RESULT_RUNTIME_ERROR)
{
uv_stop(getLoop());
setExitCode(70); // EX_SOFTWARE.
}
}
void schedulerResume(WrenValue* fiber)
{
callResume(resume, fiber, "v", fiber);
}
void schedulerResumeBytes(WrenValue* fiber, const char* bytes, size_t length)
{
callResume(resumeWithArg, fiber, "va", fiber, bytes, length);
}
void schedulerResumeDouble(WrenValue* fiber, double value)
{
callResume(resumeWithArg, fiber, "vd", fiber, value);
}
void schedulerResumeString(WrenValue* fiber, const char* text)
{
callResume(resumeWithArg, fiber, "vs", fiber, text);
}
void schedulerResumeError(WrenValue* fiber, const char* error)
{
callResume(resumeError, fiber, "vs", fiber, error);
}
void schedulerShutdown()
{
if (resume != NULL) wrenReleaseValue(getVM(), resume);
if (resumeWithArg != NULL) wrenReleaseValue(getVM(), resumeWithArg);
if (resumeError != NULL) wrenReleaseValue(getVM(), resumeError);
}