* 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:
Christopher Faylor 2005-01-22 21:17:53 +00:00
parent 672879cab6
commit 9a0b76dced
2 changed files with 77 additions and 57 deletions

View File

@ -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

View File

@ -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;
} }