Permalink
Browse files

Clear out the event queue by session ID rather than reference.

I suspect this was causing defunct parent-process events to linger in
the child-process queue after POE::Kernel->stop() was called.  Their
dispatch in the child process may have caused the "hilarity" I have
seen in the wild.
  • Loading branch information...
1 parent 32f642c commit 965458107d2730428ecaf23b94ef29069cbf61a4 @rcaputo committed Mar 25, 2011
View
@@ -636,6 +636,12 @@ Filters. He greatly improved L<POE::Wheel::FollowTail|POE::Wheel::FollowTail>,
contributions include the basic Block filter, as well as Stackable,
RecordBlock, Grep and Map.
+=item Plixer International
+
+Plixer International is at L<http://plixer.com/>. Their sponsorship
+has helped POE 1.300 and beyond be significantly more robust using
+iThreads, especially when using fork() in Windows.
+
=item Robert Seifer
Robert Seifer is <e-mail unknown>. He rotates IRC nicknames
View
@@ -1757,7 +1757,7 @@ sub alarm {
return EINVAL;
}
- $self->_data_ev_clear_alarm_by_name($kr_active_session, $event_name);
+ $self->_data_ev_clear_alarm_by_name($kr_active_session->ID(), $event_name);
# Add the new alarm if it includes a time. Calling _data_ev_enqueue
# directly is faster than calling alarm_set to enqueue it.
@@ -1920,7 +1920,7 @@ sub alarm_remove {
}
my ($time, $event) =
- $self->_data_ev_clear_alarm_by_id($kr_active_session, $alarm_id);
+ $self->_data_ev_clear_alarm_by_id($kr_active_session->ID(), $alarm_id);
return unless defined $time;
# In a list context, return the alarm that was removed. In a scalar
@@ -2058,7 +2058,9 @@ sub alarm_remove_all {
# Free every alarm owned by the session. This code is ripped off
# from the _stop code to flush everything.
- my @removed = $self->_data_ev_clear_alarm_by_session($kr_active_session);
+ my @removed = $self->_data_ev_clear_alarm_by_session(
+ $kr_active_session->ID()
+ );
return unless defined wantarray;
return @removed if wantarray;
View
@@ -112,7 +112,7 @@ sub _data_ev_enqueue {
$self->_data_ses_refcount_inc($sid) unless $event_count{$sid}++;
- return $new_id if $session == $source_session;
+ return $new_id if $sid eq $source_session->ID();
$self->_data_ses_refcount_inc($source_session->ID) unless (
$post_count{$source_session->ID}++
@@ -124,18 +124,16 @@ sub _data_ev_enqueue {
### Remove events sent to or from a specific session.
sub _data_ev_clear_session {
- my ($self, $session) = @_;
-
- # TODO - Convert the event structure to SID too?
+ my ($self, $sid) = @_;
# Events sent to the session.
PENDING: {
- my $pending_count = $event_count{$session->ID};
+ my $pending_count = $event_count{$sid};
last PENDING unless $pending_count;
foreach (
$kr_queue->remove_items(
- sub { $_[0][EV_SESSION] == $session },
+ sub { $_[0][EV_SESSION]->ID() eq $sid },
$pending_count
)
) {
@@ -153,12 +151,12 @@ sub _data_ev_clear_session {
# Events sent by the session.
SENT: {
- my $sent_count = $post_count{$session->ID};
+ my $sent_count = $post_count{$sid};
last SENT unless $sent_count;
foreach (
$kr_queue->remove_items(
- sub { $_[0][EV_SOURCE] == $session },
+ sub { $_[0][EV_SOURCE]->ID() eq $sid },
$sent_count
)
) {
@@ -173,8 +171,8 @@ sub _data_ev_clear_session {
croak "lingering sent count: $sent_count" if $sent_count;
}
- croak "lingering event count" if delete $event_count{$session->ID};
- croak "lingering post count" if delete $post_count{$session->ID};
+ croak "lingering event count" if delete $event_count{$sid};
+ croak "lingering post count" if delete $post_count{$sid};
}
# TODO Alarm maintenance functions may move out to a separate
@@ -188,11 +186,11 @@ sub _data_ev_clear_session {
### future due times.
sub _data_ev_clear_alarm_by_name {
- my ($self, $session, $alarm_name) = @_;
+ my ($self, $sid, $alarm_name) = @_;
my $my_alarm = sub {
return 0 unless $_[0]->[EV_TYPE] & ET_ALARM;
- return 0 unless $_[0]->[EV_SESSION] == $session;
+ return 0 unless $_[0]->[EV_SESSION]->ID() eq $sid;
return 0 unless $_[0]->[EV_NAME] eq $alarm_name;
return 1;
};
@@ -207,10 +205,10 @@ sub _data_ev_clear_alarm_by_name {
### times. TODO It's possible to remove non-alarms; is that wrong?
sub _data_ev_clear_alarm_by_id {
- my ($self, $session, $alarm_id) = @_;
+ my ($self, $sid, $alarm_id) = @_;
my $my_alarm = sub {
- $_[0]->[EV_SESSION] == $session;
+ $_[0]->[EV_SESSION]->ID() eq $sid;
};
my ($time, $id, $event) = $kr_queue->remove_item($alarm_id, $my_alarm);
@@ -219,7 +217,7 @@ sub _data_ev_clear_alarm_by_id {
if (TRACE_EVENTS) {
_warn(
"<ev> removed event $id ``", $event->[EV_NAME], "'' to ",
- $self->_data_alias_loggable($session->ID), " at $time"
+ $self->_data_alias_loggable($sid), " at $time"
);
}
@@ -230,11 +228,11 @@ sub _data_ev_clear_alarm_by_id {
### Remove all the alarms for a session. Whoot!
sub _data_ev_clear_alarm_by_session {
- my ($self, $session) = @_;
+ my ($self, $sid) = @_;
my $my_alarm = sub {
return 0 unless $_[0]->[EV_TYPE] & ET_ALARM;
- return 0 unless $_[0]->[EV_SESSION] == $session;
+ return 0 unless $_[0]->[EV_SESSION]->ID() eq $sid;
return 1;
};
@@ -490,7 +490,10 @@ sub _data_handle_remove {
foreach ($kr_queue->remove_items($my_select)) {
my ($time, $id, $event) = @$_;
- $self->_data_ev_refcount_dec( @$event[EV_SESSION, EV_SOURCE] );
+ $self->_data_ev_refcount_dec(
+ $event->[EV_SOURCE]->ID(),
+ $event->[EV_SESSION]->ID(),
+ );
TRACE_EVENTS and _warn(
"<ev> removing select event $id ``$event->[EV_NAME]''" .
@@ -226,7 +226,7 @@ sub _data_ses_free {
$self->_data_extref_clear_session($sid); # Remove all leftover extrefs.
$self->_data_handle_clear_session($sid); # Remove all leftover handles.
- $self->_data_ev_clear_session($session); # Remove all leftover events.
+ $self->_data_ev_clear_session($sid); # Remove all leftover events.
# Remove the session itself.
@@ -118,7 +118,7 @@ check_references(
{ # Remove one of the alarms by its ID.
my ($time, $event) = $poe_kernel->_data_ev_clear_alarm_by_id(
- $poe_kernel, $ids[1]
+ $poe_kernel->ID(), $ids[1]
);
is($time, 2, "removed event has the expected due time");
@@ -136,7 +136,7 @@ check_references(
# did exist, except it doesn't.
my ($time, $event) = $poe_kernel->_data_ev_clear_alarm_by_id(
- $poe_kernel, 8675309
+ $poe_kernel->ID(), 8675309
);
ok(!defined($time), "can't clear bogus alarm by nonexistent ID");
@@ -166,7 +166,7 @@ is(
# Remove the alarm by name, for real. We should be down to one timer
# (the original poll thing).
-$poe_kernel->_data_ev_clear_alarm_by_name($poe_kernel, "timer");
+$poe_kernel->_data_ev_clear_alarm_by_name($poe_kernel->ID(), "timer");
check_references(
$poe_kernel, 0, 0, 1, "after removing 'timer' by name"
);
@@ -181,7 +181,7 @@ check_references(
{ # Remove the last of the timers. The Kernel session is the only
# reference left for it.
- my @removed = $poe_kernel->_data_ev_clear_alarm_by_session($poe_kernel);
+ my @removed = $poe_kernel->_data_ev_clear_alarm_by_session($poe_kernel->ID());
is(@removed, 1, "removed the last alarm successfully");
# Verify that the removed timer is the correct one. We still have
@@ -258,13 +258,13 @@ $poe_kernel->_data_ev_clear_session($poe_kernel);
$poe_kernel, 1, 1, 1, "after creating inter-session messages"
);
- $poe_kernel->_data_ev_clear_session($session);
+ $poe_kernel->_data_ev_clear_session($session->ID());
check_references(
$poe_kernel, 1, 0, 0, "after clearing inter-session messages"
);
- $poe_kernel->_data_ev_clear_session($poe_kernel);
+ $poe_kernel->_data_ev_clear_session($poe_kernel->ID());
check_references(
$poe_kernel, 1, 0, 0, "after clearing kernel messages"

0 comments on commit 9654581

Please sign in to comment.