Re: Is this absurd, or have I not RTFM?
by salva (Canon) on May 19, 2014 at 08:06 UTC
|
There are two ways to workaround that issue:
- Exit from the child processes calling POSIX::_exit(). That would skip any cleanup.
- Save on your objects the PID from the process creating them (you get it from $$) and on DESTROY skip the cleanup actions if the saved PID is different to that of the current process.
Actually, you can use both at the same time. | [reply] [d/l] [select] |
|
|
Ad 1: I don't really control child process exit here. Net::Server does.
Ad 2: That would be the solution if you wanted to create an object in a parent and have only the parent DESTROY it. (like if you have process shared resources). But that's not the intention or the problem here. I *want* each process to execute DESTROY - but only once for each Perl object.
... and this solution still relies on DESTROY being called only once in each process. This is not the case here. ... it's a little different whether it's the parent or the child which calls DESTROY twice.
| [reply] |
Re: Is this absurd, or have I not RTFM?
by LanX (Saint) on May 19, 2014 at 15:36 UTC
|
| [reply] |
|
|
| [reply] |
Re: Is this absurd, or have I not RTFM?
by Anonymous Monk on May 19, 2014 at 07:19 UTC
|
Is this absurd, or have I not RTFM? If you have to ask, you have not RTFM
?!?!!? ... why was DESTROY called twice in the same process? ... and why didn't it end?
Enabling Devel::Peek will reveal it's 2 difference references to the same Perl object. Because forking forks, its like forking :) Mr. Peabody Explains fork()
| [reply] |
|
|
Ok ...
To get the headline out of the way; I *have* read the manual.
And to get the other misunderstanding out of the way: I *do* know what fork() does.
But look at the example output. You would expect that you created this object once, and then DESTROY was called once in each process in global destruction.
But in one of the processes (look at the PID) DESTROY is called twice. There's no surprice to see DESTROY being called twice in different processes. The surprise is that this is the same process, calling DESTROY (on the same object, but with different references).
Please read the question again
| [reply] |
|
|
| [reply] [d/l] |
|
|
|
|
|
|
|
To get the headline out of the way; I *have* read the manual. Odd choice for a title then :)
The surprise is that this is the same process, calling DESTROY (on the same object, but with different references).
Um, I don't find it that surprising :)
You've got file scope lexicals mixing with signals and a forking framework (used in not as documented way) ... all printing to same filehandle
Between changes made in 5.16, safe signals, perlIO and buffering, an occasional duplication of some DESTROY printed messages isn't something I'd worry about .... unless it happens with perl-5.16.3 :)
Also, there is always the possibility that while first Ctrl+C is being cached, and first server is being destroyed, another server is forked ...
I'd try only creating variables inside sub process_request as Net::Server::PreFork documents :)
| [reply] [d/l] |
|
|
|
|
|
|
|
... and btw... I haven't yet been able to reproduce this with plain calling of fork(). Only through the Net::Server::Prefork module.
| [reply] |
Re: Is this absurd, or have I not RTFM?
by locked_user sundialsvc4 (Abbot) on May 19, 2014 at 11:10 UTC
|
What stands out to me is that there is no END DESTROY message being printed for the first PID. Instead, there are two BEGIN DESTROY messages in a row, and only one END, but only for that one PID. Unless there is an equal pairing of BEGIN/END messages which I do not yet see but may well have missed, this suggests some kind of recursion, subclassing issue, or even a good old-fashioned subtle bug ... in your code. Is it possible, therefore, to post a complete example of the actual destructor, and a synopsis of any class/subclass hierarchy that you use?
| |
|
|
Is it possible, therefore, to post a complete example of the actual destructor, and a synopsis of any class/subclass hierarchy that you use? OP already did that sundialsvc4 , thats what "boiled it down to this script" means
| [reply] |
|
|
======= BEGIN DESTROY:9980========
======= BEGIN DESTROY:9980========
============ END DESTROY:9980========
======= BEGIN DESTROY:9979========
============ END DESTROY:9979========
Now, this might not be complete, so there might well be more to it than is shown and maybe this pattern is not repeatable. We would need to see the entire display and maybe several instances of it to see if it is basically a timing-artifact. But I believe that I saw the same basic behavior in other follow-ups to this thread also. The first BEGIN for pid #9980 is not followed by an END ... ever. It’s followed by another BEGIN, which is followed by END, as is the display for the second pid #9979. (I do not presume which one of these is actually the child and which one is the parent ... PID-assignments are assumed-random.)
In the complete display, I expect that the BEGIN and END calls should be evenly matched, regardless of the exact order in which they occur. If they are not, then I no longer accept the premise that “the destructor is ‘being called twice.’” (Lemma: If it is called twice, then it should end twice. Destructors are nothing more than de-initialization subroutines. They should run to completion.) If they do not, then perhaps a runtime error is being thrown that we cannot see here. I am sensitive to the Red-Herring Effect here . . . I smell a fish. It would be very, very easy to mis-interpret what is being presented here. Yeah, I think that the presumption that there is something wrong with the destructor-system should well be called, for the moment at least, “absurd(ly improbable).” Sufficiently improbable to smell like seafood. So, what else might it be.
| |
|
|
|
|
|
|
|
|
|
|
|
|
| A reply falls below the community's threshold of quality. You may see it by logging in. |