Skip to content
Browse files

garbage collection fixes

  • Loading branch information...
1 parent f8a6b7c commit b5cccc0f7e8398ef6a9887f22b6e494d64615a72 @rcaputo committed
Showing with 37 additions and 82 deletions.
  1. +9 −8 Changes
  2. +19 −62 lib/POE/Kernel.pm
  3. +0 −1 tests/02_alarms.t
  4. +2 −3 tests/09_wheels_unix.t
  5. +2 −3 tests/10_wheels_tcp.t
  6. +2 −2 tests/11_signals_poe.t
  7. +3 −3 tests/12_signals_ev.t
View
17 Changes
@@ -16,10 +16,6 @@ subversions are available from <http://www.newts.org/~troc/poe.html>.
,----- To Do -----
|
-| Before 0.1008
-|
-| Initialize KR_GC_MARKS as a hash.
-|
| Before 0.11
|
| Test $kernel->fork() or replace it entirely.
@@ -37,13 +33,18 @@ subversions are available from <http://www.newts.org/~troc/poe.html>.
0.1008 2000.??.??
-----------------
+Tidied Session garbage collection tests.
+
+Stopped setting $SIG{CH?LD} handlers when using Event.
+
+The wheels tests were failing on DOSISH systems because the 1-byte
+blocksize generated fake newlines. CR and LF coming in separately and
+being interpreted as two newlines. Increased the BlockSize so this
+won't happen.
+
Prevented the TKDESTROY signal from being fired if POE finishes before
Tk does. There's nothing to receive the signal!
-Added the beginnings of a mark/sweep garbage collector for sessions.
-This is added mainly to avoid redundant garbage collections; if
-there's any performance benefit, it's purely accidental.
-
Enhanced the "# line" directives that POE::Preprocessor injects into
macros. Now they're added when macros are used; this enables them to
include not only the macro name and line number but also the source
View
81 lib/POE/Kernel.pm
@@ -113,17 +113,6 @@ macro alias_resolve (<name>) {
)
}
-macro gc_mark(<session>) {
- $self->[KR_GC_MARKS]->{<session>} = $session;
-}
-
-macro gc_clear(<session>) {
- delete $self->[KR_GC_MARKS]->{<session>};
-}
-
-macro gc_sweep {
-}
-
macro collect_garbage (<session>) {
if (<session> != $self) {
TRACE_GARBAGE and $self->trace_gc_refcount(<session>);
@@ -196,49 +185,24 @@ macro post_plain_signal (<destination>,<signal_name>) {
);
}
-macro post_child_signal(<destination>,<pid>,<exit_status>) {
- # Determine if the child process is really exiting and not just
- # stopping for some other reason. This is per Perl Cookbook recipe
- # 16.19.
- if (WIFEXITED(<exit_status>)) {
- $poe_kernel->_enqueue_state( <destination>, $poe_kernel,
- EN_SIGNAL, ET_SIGNAL,
- [ 'CHLD', <pid>, <exit_status> ],
- time(), __FILE__, __LINE__
- );
- }
-}
-
macro dispatch_one_from_fifo {
+ # Pull an event off the queue, and dispatch it.
if ( @{ $self->[KR_STATES] } ) {
-
- # Pull an event off the queue.
-
my $event = shift @{ $self->[KR_STATES] };
{% ses_refcount_dec2 $event->[ST_SESSION], SS_EVCOUNT %}
-
- # Dispatch it, and see if that was the last thing the session
- # needed to do.
-
$self->_dispatch_state(@$event);
{% collect_garbage $event->[ST_SESSION] %}
}
}
macro dispatch_due_alarms {
+ # Pull due alarms off the queue, and dispatch them.
my $now = time();
while ( @{ $self->[KR_ALARMS] } and
($self->[KR_ALARMS]->[0]->[ST_TIME] <= $now)
) {
-
- # Pull an alarm off the queue.
-
my $event = shift @{ $self->[KR_ALARMS] };
{% ses_refcount_dec2 $event->[ST_SESSION], SS_ALCOUNT %}
-
- # Dispatch it, and see if that was the last thing the session
- # needed to do.
-
$self->_dispatch_state(@$event);
{% collect_garbage $event->[ST_SESSION] %}
}
@@ -385,8 +349,7 @@ enum SH_HANDLE SH_REFCOUNT SH_VECCOUNT
# The Kernel object. KR_SIZE goes last (it's the index count).
enum KR_SESSIONS KR_VECTORS KR_HANDLES KR_STATES KR_SIGNALS KR_ALIASES
enum + KR_ACTIVE_SESSION KR_PROCESSES KR_ALARMS KR_ID KR_SESSION_IDS
-enum + KR_ID_INDEX KR_WATCHER_TIMER KR_WATCHER_IDLE KR_EXTRA_REFS
-enum + KR_GC_MARKS KR_SIZE
+enum + KR_ID_INDEX KR_WATCHER_TIMER KR_WATCHER_IDLE KR_EXTRA_REFS KR_SIZE
# Handle structure.
enum HND_HANDLE HND_REFCOUNT HND_VECCOUNT HND_SESSIONS HND_FILENO HND_WATCHERS
@@ -502,8 +465,6 @@ const FIFO_DISPATCH_TIME 0.01
#
# names: { $name => $session };
#
-# gc marks: { $session => $session };
-#
#------------------------------------------------------------------------------
#==============================================================================
@@ -1030,7 +991,8 @@ sub _dispatch_state {
if ($type) {
# A new session has started. Tell its parent. Incidental _start
- # events are fired after the dispatch.
+ # events are fired after the dispatch. Garbage collection is
+ # delayed until ET_GC.
if ($type & ET_START) {
$self->_dispatch_state( $sessions->{$session}->[SS_PARENT], $self,
@@ -1040,7 +1002,8 @@ sub _dispatch_state {
);
}
- # This session has stopped. Clean up after it.
+ # This session has stopped. Clean up after it. There's no
+ # garbage collection necessary since the session's stopped.
elsif ($type & ET_STOP) {
@@ -1174,9 +1137,8 @@ sub _dispatch_state {
# Remove the session's structure from the kernel's structure.
delete $sessions->{$session};
- # Check the parent to see if it's time to garbage collect. This
- # is here because POE::Kernel is sort of a session, and it has
- # no parent.
+ # See if the parent should leave, too.
+
if (defined $parent) {
{% collect_garbage $parent %}
}
@@ -1396,7 +1358,6 @@ sub run {
# seems to use them this way, though, not even the author.
foreach my $select (@selects) {
-
$self->_dispatch_state
( $select->[HSS_SESSION], $select->[HSS_SESSION],
$select->[HSS_STATE], ET_SELECT,
@@ -1422,14 +1383,10 @@ sub run {
)
};
- # Pull an alarm off the queue.
+ # Pull an alarm off the queue, and dispatch it.
my $event = shift @$kr_alarms;
{% ses_refcount_dec2 $event->[ST_SESSION], SS_ALCOUNT %}
-
- # Dispatch it, and see if that was the last thing the session
- # needed to do.
$self->_dispatch_state(@$event);
- {% collect_garbage $event->[ST_SESSION] %}
}
# Dispatch one or more FIFOs, if they are available. There is a
@@ -1448,14 +1405,10 @@ sub run {
)
};
- # Pull an event off the queue.
+ # Pull an event off the queue, and dispatch it.
my $event = shift @$kr_states;
{% ses_refcount_dec2 $event->[ST_SESSION], SS_EVCOUNT %}
-
- # Dispatch it, and see if that was the last thing the session
- # needed to do.
$self->_dispatch_state(@$event);
- {% collect_garbage $event->[ST_SESSION] %}
# If Time::HiRes isn't available, then the fairest thing to do
# is loop immediately.
@@ -1735,8 +1688,10 @@ sub _invoke_state {
# loop. Warn if it's something unexpected.
else {
- $SIG{CHLD} = \&_poe_signal_handler_child if exists $SIG{CHLD};
- $SIG{CLD} = \&_poe_signal_handler_child if exists $SIG{CLD};
+ unless (POE_HAS_EVENT) {
+ $SIG{CHLD} = \&_poe_signal_handler_child if exists $SIG{CHLD};
+ $SIG{CLD} = \&_poe_signal_handler_child if exists $SIG{CLD};
+ }
warn $! if $! and $! != ECHILD;
}
}
@@ -1744,8 +1699,10 @@ sub _invoke_state {
# Nothing is left to wait for. Stop the wait loop.
else {
- $SIG{CHLD} = \&_poe_signal_handler_child if exists $SIG{CHLD};
- $SIG{CLD} = \&_poe_signal_handler_child if exists $SIG{CLD};
+ unless (POE_HAS_EVENT) {
+ $SIG{CHLD} = \&_poe_signal_handler_child if exists $SIG{CHLD};
+ $SIG{CLD} = \&_poe_signal_handler_child if exists $SIG{CLD};
+ }
}
}
View
1 tests/02_alarms.t
@@ -10,7 +10,6 @@ use TestSetup;
&test_setup(14);
# Turn on all asserts.
-sub POE::Kernel::TRACE_DEFAULT () { 1 }
sub POE::Kernel::ASSERT_DEFAULT () { 1 }
use POE;
View
5 tests/09_wheels_unix.t
@@ -45,7 +45,7 @@ sub sss_start {
delete $heap->{wheel};
$heap->{wheel} = POE::Wheel::ReadWrite->new
( Handle => $socket,
- Driver => POE::Driver::SysRW->new( BlockSize => 1 ),
+ Driver => POE::Driver::SysRW->new( BlockSize => 10 ),
Filter => POE::Filter::Line->new(),
InputState => 'got_line',
ErrorState => 'got_error',
@@ -159,12 +159,11 @@ sub client_unix_connected {
delete $heap->{wheel};
$heap->{wheel} = POE::Wheel::ReadWrite->new
( Handle => $server_socket,
- Driver => POE::Driver::SysRW->new(),
+ Driver => POE::Driver::SysRW->new( BlockSize => 10 ),
Filter => POE::Filter::Line->new(),
InputState => 'got_line',
ErrorState => 'got_error',
FlushedState => 'got_flush',
- BlockSize => 1,
);
&ok_if(4, defined $heap->{wheel});
View
5 tests/10_wheels_tcp.t
@@ -45,7 +45,7 @@ sub sss_start {
delete $heap->{wheel};
$heap->{wheel} = POE::Wheel::ReadWrite->new
( Handle => $socket,
- Driver => POE::Driver::SysRW->new( BlockSize => 1 ),
+ Driver => POE::Driver::SysRW->new( BlockSize => 10 ),
Filter => POE::Filter::Line->new(),
InputState => 'got_line',
ErrorState => 'got_error',
@@ -109,12 +109,11 @@ sub client_tcp_connected {
delete $heap->{wheel};
$heap->{wheel} = POE::Wheel::ReadWrite->new
( Handle => $server_socket,
- Driver => POE::Driver::SysRW->new(),
+ Driver => POE::Driver::SysRW->new( BlockSize => 10 ),
Filter => POE::Filter::Line->new(),
InputState => 'got_line',
ErrorState => 'got_error',
FlushedState => 'got_flush',
- BlockSize => 1,
);
&ok_if(7, defined $heap->{wheel});
View
4 tests/11_signals_poe.t
@@ -13,6 +13,8 @@ use TestSetup;
sub POE::Kernel::ASSERT_DEFAULT () { 1 }
use POE;
+my $fork_count = 16;
+
# Use Time::HiRes, if it's available. This will get us super accurate
# sleep times so all the child processes wake up close together. The
# idea is to have CHLD signals overlap.
@@ -22,8 +24,6 @@ eval {
import Time::HiRes qw(time sleep);
};
-my $fork_count = 16;
-
# Set up a signal catching session. This test uses plain fork(2) and
# POE's $SIG{CHLD} handler.
View
6 tests/12_signals_ev.t
@@ -22,6 +22,8 @@ use POE;
&test_setup(2);
+my $fork_count = 16;
+
# Everything past here should be identical to 11_signals_poe.t
# Use Time::HiRes, if it's available. This will get us super accurate
@@ -33,8 +35,6 @@ eval {
import Time::HiRes qw(time sleep);
};
-my $fork_count = 16;
-
# Set up a signal catching session. This test uses plain fork(2) and
# POE's $SIG{CHLD} handler.
@@ -57,7 +57,7 @@ POE::Session->create
}
else {
sleep $wake_time - time();
- dump;
+ exit;
}
}
else {

0 comments on commit b5cccc0

Please sign in to comment.
Something went wrong with that request. Please try again.