mirror of
https://github.com/SoftEtherVPN/SoftEtherVPN.git
synced 2024-11-22 17:39:53 +03:00
Fix a deadlock when Run() to create a process. Child forked will inherit
state of global mutex which may be in intermidiate taken status by one of threads of the parent, then in child process it tries to get this mutex and is always pending. One example of mutex is malloc_lock, and there are more.
This commit is contained in:
parent
1e17c9bcfd
commit
69d132e997
47
src/Mayaqua/Unix.c
Normal file → Executable file
47
src/Mayaqua/Unix.c
Normal file → Executable file
@ -1162,7 +1162,9 @@ bool UnixRunW(wchar_t *filename, wchar_t *arg, bool hide, bool wait)
|
|||||||
bool UnixRun(char *filename, char *arg, bool hide, bool wait)
|
bool UnixRun(char *filename, char *arg, bool hide, bool wait)
|
||||||
{
|
{
|
||||||
TOKEN_LIST *t;
|
TOKEN_LIST *t;
|
||||||
|
char **args;
|
||||||
UINT ret;
|
UINT ret;
|
||||||
|
|
||||||
// Validate arguments
|
// Validate arguments
|
||||||
if (filename == NULL)
|
if (filename == NULL)
|
||||||
{
|
{
|
||||||
@ -1173,6 +1175,25 @@ bool UnixRun(char *filename, char *arg, bool hide, bool wait)
|
|||||||
arg = "";
|
arg = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Print("", filename, arg);
|
||||||
|
t = ParseToken(arg, " ");
|
||||||
|
if (t == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UINT num_args;
|
||||||
|
UINT i;
|
||||||
|
num_args = t->NumTokens + 2;
|
||||||
|
args = ZeroMalloc(sizeof(char *) * num_args);
|
||||||
|
args[0] = filename;
|
||||||
|
for (i = 1;i < num_args - 1;i++)
|
||||||
|
{
|
||||||
|
args[i] = t->Token[i - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Create a child process
|
// Create a child process
|
||||||
ret = fork();
|
ret = fork();
|
||||||
if (ret == -1)
|
if (ret == -1)
|
||||||
@ -1183,39 +1204,21 @@ bool UnixRun(char *filename, char *arg, bool hide, bool wait)
|
|||||||
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
{
|
{
|
||||||
Print("", filename, arg);
|
|
||||||
// Child process
|
// Child process
|
||||||
if (hide)
|
if (hide)
|
||||||
{
|
{
|
||||||
// Close the standard I/O
|
// Close the standard I/O
|
||||||
UnixCloseIO();
|
UnixCloseIO();
|
||||||
}
|
}
|
||||||
|
execvp(filename, args);
|
||||||
t = ParseToken(arg, " ");
|
AbortExit();
|
||||||
if (t == NULL)
|
|
||||||
{
|
|
||||||
AbortExit();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char **args;
|
|
||||||
UINT num_args;
|
|
||||||
UINT i;
|
|
||||||
num_args = t->NumTokens + 2;
|
|
||||||
args = ZeroMalloc(sizeof(char *) * num_args);
|
|
||||||
args[0] = filename;
|
|
||||||
for (i = 1;i < num_args - 1;i++)
|
|
||||||
{
|
|
||||||
args[i] = t->Token[i - 1];
|
|
||||||
}
|
|
||||||
execvp(filename, args);
|
|
||||||
AbortExit();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Parent process
|
// Parent process
|
||||||
pid_t pid = (pid_t)ret;
|
pid_t pid = (pid_t)ret;
|
||||||
|
Free(args);
|
||||||
|
FreeToken(t);
|
||||||
|
|
||||||
if (wait)
|
if (wait)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user