Skip Menu |

This queue is for tickets about the POE CPAN distribution.

Report information
The Basics
Id: 28136
Status: rejected
Priority: 0/
Queue: POE

People
Owner: Nobody in particular
Requestors: yshtil [...] cisco.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: Suggested change in POE/Resource/FileHandles.pm
Date: Thu, 12 Jul 2007 10:59:21 -0700
To: rcaputo [...] cpan.org
From: Yuri Shtil <yshtil [...] cisco.com>
Hi Rocco, I attached a suggested change to the file. The reason is that the existing code keeps track of the file handles in hash keyed by the globs . The resultant key is a stringified reference like GLOB(0x91615e4). In my case I used POE::Component::Server::TCP to hook HTTP::Daemon on a connection. I blessed the socket from the client wheel to HTTP::Daemon which is a subclass of Socket so everything worked fine. However when the connection and the session was gone, the socket was stuck because the object reference changed. My change consists of using the object address as the key since it will not change when the object is re-blessed. Please let me know if my solution is acceptable. -- Yuri Shtil --- POE/Resource/FileHandles.pm Thu Jul 12 10:40:13 2007 +++ POE_PATCHED/Resource/FileHandles.pm Thu Jul 12 10:37:57 2007 @@ -272,8 +272,17 @@ sub _data_handle_is_good { ### Add a select to the session, and possibly begin a watcher. +sub _deglob { + my ($h) = @_; + + $h =~ m!GLOB\(([^)]+)!; + $1; +} + sub _data_handle_add { my ($self, $handle, $mode, $session, $event) = @_; + my $handleref = _deglob($handle); + my $fd = fileno($handle); # First time watching the file descriptor. Do some heavy setup. @@ -366,7 +375,7 @@ sub _data_handle_add { # The session is also watching it by the same handle. Treat this # as a "resume" in this mode. - if (exists $kr_fno_rec->[FMO_SESSIONS]->{$session}->{$handle}) { + if (exists $kr_fno_rec->[FMO_SESSIONS]->{$session}->{$handleref}) { if (TRACE_FILES) { _warn( "<fh> running fileno($fd) mode($mode) " . @@ -415,7 +424,7 @@ sub _data_handle_add { # the session/handle pair. else { - $kr_fno_rec->[FMO_SESSIONS]->{$session}->{$handle} = + $kr_fno_rec->[FMO_SESSIONS]->{$session}->{$handleref} = [ $handle, # HSS_HANDLE $session, # HSS_SESSION $event, # HSS_STATE @@ -438,8 +447,8 @@ sub _data_handle_add { # If the session hasn't already been watching the filehandle, then # register the filehandle in the session's structure. - unless (exists $kr_ses_to_handle{$session}->{$handle}) { - $kr_ses_to_handle{$session}->{$handle} = + unless (exists $kr_ses_to_handle{$session}->{$handleref}) { + $kr_ses_to_handle{$session}->{$handleref} = [ $handle, # SH_HANDLE 0, # SH_REFCOUNT [ 0, # SH_MODECOUNT / MODE_RD @@ -453,7 +462,7 @@ sub _data_handle_add { # Modify the session's handle structure's reference counts, so the # session knows it has a reason to live. - my $ss_handle = $kr_ses_to_handle{$session}->{$handle}; + my $ss_handle = $kr_ses_to_handle{$session}->{$handleref}; unless ($ss_handle->[SH_MODECOUNT]->[$mode]) { $ss_handle->[SH_MODECOUNT]->[$mode]++; $ss_handle->[SH_REFCOUNT]++; @@ -465,6 +474,8 @@ sub _data_handle_add { sub _data_handle_remove { my ($self, $handle, $mode, $session) = @_; + my $handleref = _deglob($handle); + my $fd = fileno($handle); # Make sure the handle is deregistered with the kernel. @@ -477,7 +488,7 @@ sub _data_handle_remove { if ( exists($kr_fno_rec->[FMO_SESSIONS]->{$session}) and - exists($kr_fno_rec->[FMO_SESSIONS]->{$session}->{$handle}) + exists($kr_fno_rec->[FMO_SESSIONS]->{$session}->{$handleref}) ) { TRACE_FILES and @@ -486,7 +497,7 @@ sub _data_handle_remove { # Remove the handle from the kernel's session record. my $handle_rec = - delete $kr_fno_rec->[FMO_SESSIONS]->{$session}->{$handle}; + delete $kr_fno_rec->[FMO_SESSIONS]->{$session}->{$handleref}; my $kill_session = $handle_rec->[HSS_SESSION]; my $kill_event = $handle_rec->[HSS_STATE]; @@ -584,12 +595,12 @@ sub _data_handle_remove { if ( exists($kr_ses_to_handle{$session}) and - exists($kr_ses_to_handle{$session}->{$handle}) + exists($kr_ses_to_handle{$session}->{$handleref}) ) { # Remove it from the session's read, write or expedite mode. - my $ss_handle = $kr_ses_to_handle{$session}->{$handle}; + my $ss_handle = $kr_ses_to_handle{$session}->{$handleref}; if ($ss_handle->[SH_MODECOUNT]->[$mode]) { # Hmm... what is this? Was POE going to support multiple selects? @@ -606,7 +617,7 @@ sub _data_handle_remove { } unless ($ss_handle->[SH_REFCOUNT]) { - delete $kr_ses_to_handle{$session}->{$handle}; + delete $kr_ses_to_handle{$session}->{$handleref}; $self->_data_ses_refcount_dec($session); delete $kr_ses_to_handle{$session} unless keys %{$kr_ses_to_handle{$session}};
Hi, Yuri. It just occurred to me that we might want to track filehandles by fileno() internally rather than GLOB string or object address. The object could change entirely, address and all, but the fileno() should remain constant. What do you think? -- Rocco On Thu Jul 12 16:23:53 2007, yshtil@cisco.com wrote: Show quoted text
> Hi Rocco, > > I attached a suggested change to the file. > The reason is that the existing code keeps track of the file handles > in hash keyed by the globs . The resultant key is a stringified > reference like GLOB(0x91615e4). > In my case I used POE::Component::Server::TCP to hook HTTP::Daemon on > a connection. I blessed the socket from the client wheel to > HTTP::Daemon which is a subclass of Socket so everything worked fine. > However when the connection and the session was gone, the socket was > stuck because the object reference changed. > > My change consists of using the object address as the key since it > will not change when the object is re-blessed. > > Please let me know if my solution is acceptable. >
No followup from reporter.