win32/win32.c: don't call FindChildSlot in MJIT
worker. It's very likely to be thread-unsafe and so it's better to avoid using in MJIT worker to prevent surprises by race condition. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65048 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
9d46f5490f
commit
26519ebaed
@ -119,7 +119,6 @@ static char *w32_getenv(const char *name, UINT cp);
|
|||||||
|
|
||||||
int rb_w32_reparse_symlink_p(const WCHAR *path);
|
int rb_w32_reparse_symlink_p(const WCHAR *path);
|
||||||
|
|
||||||
static struct ChildRecord *CreateChild(const WCHAR *, const WCHAR *, HANDLE, HANDLE, HANDLE, DWORD);
|
|
||||||
static int has_redirection(const char *, UINT);
|
static int has_redirection(const char *, UINT);
|
||||||
int rb_w32_wait_events(HANDLE *events, int num, DWORD timeout);
|
int rb_w32_wait_events(HANDLE *events, int num, DWORD timeout);
|
||||||
static int rb_w32_open_osfhandle(intptr_t osfhandle, int flags);
|
static int rb_w32_open_osfhandle(intptr_t osfhandle, int flags);
|
||||||
@ -1196,24 +1195,22 @@ child_result(struct ChildRecord *child, int mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* License: Ruby's */
|
/* License: Ruby's */
|
||||||
static struct ChildRecord *
|
static int
|
||||||
CreateChild(const WCHAR *cmd, const WCHAR *prog, HANDLE hInput, HANDLE hOutput, HANDLE hError, DWORD dwCreationFlags)
|
CreateChild(struct ChildRecord *child, const WCHAR *cmd, const WCHAR *prog, HANDLE hInput, HANDLE hOutput, HANDLE hError, DWORD dwCreationFlags)
|
||||||
{
|
{
|
||||||
BOOL fRet;
|
BOOL fRet;
|
||||||
STARTUPINFOW aStartupInfo;
|
STARTUPINFOW aStartupInfo;
|
||||||
PROCESS_INFORMATION aProcessInformation;
|
PROCESS_INFORMATION aProcessInformation;
|
||||||
SECURITY_ATTRIBUTES sa;
|
SECURITY_ATTRIBUTES sa;
|
||||||
struct ChildRecord *child;
|
|
||||||
|
|
||||||
if (!cmd && !prog) {
|
if (!cmd && !prog) {
|
||||||
errno = EFAULT;
|
errno = EFAULT;
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
child = FindFreeChildSlot();
|
|
||||||
if (!child) {
|
if (!child) {
|
||||||
errno = EAGAIN;
|
errno = EAGAIN;
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
|
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||||
@ -1248,7 +1245,7 @@ CreateChild(const WCHAR *cmd, const WCHAR *prog, HANDLE hInput, HANDLE hOutput,
|
|||||||
if (lstrlenW(cmd) > 32767) {
|
if (lstrlenW(cmd) > 32767) {
|
||||||
child->pid = 0; /* release the slot */
|
child->pid = 0; /* release the slot */
|
||||||
errno = E2BIG;
|
errno = E2BIG;
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
RUBY_CRITICAL {
|
RUBY_CRITICAL {
|
||||||
@ -1260,7 +1257,7 @@ CreateChild(const WCHAR *cmd, const WCHAR *prog, HANDLE hInput, HANDLE hOutput,
|
|||||||
|
|
||||||
if (!fRet) {
|
if (!fRet) {
|
||||||
child->pid = 0; /* release the slot */
|
child->pid = 0; /* release the slot */
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseHandle(aProcessInformation.hThread);
|
CloseHandle(aProcessInformation.hThread);
|
||||||
@ -1268,7 +1265,7 @@ CreateChild(const WCHAR *cmd, const WCHAR *prog, HANDLE hInput, HANDLE hOutput,
|
|||||||
child->hProcess = aProcessInformation.hProcess;
|
child->hProcess = aProcessInformation.hProcess;
|
||||||
child->pid = (rb_pid_t)aProcessInformation.dwProcessId;
|
child->pid = (rb_pid_t)aProcessInformation.dwProcessId;
|
||||||
|
|
||||||
return child;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* License: Ruby's */
|
/* License: Ruby's */
|
||||||
@ -1298,10 +1295,11 @@ is_batch(const char *cmd)
|
|||||||
MJIT_FUNC_EXPORTED HANDLE
|
MJIT_FUNC_EXPORTED HANDLE
|
||||||
rb_w32_start_process(const char *abspath, char *const *argv, int out_fd)
|
rb_w32_start_process(const char *abspath, char *const *argv, int out_fd)
|
||||||
{
|
{
|
||||||
/* NOTE: This function is used by MJIT worker, i.e. it must not touch Ruby VM.
|
/* NOTE: This function is used by MJIT worker, so it can be used parallelly with
|
||||||
This function is not using ALLOCV that may trigger GC. So this can't be
|
Ruby's main thread. So functions touching things shared with main thread can't
|
||||||
replaced with some families in this file. */
|
be sued, like `ALLOCV` that may trigger GC or `FindChildSlot` that finds a slot
|
||||||
struct ChildRecord *child;
|
from shared memory without locks. */
|
||||||
|
struct ChildRecord child;
|
||||||
char *cmd;
|
char *cmd;
|
||||||
size_t len;
|
size_t len;
|
||||||
WCHAR *wcmd = NULL, *wprog = NULL;
|
WCHAR *wcmd = NULL, *wprog = NULL;
|
||||||
@ -1317,22 +1315,20 @@ rb_w32_start_process(const char *abspath, char *const *argv, int out_fd)
|
|||||||
|
|
||||||
if (!(wcmd = mbstr_to_wstr(filecp(), cmd, -1, NULL))) {
|
if (!(wcmd = mbstr_to_wstr(filecp(), cmd, -1, NULL))) {
|
||||||
errno = E2BIG;
|
errno = E2BIG;
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (!(wprog = mbstr_to_wstr(filecp(), abspath, -1, NULL))) {
|
if (!(wprog = mbstr_to_wstr(filecp(), abspath, -1, NULL))) {
|
||||||
errno = E2BIG;
|
errno = E2BIG;
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
child = CreateChild(wcmd, wprog, NULL, outHandle, outHandle, 0);
|
if (!CreateChild(&child, wcmd, wprog, NULL, outHandle, outHandle, 0)) {
|
||||||
if (child == NULL) {
|
return NULL;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
child->pid = 0; /* release the slot */
|
|
||||||
|
|
||||||
free(wcmd);
|
free(wcmd);
|
||||||
free(wprog);
|
free(wprog);
|
||||||
return child->hProcess;
|
return child.hProcess;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* License: Artistic or GPL */
|
/* License: Artistic or GPL */
|
||||||
@ -1451,7 +1447,10 @@ w32_spawn(int mode, const char *cmd, const char *prog, UINT cp)
|
|||||||
if (v) ALLOCV_END(v);
|
if (v) ALLOCV_END(v);
|
||||||
|
|
||||||
if (!e) {
|
if (!e) {
|
||||||
ret = child_result(CreateChild(wcmd, wshell, NULL, NULL, NULL, 0), mode);
|
struct ChildRecord *child = FindFreeChildSlot();
|
||||||
|
if (CreateChild(child, wcmd, wshell, NULL, NULL, NULL, 0)) {
|
||||||
|
ret = child_result(child, mode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
free(wshell);
|
free(wshell);
|
||||||
free(wcmd);
|
free(wcmd);
|
||||||
@ -1536,7 +1535,10 @@ w32_aspawn_flags(int mode, const char *prog, char *const *argv, DWORD flags, UIN
|
|||||||
if (!e && prog && !(wprog = mbstr_to_wstr(cp, prog, -1, NULL))) e = E2BIG;
|
if (!e && prog && !(wprog = mbstr_to_wstr(cp, prog, -1, NULL))) e = E2BIG;
|
||||||
|
|
||||||
if (!e) {
|
if (!e) {
|
||||||
ret = child_result(CreateChild(wcmd, wprog, NULL, NULL, NULL, flags), mode);
|
struct ChildRecord *child = FindFreeChildSlot();
|
||||||
|
if (CreateChild(child, wcmd, wprog, NULL, NULL, NULL, flags)) {
|
||||||
|
ret = child_result(child, mode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
free(wprog);
|
free(wprog);
|
||||||
free(wcmd);
|
free(wcmd);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user