in reply to Re: Is this absurd, or have I not RTFM?
in thread Is this absurd, or have I not RTFM?

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

  • Comment on Re^2: Is this absurd, or have I not RTFM?

Replies are listed 'Best First'.
Re^3: Is this absurd, or have I not RTFM?
by salva (Canon) on May 19, 2014 at 08:15 UTC
    That smells like a buffering issue.

    Data in intermediate stdio or PerlIO write buffers can become duplicated when forking. Try setting $| = 1.

      Buffering doesn't explain why the two calls to DESTROY in the same process are handed different references to the same Perl object.

      I tried running with $|=1 ... it's still reproducible. If you try sufficient amount of times.

      auto-flushing can however explain why there's sometimes missing an "END DESTROY" output line. It's probably lost in a buffer when the process exits. It doesn't explain why DESTROY is called twice in the same process with different argument references to the same blessed Perl object.

        The documentation for $$ on perlvar talks about some problem with that variable being cached.

        Maybe running the program with strace could throw some light on this.

Re^3: Is this absurd, or have I not RTFM?
by Anonymous Monk on May 19, 2014 at 07:59 UTC

    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 :)

      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 :)

      This is not mere duplication of a printed message. As mentioned, when you enable the Devel::Peek statement you can see it's different references being provided in each call. Also this whole problem originated from a much more elaborate test-case where the result was that an XS module called free() twice on the same pointer in the same process. To my knowledge, this can't be explained with filehandles and buffers.

      Also, there is always the possibility that while first Ctrl+C is being cached, and first server is being destroyed, another server is forked ...

      Yeah... but strange that that new server get's the same PID as one of the old processes then.

      I'd try only creating variables inside sub process_request as Net::Server::PreFork documents :)

      I can't find that documented... anyway, that would of course be wise if the variable was a per-request variable. But this whole problem originated from needing to initialize a server global peace of data for all workers to be able to read.

      And PS: ... The title hinted at the possibility that there was some documented caveat wrt. global destruction phase in certain Perl versions which I hadn't found. ... btw...this seems to happen only during global destruction

        This is not mere duplication of a printed message. As mentioned, when you enable the Devel::Peek statement you can see it's different references being provided in each call.

        Can you add  STDOUT->autoflush(1); and show that output ?

Re^3: Is this absurd, or have I not RTFM?
by petermogensen (Sexton) on May 19, 2014 at 07:34 UTC
    ... and btw... I haven't yet been able to reproduce this with plain calling of fork(). Only through the Net::Server::Prefork module.