Change name from commune_recv to commune_process throughout. Change name from
commune_send to commune_request throughout. * pinfo.h (PICOM_EXTRASTR): New flag. (PICOM_FIFO): Define with new flag. (_pinfo::hello_pid): Delete. (_pinfo::tothem): Delete. (_pinfo::fromthem): Delete. (_pinfo::commune_process): Rename from commune_recv. Add a siginfo_t argument to declaration. (_pinfo::commune_request): Rename from commune_send. Change DWORD to __uint32_t in declaration. * pinfo.cc (_pinfo::commune_process): Rename from commune_recv. Add siginfo_t argument. Use information from argument rather than reading from another pipe. Synchronize with other process's commune event. (_pinfo::commune_request): Rename from commune_send. Change DWORD to __uint32 in argument. Fill out information in new siginfo_t element and rely on extended operation of sig_send rather than trying to deal with synchronization issues here. Use process handle and read pipe information filled out by sig_send to gather information from the other process. * sigproc.cc (sig_send): Take special action if "communing" to ensure synchronization with the other process and to return information about the other process to the caller. (talktome): Accept a siginfo_t and handle arguments. Read additional information from the signal pipe when _si_commune._si_code has the PICOM_EXTRASTR flag set. (wait_sig): Pass the transmitted siginfo_t struct and the pipe handle to talktome. Close pipe read handle as soon as possible after we detect that we're exiting.
This commit is contained in:
@@ -526,6 +526,7 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
|
||||
bool its_me;
|
||||
HANDLE sendsig;
|
||||
sigpacket pack;
|
||||
bool communing = si.si_signo == __SIGCOMMUNE;
|
||||
|
||||
pack.wakeup = NULL;
|
||||
bool wait_for_completion;
|
||||
@@ -598,8 +599,29 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
|
||||
CloseHandle (hp);
|
||||
goto out;
|
||||
}
|
||||
CloseHandle (hp);
|
||||
VerifyHandle (sendsig);
|
||||
if (!communing)
|
||||
CloseHandle (hp);
|
||||
else
|
||||
{
|
||||
si._si_commune._si_process_handle = hp;
|
||||
|
||||
HANDLE& tome = si._si_commune._si_write_handle;
|
||||
HANDLE& fromthem = si._si_commune._si_read_handle;
|
||||
if (!CreatePipe (&fromthem, &tome, &sec_all_nih, 0))
|
||||
{
|
||||
sigproc_printf ("CreatePipe for __SIGCOMMUNE failed, %E");
|
||||
__seterrno ();
|
||||
goto out;
|
||||
}
|
||||
if (!DuplicateHandle (hMainProc, tome, hp, &tome, false, 0,
|
||||
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
|
||||
{
|
||||
sigproc_printf ("DuplicateHandle for __SIGCOMMUNE failed, %E");
|
||||
__seterrno ();
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sigproc_printf ("sendsig %p, pid %d, signal %d, its_me %d", sendsig, p->pid, si.si_signo, its_me);
|
||||
@@ -628,8 +650,25 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
|
||||
ProtectHandle (pack.wakeup);
|
||||
}
|
||||
|
||||
char *leader;
|
||||
size_t packsize;
|
||||
if (!communing || !(si._si_commune._si_code & PICOM_EXTRASTR))
|
||||
{
|
||||
leader = (char *) &pack;
|
||||
packsize = sizeof (pack);
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t n = strlen (si._si_commune._si_str);
|
||||
char *p = leader = (char *) alloca (sizeof (pack) + sizeof (n) + n);
|
||||
memcpy (p, &pack, sizeof (pack)); p += sizeof (pack);
|
||||
memcpy (p, &n, sizeof (n)); p += sizeof (n);
|
||||
memcpy (p, si._si_commune._si_str, n); p += n;
|
||||
packsize = p - leader;
|
||||
}
|
||||
|
||||
DWORD nb;
|
||||
if (!WriteFile (sendsig, &pack, sizeof (pack), &nb, NULL) || nb != sizeof (pack))
|
||||
if (!WriteFile (sendsig, leader, packsize, &nb, NULL) || nb != packsize)
|
||||
{
|
||||
/* Couldn't send to the pipe. This probably means that the
|
||||
process is exiting. */
|
||||
@@ -687,8 +726,16 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
|
||||
|
||||
if (wait_for_completion && si.si_signo != __SIGFLUSHFAST)
|
||||
_my_tls.call_signal_handler ();
|
||||
goto out;
|
||||
|
||||
out:
|
||||
if (communing && rc)
|
||||
{
|
||||
if (si._si_commune._si_process_handle)
|
||||
CloseHandle (si._si_commune._si_process_handle);
|
||||
if (si._si_commune._si_read_handle)
|
||||
CloseHandle (si._si_commune._si_read_handle);
|
||||
}
|
||||
if (pack.wakeup)
|
||||
ForceCloseHandle (pack.wakeup);
|
||||
if (si.si_signo != __SIGPENDING)
|
||||
@@ -921,11 +968,23 @@ stopped_or_terminated (waitq *parent_w, _pinfo *child)
|
||||
}
|
||||
|
||||
static void
|
||||
talktome (siginfo_t& si)
|
||||
talktome (siginfo_t& si, HANDLE readsig)
|
||||
{
|
||||
pinfo p (si.si_pid, PID_MAP_RW);
|
||||
if (p)
|
||||
p->commune_recv ();
|
||||
pinfo pi (si.si_pid);
|
||||
if (si._si_commune._si_code & PICOM_EXTRASTR)
|
||||
{
|
||||
size_t n;
|
||||
DWORD nb;
|
||||
if (!ReadFile (readsig, &n, sizeof (n), &nb, NULL) || nb != sizeof (n))
|
||||
return;
|
||||
// FIXME: Is alloca here?
|
||||
si._si_commune._si_str = (char *) alloca (n + 1);
|
||||
if (!ReadFile (readsig, si._si_commune._si_str, n, &nb, NULL) || nb != n)
|
||||
return;
|
||||
si._si_commune._si_str[n] = '\0';
|
||||
}
|
||||
if (pi)
|
||||
pi->commune_process (si);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1039,7 +1098,7 @@ wait_sig (VOID *)
|
||||
switch (pack.si.si_signo)
|
||||
{
|
||||
case __SIGCOMMUNE:
|
||||
talktome (pack.si);
|
||||
talktome (pack.si, readsig);
|
||||
break;
|
||||
case __SIGSTRACE:
|
||||
strace.hello ();
|
||||
|
Reference in New Issue
Block a user