in reply to Re^4: Socket descriptor passed across fork -- hanging
in thread Socket descriptor passed across fork -- hanging

I guess I should explain, that I started with C code and then said, "hey, what would this look like in Perl for the fun of it". I was able to any combination working together. C server/Perl Client, Perl Server/C client or both each way.

You brought up some good points, one is the "or next" in the accept().
You say in the code that the "next" if accept returns undef isn't necessary any more, but I've seen my $listen->accept() call return EINTR (perl 5.8.8, Linux 2.6.18), so it seems to be necessary still here. I agree with you and would leave the code as is - my comment is wrong.

Yes, I would close the sockets that aren't going to be used! This is cheap and solves problems!

For example, as a parent (the server) after I have forked off a child, I am not going to talk on the active socket. That is the child's job. One reason to close it is assist in freeing resources. If the child decides to hang up on the client close the active socket, then we don't have to worry about what kind of weird stuff might or might not happen because I still have it open in a parent.

We get into a similar sort of a thing if the child doesn't close the passive socket. We don't want children somehow running off making grandchildern! A child's job is to talk to one client. If somehow some kid had a baby then we have some dual role stuff going on and there can be issues with who reaps who when who dies. "close($passive)"; closes off a lot of possible nasty things at very little cost.

Keep the fork architecture "clean":
Parents only listen for new clients, they make a new child to deal with the new client and then go back to listening.

Children only talk to the client that they are connected to. They die when the need for them to talk to that client goes away. The parent who started them is notified when they die.

I've been finding various strange returns from $sock->read(), including undef with $! empty. Yes there can be strange things. $! is only set only an error. It is not reset if there is no error. I think in some circumstances undef is just considered "normal status" and is not an error. This is true in the C interface where there is of course no such thing as "undef".

Systems programming is complicated stuff and there are lots of timing related "yeah but's".

  • Comment on Re^5: Socket descriptor passed across fork -- hanging