* pinfo.cc (pinfo::init): Move everything but the MapViewOfFileEx out of the
loop since trying multiple times to call CreateFileMapping doesn't make much sense. Try to structure the loop a little better so that exiting with a break does the right thing. (pinfo::release): Release shared memory area if it exists and close handle if it exists.
This commit is contained in:
parent
672879cab6
commit
9a0b76dced
|
@ -1,3 +1,12 @@
|
||||||
|
2005-01-22 Christopher Faylor <cgf@timesys.com>
|
||||||
|
|
||||||
|
* pinfo.cc (pinfo::init): Move everything but the MapViewOfFileEx out
|
||||||
|
of the loop since trying multiple times to call CreateFileMapping
|
||||||
|
doesn't make much sense. Try to structure the loop a little better so
|
||||||
|
that exiting with a break does the right thing.
|
||||||
|
(pinfo::release): Release shared memory area if it exists and close
|
||||||
|
handle if it exists.
|
||||||
|
|
||||||
2005-01-22 Christopher Faylor <cgf@timesys.com>
|
2005-01-22 Christopher Faylor <cgf@timesys.com>
|
||||||
|
|
||||||
* pinfo.cc (pinfo::maybe_set_exit_code_from_windows): Make sure that
|
* pinfo.cc (pinfo::maybe_set_exit_code_from_windows): Make sure that
|
||||||
|
|
|
@ -117,8 +117,8 @@ pinfo::maybe_set_exit_code_from_windows ()
|
||||||
GetExitCodeProcess (hProcess, &x);
|
GetExitCodeProcess (hProcess, &x);
|
||||||
self->exitcode = EXITCODE_SET | (x & 0xff) << 8;
|
self->exitcode = EXITCODE_SET | (x & 0xff) << 8;
|
||||||
}
|
}
|
||||||
sigproc_printf ("exit value - old %p, windows %p, cygwin %p", oexitcode, x,
|
sigproc_printf ("pid %d, exit value - old %p, windows %p, cygwin %p",
|
||||||
self->exitcode);
|
self->pid, oexitcode, x, self->exitcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -138,10 +138,17 @@ pinfo::exit (DWORD n)
|
||||||
fill_rusage (&r, hMainProc);
|
fill_rusage (&r, hMainProc);
|
||||||
add_rusage (&self->rusage_self, &r);
|
add_rusage (&self->rusage_self, &r);
|
||||||
|
|
||||||
|
/* The below call could be moved down two lines, but I like to see consistent
|
||||||
|
output from strace and the overhead should be extremely negligible. */
|
||||||
maybe_set_exit_code_from_windows ();
|
maybe_set_exit_code_from_windows ();
|
||||||
if (n != EXITCODE_NOSET)
|
if (n != EXITCODE_NOSET)
|
||||||
{
|
{
|
||||||
|
/* Move to an innocuous location to avoid races with other processes
|
||||||
|
that may want to manipulate the current directory before this process
|
||||||
|
has completely exited. */
|
||||||
SetCurrentDirectory ("c:\\");
|
SetCurrentDirectory ("c:\\");
|
||||||
|
/* Shave a little time off by telling our parent that we have now
|
||||||
|
exited. */
|
||||||
self->alert_parent (0);
|
self->alert_parent (0);
|
||||||
}
|
}
|
||||||
int exitcode = self->exitcode;
|
int exitcode = self->exitcode;
|
||||||
|
@ -156,7 +163,7 @@ pinfo::exit (DWORD n)
|
||||||
# undef self
|
# undef self
|
||||||
|
|
||||||
void
|
void
|
||||||
pinfo::init (pid_t n, DWORD flag, HANDLE in_h)
|
pinfo::init (pid_t n, DWORD flag, HANDLE h0)
|
||||||
{
|
{
|
||||||
if (myself && n == myself->pid)
|
if (myself && n == myself->pid)
|
||||||
{
|
{
|
||||||
|
@ -166,6 +173,9 @@ pinfo::init (pid_t n, DWORD flag, HANDLE in_h)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h = NULL;
|
||||||
|
procinfo = NULL;
|
||||||
|
|
||||||
void *mapaddr;
|
void *mapaddr;
|
||||||
if (!(flag & PID_MYSELF))
|
if (!(flag & PID_MYSELF))
|
||||||
mapaddr = NULL;
|
mapaddr = NULL;
|
||||||
|
@ -179,10 +189,13 @@ pinfo::init (pid_t n, DWORD flag, HANDLE in_h)
|
||||||
int createit = flag & (PID_IN_USE | PID_EXECED);
|
int createit = flag & (PID_IN_USE | PID_EXECED);
|
||||||
DWORD access = FILE_MAP_READ
|
DWORD access = FILE_MAP_READ
|
||||||
| (flag & (PID_IN_USE | PID_EXECED | PID_MAP_RW) ? FILE_MAP_WRITE : 0);
|
| (flag & (PID_IN_USE | PID_EXECED | PID_MAP_RW) ? FILE_MAP_WRITE : 0);
|
||||||
for (int i = 0; i < 10; i++)
|
|
||||||
|
bool created;
|
||||||
|
if (h0)
|
||||||
|
created = 0;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
int created;
|
char mapname[CYG_MAX_PATH];
|
||||||
char mapname[CYG_MAX_PATH]; /* XXX Not a path */
|
|
||||||
shared_name (mapname, "cygpid", n);
|
shared_name (mapname, "cygpid", n);
|
||||||
|
|
||||||
int mapsize;
|
int mapsize;
|
||||||
|
@ -191,14 +204,9 @@ pinfo::init (pid_t n, DWORD flag, HANDLE in_h)
|
||||||
else
|
else
|
||||||
mapsize = sizeof (_pinfo);
|
mapsize = sizeof (_pinfo);
|
||||||
|
|
||||||
if (in_h)
|
if (!createit)
|
||||||
{
|
{
|
||||||
h = in_h;
|
h0 = OpenFileMapping (access, FALSE, mapname);
|
||||||
created = 0;
|
|
||||||
}
|
|
||||||
else if (!createit)
|
|
||||||
{
|
|
||||||
h = OpenFileMapping (access, FALSE, mapname);
|
|
||||||
created = 0;
|
created = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -207,48 +215,41 @@ pinfo::init (pid_t n, DWORD flag, HANDLE in_h)
|
||||||
PSECURITY_ATTRIBUTES sec_attribs =
|
PSECURITY_ATTRIBUTES sec_attribs =
|
||||||
sec_user_nih (sa_buf, cygheap->user.sid(), well_known_world_sid,
|
sec_user_nih (sa_buf, cygheap->user.sid(), well_known_world_sid,
|
||||||
FILE_MAP_READ);
|
FILE_MAP_READ);
|
||||||
h = CreateFileMapping (INVALID_HANDLE_VALUE, sec_attribs,
|
h0 = CreateFileMapping (INVALID_HANDLE_VALUE, sec_attribs,
|
||||||
PAGE_READWRITE, 0, mapsize, mapname);
|
PAGE_READWRITE, 0, mapsize, mapname);
|
||||||
created = h && GetLastError () != ERROR_ALREADY_EXISTS;
|
created = GetLastError () != ERROR_ALREADY_EXISTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!h)
|
if (!h0)
|
||||||
{
|
{
|
||||||
if (createit)
|
if (createit)
|
||||||
__seterrno ();
|
__seterrno ();
|
||||||
procinfo = NULL;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
procinfo = (_pinfo *) MapViewOfFileEx (h, access, 0, 0, 0, mapaddr);
|
ProtectHandle1 (h0, pinfo_shared_handle);
|
||||||
if (procinfo)
|
|
||||||
/* it worked */;
|
for (int i = 0; i < 20; i++)
|
||||||
else if (exit_state)
|
{
|
||||||
return; /* exiting */
|
procinfo = (_pinfo *) MapViewOfFileEx (h0, access, 0, 0, 0, mapaddr);
|
||||||
else
|
if (!procinfo)
|
||||||
{
|
{
|
||||||
if (GetLastError () == ERROR_INVALID_HANDLE)
|
if (exit_state)
|
||||||
api_fatal ("MapViewOfFileEx(%p, in_h %p) failed, %E", h, in_h);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
debug_printf ("MapViewOfFileEx(%p, in_h %p) failed, %E", h, in_h);
|
|
||||||
if (h != in_h)
|
|
||||||
CloseHandle (h);
|
|
||||||
}
|
|
||||||
if (i < 9)
|
|
||||||
continue;
|
|
||||||
else
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
ProtectHandle1 (h, pinfo_shared_handle);
|
if (GetLastError () == ERROR_INVALID_HANDLE)
|
||||||
|
api_fatal ("MapViewOfFileEx h0 %p, i %d failed, %E", h0, i);
|
||||||
|
|
||||||
|
debug_printf ("MapViewOfFileEx h0 %p, i %d failed, %E", h0, i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ((procinfo->process_state & PID_INITIALIZING) && (flag & PID_NOREDIR)
|
if ((procinfo->process_state & PID_INITIALIZING) && (flag & PID_NOREDIR)
|
||||||
&& cygwin_pid (procinfo->dwProcessId) != procinfo->pid)
|
&& cygwin_pid (procinfo->dwProcessId) != procinfo->pid)
|
||||||
{
|
{
|
||||||
release ();
|
set_errno (ESRCH);
|
||||||
set_errno (ENOENT);
|
break;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (procinfo->process_state & PID_EXECED)
|
if (procinfo->process_state & PID_EXECED)
|
||||||
|
@ -259,26 +260,21 @@ pinfo::init (pid_t n, DWORD flag, HANDLE in_h)
|
||||||
if (realpid == n)
|
if (realpid == n)
|
||||||
api_fatal ("retrieval of execed process info for pid %d failed due to recursion.", n);
|
api_fatal ("retrieval of execed process info for pid %d failed due to recursion.", n);
|
||||||
n = realpid;
|
n = realpid;
|
||||||
release ();
|
|
||||||
if (flag & PID_ALLPIDS)
|
if ((flag & PID_ALLPIDS))
|
||||||
{
|
{
|
||||||
set_errno (ENOENT);
|
set_errno (ESRCH);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
continue;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* In certain rare, pathological cases, it is possible for the shared
|
/* In certain rare cases, it is possible for the shared memory region to
|
||||||
memory region to exist for a while after a process has exited. This
|
exist for a while after a process has exited. This should only be a
|
||||||
should only be a brief occurrence, so rather than introduce some kind
|
brief occurrence, so rather than introduce some kind of locking
|
||||||
of locking mechanism, just loop. FIXME: I'm sure I'll regret doing it
|
mechanism, just loop. */
|
||||||
this way at some point. */
|
if (!created && createit && (procinfo->process_state & PID_EXITED))
|
||||||
if (i < 9 && !created && createit && (procinfo->process_state & PID_EXITED))
|
goto loop;
|
||||||
{
|
|
||||||
low_priority_sleep (5);
|
|
||||||
release ();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!created)
|
if (!created)
|
||||||
/* nothing */;
|
/* nothing */;
|
||||||
|
@ -290,9 +286,21 @@ pinfo::init (pid_t n, DWORD flag, HANDLE in_h)
|
||||||
procinfo->pid = myself->pid;
|
procinfo->pid = myself->pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h = h0; /* Success! */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
loop:
|
||||||
|
release ();
|
||||||
|
low_priority_sleep (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (h)
|
||||||
|
destroy = 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
h = h0;
|
||||||
|
release ();
|
||||||
}
|
}
|
||||||
destroy = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -875,7 +883,7 @@ _pinfo::alert_parent (char sig)
|
||||||
void
|
void
|
||||||
pinfo::release ()
|
pinfo::release ()
|
||||||
{
|
{
|
||||||
if (h)
|
if (procinfo)
|
||||||
{
|
{
|
||||||
#ifdef DEBUGGING
|
#ifdef DEBUGGING
|
||||||
if (((DWORD) procinfo & 0x77000000) == 0x61000000)
|
if (((DWORD) procinfo & 0x77000000) == 0x61000000)
|
||||||
|
@ -883,6 +891,9 @@ pinfo::release ()
|
||||||
#endif
|
#endif
|
||||||
UnmapViewOfFile (procinfo);
|
UnmapViewOfFile (procinfo);
|
||||||
procinfo = NULL;
|
procinfo = NULL;
|
||||||
|
}
|
||||||
|
if (h)
|
||||||
|
{
|
||||||
ForceCloseHandle1 (h, pinfo_shared_handle);
|
ForceCloseHandle1 (h, pinfo_shared_handle);
|
||||||
h = NULL;
|
h = NULL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue