asdfgroup has asked for the wisdom of the Perl Monks concerning the following question:

Made small program to test speed of Event module :
use Event; Event->signal(signal=>'HUP', cb=>sub {$i++; kill 1, $$}); Event->signal(signal=>'ALRM', cb=>sub {printf "%d\t%d\n", ++$t, $i-$ol +d_i; $old_i=$i; ; alarm 1}); alarm 1; kill 1, $$; Event::loop;
Looks like this code use memory infinitely.
Is this memory leak in Event.pm ?

Replies are listed 'Best First'.
Re: Event.pm memory leek ?
by cazz (Pilgrim) on Apr 22, 2005 at 13:17 UTC
    No, this is a memory leak in your code.

    Don't put memory allocation in a signal handler. The underpinnings of printf are mallocing. Before printf can free, you are calling the signal handler again.

      This does not look correct, because :
      - signal is masked in own callback (normal Unix behaviour, tested this is ok in Event.pm as well)
      - if you change printf on print or even syswrite, memory leak will still exist
      - similar code works fine in test without Event.pm (using %SIG)

      Update: code like
      use Event; Event->signal(signal=>'HUP', cb=>sub {kill 1, $$}); kill 1, $$; Event::loop;
      produce memory leak as well :)
        Ok, so not only does your code malloc inside a signal handler, so does Event.

        Well, Event.xs shows that when signal is called, it does copying.

        _signal_signal(THIS, items == 2? sv_mortalcopy(ST(1)) : 0);
        sv_mortalcopy mallocs. Since you are calling the signal handler from inside the signal handler, it never frees that memory. Simple solution: Don't call the signal handler from inside the signal handler.
Re: Event.pm memory leek ?
by salva (Canon) on Apr 22, 2005 at 14:52 UTC

    Maybe...

    Programs using signals are tricky in perl (well, actually in any language), and I have been looking at Event.pm source code, and it is anything but simple, so I would not discard some bug there.

    Also because you are (ab)using the module in some unusual way, sending a HUP signal from the HUP signal handler all the time without letting it rest for a while...

    Yes I know, that sounds a bit silly, programs don't need to rest, but I have a reason to say that: the way perl vars are freed, marking them as mortals (see perlxs, perlguts and perlapi man pages for what's a mortal explanations).

    Maybe Event.pm only closes the callback calling scope when the event queue is empty, and not after every callback invocation...

    So, summarizing: send a bug report to the module author!!!

      Looks like this is really some memory leak in Event.pm, becuase code like this :
      use Event; pipe(R,W); Event->io(fd=>\*R, poll=>"r", cb=>sub {sysread R, $r, 1 or warn "read: + $!"; syswrite W, $r, 1 or warn "write: $!"; i++}); Event->signal(signal=>'ALRM', cb=>sub {printf "%d\t%d\n", ++$t, $i-$ol +d_i; $old_i=$i; alarm 1}); alarm 1; syswrite W, "!" or die $!; Event::loop;
      produce memory leak as well :(