On Wed, Aug 18, 2004 at 02:09:53PM -0700, Stas Bekman wrote: > Glenn Strauss wrote: > >On Wed, Aug 18, 2004 at 12:59:51PM -0700, Ken Simpson wrote: > > > >>>the APR::Socket object is an opaque one, so it can't interoperate with > >>>any other perl modules. Have you looked if there is some C api to get > >>>the native socket object? There could be one (as they have for file > >>>objects), I didn't check. > >> > >>I looked through apr_network_io.h, which seemed like the logical > >>place, and couldn't find an API that returns the native socket > >>object. But I'm pretty unfamiliar with the Apache code base, so > >>someone else would probably have better luck. > > > > > >This is what we'd need bound to the Perl API: > > > >apr_os_sock_t fd; > >apr_os_sock_get((apr_os_sock_t *) &fd, (apr_socket_t *) client_socket); > > > >On Unix-type platforms, apr_os_sock_t is an int -- the file descriptor, > >which you can use with select() or IO::Select() or anything you > >like in Perl to poll the descriptor: > > and what do you do with socket fd to get it to work with IO::Select? > > >$rin = ''; > >vec($rin, $fd) = 1; ## $fd directly instead of fileno(STDIN) or > >fileno($FH) > >... > >$nfound = select($rout=$rin, undef, undef, $timeout); > > > > > >(On other platforms, like Windows, I don't know what apr_os_sock_t is; > > check the headers files. :) > > I'd rather not expose OS specific bits if they won't work with all perl > modules. APR provides the API that should (hopefully) work on all > platforms, so why not use that? > > >To get the client socket for a connection, you can obtain the > >(apr_socket_t *) with the incantation: > > > >apr_socket_t *client_socket = > > ap_get_module_config(r->connection->conn_config, &core_module); > > > >and then use apr_os_sock_get() to get the fd. > > Yup, we already have that one. > >
Currently we use the following hacky solution to make the fd work with IO::Select and Core::select use constant MAGIC_FILENO => 7; use ex::override GLOBAL_select => sub { if (@_ == 1) { my $sh = shift; unless (ref($sh)) { my $caller = caller(); $sh = \*{$caller .'::'. $sh}; } return CORE::select(); } elsif (@_ == 4) { my $rin = vec($_[0],MAGIC_FILENO,1) if $_[0]; my $win = vec($_[1],MAGIC_FILENO,1) if $_[1]; my $ein = vec($_[2],MAGIC_FILENO,1) if $_[2]; if ($rin or $win or $ein) { #magic fileno do something special #should poll the socket for data here, #but that doesn't work yet, so fake it return wantarray ? (1,$_[3]) : 1; } else { return CORE::select($_[0],$_[1],$_[2],$_[3]); } } else { die "WTF ?"; } }; In the latest incarnation of TieBucketBrigade we do the following sub FILENO { #returns magic fileno which select and fdopen will do something special with shift; return MAGIC_FILENO; } Provided you don't need fd 7 anywhere else, this should work. Ideally we should get the real fd and use it instead. So all we need to make IO::Select, select and everything else work, is the ability to poll for data on the socket, which we'll just stick in the overridden select at the appropriate point above. mock -- Report problems: http://perl.apache.org/bugs/ Mail list info: http://perl.apache.org/maillist/modperl.html List etiquette: http://perl.apache.org/maillist/email-etiquette.html