in src/couch_quickjs/quickjs/quickjs-libc.c [3543:3624]
static JSValue js_worker_ctor(JSContext *ctx, JSValueConst new_target,
int argc, JSValueConst *argv)
{
JSRuntime *rt = JS_GetRuntime(ctx);
WorkerFuncArgs *args = NULL;
pthread_t tid;
pthread_attr_t attr;
JSValue obj = JS_UNDEFINED;
int ret;
const char *filename = NULL, *basename;
JSAtom basename_atom;
/* XXX: in order to avoid problems with resource liberation, we
don't support creating workers inside workers */
if (!is_main_thread(rt))
return JS_ThrowTypeError(ctx, "cannot create a worker inside a worker");
/* base name, assuming the calling function is a normal JS
function */
basename_atom = JS_GetScriptOrModuleName(ctx, 1);
if (basename_atom == JS_ATOM_NULL) {
return JS_ThrowTypeError(ctx, "could not determine calling script or module name");
}
basename = JS_AtomToCString(ctx, basename_atom);
JS_FreeAtom(ctx, basename_atom);
if (!basename)
goto fail;
/* module name */
filename = JS_ToCString(ctx, argv[0]);
if (!filename)
goto fail;
args = malloc(sizeof(*args));
if (!args)
goto oom_fail;
memset(args, 0, sizeof(*args));
args->filename = strdup(filename);
args->basename = strdup(basename);
/* ports */
args->recv_pipe = js_new_message_pipe();
if (!args->recv_pipe)
goto oom_fail;
args->send_pipe = js_new_message_pipe();
if (!args->send_pipe)
goto oom_fail;
args->strip_flags = JS_GetStripInfo(rt);
obj = js_worker_ctor_internal(ctx, new_target,
args->send_pipe, args->recv_pipe);
if (JS_IsException(obj))
goto fail;
pthread_attr_init(&attr);
/* no join at the end */
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
ret = pthread_create(&tid, &attr, worker_func, args);
pthread_attr_destroy(&attr);
if (ret != 0) {
JS_ThrowTypeError(ctx, "could not create worker");
goto fail;
}
JS_FreeCString(ctx, basename);
JS_FreeCString(ctx, filename);
return obj;
oom_fail:
JS_ThrowOutOfMemory(ctx);
fail:
JS_FreeCString(ctx, basename);
JS_FreeCString(ctx, filename);
if (args) {
free(args->filename);
free(args->basename);
js_free_message_pipe(args->recv_pipe);
js_free_message_pipe(args->send_pipe);
free(args);
}
JS_FreeValue(ctx, obj);
return JS_EXCEPTION;
}