Craig A. Berry wrote:
> At 04:52 PM 4/22/2002 -0400, Charles Lane wrote:
> >(it sounded like you were assuming that a read doesn't remove the
> >message; it does)

> I guess I was assuming that whatever writes the termination message will
> satisfy an arbitrary number of readers. I'm not sure where I got this
> impression and it may be completely wrong.  Somewhere I could swear I saw an
> example (possibly in the Apache sources?) of reading a termination mailbox
> where the reader discarded a message and requeued itself if the pid didn't
> match (perhaps was a different child of the same parent) or the type of
> message was anything other than process termination (since the same mbx is
> used, as you indicate below, for other purposes).  This would only work if
> the writer was willing to satisfy multiple requests since otherwise, as you
> suggest, whoever got there first would steal the message from the others.

Well, according to the "VAX/VMS Internals and Data Structures" book, the
mailbox message is constructed deep in the "DELETE Kernel Mode AST".  I
very much doubt that it pays any attention at all as to how many mbx
"readers" there are, and whether the parent process actually picks up the
message.  It just dumps a message in the mailbox and continues with
process rundown.

The example you mention is of multiple writers and one reader, and it sounds
like it's getting confused with multiple readers and one writer.

>>  It
> >> looked to me like the only time we could fail to recognize a pipe subprocess
> >> was when my_pclose had already initiated shutdown with either $delprc or
> >> $forcex.
> >Not true, I was seeing the hang even when the child process exits
> >normally.
> In which case the process would still be in the midst of getting deleted,
> right?

Correct, but the point being that a $delprc or $forcex from the parent
isn't required.   It's likely that my machine is slower than yours, so
I can see this stuff more easily :)

> >Which isn't that bad a way of getting a "wait for termination" without
> >having to do polling, but it still is problematic.
> >
> >For example (and I have a program that does stuff like this):
> >
>>    Process A creates a "general purpose message mailbox", opens read/write
>>        channel to that mailbox, queues a read to mbx.
>>    Process A spawns child B, with the term mbx -> general purpose mbx
>>    Process A spawns child C, with the term mbx -> general purpose mbx

> Eek!  Why is process A using its general purpose mbx as the termination mbx
> of its children?  That will definitely cause hilarity, if not mayhem.  It
> couldn't happen in the piping code since you use lib$spawn instead of
> sys$creprc.

I should have made it clearer, my bad.
The processes A, B, C aren't Perl.  Perl is playing the part of an
interloper, that is trying to determine when B terminates.

IIRC, when you open a device "with associated mailbox", the format of
the mailbox messages are the same as process termination messages, so
it makes sense to just have a single mailbox to collect 'em all.

In fact for sending messages between cooperating processes, it makes
sense to just use the standard "mailbox message format" for your own
stuff as well, rather than having multiple i/o queues for multiple
mailboxes.

> >In this case, the WRITERCHECK won't help, because A maintains a r/w
> >channel to the mailbox.  (the write is used to put "internal" messages
> >in its input queue).
> >
> >Perl is waiting for child B, so you queue a read to the mbx; child B
> >terminates, but since process A had a read queued first, it gets the
> >termination message.
> >
> >Then A queues another read.
> >
> >Then child C exits, giving another termination message, or perhaps
> >something else writes to the mailbox (a DECnet event, for example).
> >
> >Since Perl's waitpid queued its read before A's, waitpid will get the
> >message and A won't.  Hilarity ensues.

> It's got to be a bit more complicated than that.  Perhaps the writer can
> satisfy multiple readers but not an arbitrary number of them, i.e., perhaps
> it knows how many children it has (not how many read channels are open) and
> what I've done is create a sort of musical chairs situation where one child
> always gets left without a mailbox message.

It isn't that complicated, it's dead simple.  No doubt, that's the
confusing part!

If a process has a "termination mailbox", during process rundown a single
termination message is written to the mailbox. End of story.

All the rest: (when|by whom|whether) that message is read is entirely
out of the control of the now-defunct child process.

> >In the above example, the problem is that while a CHILD subprocess has
> >a single termination mailbox, that mailbox can also be used by the
> >PARENT for many disparate purposes, and when we *can* break into the
> >communication between parent and child, we probably shouldn't unless
> >we know exactly what we're doing.  Which is not something one can do
> >in a "general purpose" utility routine.

> Possibly not.  Unless someone can help us out with how termination mailboxes
> really work, we should probably ditch waitpid's attempt to use them for now.

I use them extensively in the CRINOID server, since the server has to
dynamically manage a bunch of subprocesses. The A/B/C example above is
a simplified version of how CRINOID handles subprocesses.  And yes, there
is a general-purpose mailbox that collects process termination messages,
communication between processes, and DECnet events.
--
 Drexel University       \V                    --Chuck Lane
======]---------->--------*------------<-------[===========
     (215) 895-1545     _/ \  Particle Physics
FAX: (215) 895-5934     /\ /~~~~~~~~~~~        [EMAIL PROTECTED]

Reply via email to