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

Reply via email to