You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Ken Simpson <ks...@larch.mailchannels.com> on 2004/08/18 01:37:53 UTC

How to tell if there's data waiting on a NON-blocking Apache connection?

Oops -- the subject line was wrong last time. Let's try again:

If all I have is an Apache::Connection object, is there a way to tell
whether data is available from the connection's socket in the case
where the connection has been put into nonblocking mode.

Thanks,
Ken

-- 
MailChannels: Control Your Email
http://www.mailchannels.com

Ken Simpson, CEO
+1-604-729-1741

-- 
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


Re: How to tell if there's data waiting on a NON-blocking Apache connection?

Posted by Stas Bekman <st...@stason.org>.
Glenn Strauss wrote:
[...]
>>So do you think it's easier to just get this sock_get thing crossplatform 
>>and then just use perl modules to manipulate the socket object? Or is it 
>>better to expose apr_poll(set)?_.* interface? I prefer the later, as we 
>>won't need to deal with crossplatform issues, leaving those to the letter 
>>P in APR.
> 
> 
> Sure, give me ever-evolving (for the better!) APIs that hide
> low level primitives, but please also always give me access to
> the low level primitives so that I can get the job done when
> the higher level APIs do not meet my needs/map to my paradigm.
> TIMTOWTDI. :)

You know that "give me" doesn't work well in the open source env. In other 
words patches are always welcome :)

-- 
__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com

-- 
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


Re: How to tell if there's data waiting on a NON-blocking Apache connection?

Posted by Glenn Strauss <gs...@gluelogic.com>.
On Wed, Aug 18, 2004 at 09:27:57PM -0700, Stas Bekman wrote:
> Glenn Strauss wrote:
> >The Socket.Handle property is what I think is needed so that
> >APR::OS::sock_get() can be made to work on Windows, too.
> >mpxs_APR__OS_sock_get() will need to special-case Windows platforms
> >and pull the Handle property.  I hope that works.  Any Windows
> >programmers out there?
> 
> and I suppose IntPtr is an integer pointer?
> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemintptrclasstopic.asp
> but it can't be really casted with (int) as it can be longer than 
> sizeof(int).

Theoretically, yes.  But we're talking about file descriptors in this
case, and that's a lot of open files.  Does any operating system out
there support 2 GB open file descriptors?

Casting to int shouldn't be a problem in current practice, though I'm
not a Windows developer, so take that with some sea salt (large grains;
great for Margaritas).


> and if it was the case, why didn't apr provid such a call?

Any APR developers listening?

APR hasn't reached version 1.0 yet (though it is frozen for its
upcoming release); it has come a long way and is constantly improving.

> So do you think it's easier to just get this sock_get thing crossplatform 
> and then just use perl modules to manipulate the socket object? Or is it 
> better to expose apr_poll(set)?_.* interface? I prefer the later, as we 
> won't need to deal with crossplatform issues, leaving those to the letter 
> P in APR.

Sure, give me ever-evolving (for the better!) APIs that hide
low level primitives, but please also always give me access to
the low level primitives so that I can get the job done when
the higher level APIs do not meet my needs/map to my paradigm.
TIMTOWTDI. :)

Cheers,
Glenn

-- 
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


Re: How to tell if there's data waiting on a NON-blocking Apache connection?

Posted by Stas Bekman <st...@stason.org>.
Glenn Strauss wrote:
[...]
>>>>>(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?
>>>
>>>
>>>I'm not a Windows programmer, but in the case of sockets, it looks like
>>>it might be an int (file descriptor) on Windows, too.  We're talking
>>>Berkeley sockets on both platforms, right?  Whatever socket() returns.
> 
> 
> I was wrong.  apr_os_sock_t is a (SOCKET) on Win32, not an (int).
> 
> 
>>why then APR went through the pain of abstracting this interface?
> 
> 
> Turns out to be the obvious answer: because Windows does it differently
> from everyone else.  Whether that is better or worse depends on the
> situation, but the pain in writing cross-platform code still riles me,
> not to mention how many 10's of clicks (hundreds?) it took me to navigate
> the MSDN morass of documentation to find the following:
> 
> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemNetSocketsSocketPropertiesTopic.asp
> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemnetsocketssocketclasshandletopic.asp
> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemintptrclasstopic.asp
> 
> The Socket.Handle property is what I think is needed so that
> APR::OS::sock_get() can be made to work on Windows, too.
> mpxs_APR__OS_sock_get() will need to special-case Windows platforms
> and pull the Handle property.  I hope that works.  Any Windows
> programmers out there?

and I suppose IntPtr is an integer pointer?
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemintptrclasstopic.asp
but it can't be really casted with (int) as it can be longer than 
sizeof(int). and if it was the case, why didn't apr provid such a call?

So do you think it's easier to just get this sock_get thing crossplatform 
and then just use perl modules to manipulate the socket object? Or is it 
better to expose apr_poll(set)?_.* interface? I prefer the later, as we 
won't need to deal with crossplatform issues, leaving those to the letter 
P in APR.

-- 
__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com

-- 
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


Re: How to tell if there's data waiting on a NON-blocking Apache connection?

Posted by Glenn Strauss <gs...@gluelogic.com>.
On Wed, Aug 18, 2004 at 02:51:06PM -0700, Stas Bekman wrote:
> Glenn Strauss wrote:
> >>>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?
> >
> >
> >Perl's equivalent of fdopen():
> >  open($FH, "<&=$fd")
> >and then use $FH
> 
> I guess that could work.
> 
> but I'm not sure how could we write a perl glue for apr_os_sock_get. How 
> will you handle apr_os_sock_t? You can't force it into int, can you?
> 
> >>>$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?
> >
> >
> >I'm not a Windows programmer, but in the case of sockets, it looks like
> >it might be an int (file descriptor) on Windows, too.  We're talking
> >Berkeley sockets on both platforms, right?  Whatever socket() returns.

I was wrong.  apr_os_sock_t is a (SOCKET) on Win32, not an (int).

> why then APR went through the pain of abstracting this interface?

Turns out to be the obvious answer: because Windows does it differently
from everyone else.  Whether that is better or worse depends on the
situation, but the pain in writing cross-platform code still riles me,
not to mention how many 10's of clicks (hundreds?) it took me to navigate
the MSDN morass of documentation to find the following:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemNetSocketsSocketPropertiesTopic.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemnetsocketssocketclasshandletopic.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemintptrclasstopic.asp

The Socket.Handle property is what I think is needed so that
APR::OS::sock_get() can be made to work on Windows, too.
mpxs_APR__OS_sock_get() will need to special-case Windows platforms
and pull the Handle property.  I hope that works.  Any Windows
programmers out there?


Cheers,
Glenn

-- 
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


Re: How to tell if there's data waiting on a NON-blocking Apache connection?

Posted by Stas Bekman <st...@stason.org>.
Glenn Strauss wrote:
> 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?
> 
> 
> Perl's equivalent of fdopen():
>   open($FH, "<&=$fd")
> and then use $FH

I guess that could work.

but I'm not sure how could we write a perl glue for apr_os_sock_get. How 
will you handle apr_os_sock_t? You can't force it into int, can you?

>>>$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?
> 
> 
> I'm not a Windows programmer, but in the case of sockets, it looks like
> it might be an int (file descriptor) on Windows, too.  We're talking
> Berkeley sockets on both platforms, right?  Whatever socket() returns.

why then APR went through the pain of abstracting this interface?

> While, you're right that this is better hidden by APR, don't let
> cross-platform concerns entirely prevent you from getting the job done. :)

no objections here. But as I understood Ken is working on a common module, 
which should work everywhere.

-- 
__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com

-- 
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


Re: How to tell if there's data waiting on a NON-blocking Apache connection?

Posted by Glenn Strauss <gs...@gluelogic.com>.
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?

Perl's equivalent of fdopen():
  open($FH, "<&=$fd")
and then use $FH

> >$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?

I'm not a Windows programmer, but in the case of sockets, it looks like
it might be an int (file descriptor) on Windows, too.  We're talking
Berkeley sockets on both platforms, right?  Whatever socket() returns.

While, you're right that this is better hidden by APR, don't let
cross-platform concerns entirely prevent you from getting the job done. :)

Cheers,
Glenn

-- 
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


Re: How to tell if there's data waiting on a NON-blocking Apache connection?

Posted by mock <mo...@obscurity.org>.
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


Re: How to tell if there's data waiting on a NON-blocking Apache connection?

Posted by Stas Bekman <st...@stason.org>.
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.


-- 
__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com

-- 
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


Re: How to tell if there's data waiting on a NON-blocking Apache connection?

Posted by Ken Simpson <ks...@larch.mailchannels.com>.
> >Right on -- that would give us _everything_ we need.
> 
> but it'll work only on unix, isn't it?

Yes -- that's right. It would be a unix-only solution.
A more universal solution would be preferred -- i.e. supporting
the APR::Poll interface.

TTUL
Ken

-- 
MailChannels: Control Your Email
http://www.mailchannels.com

Ken Simpson, CEO
+1-604-729-1741

-- 
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


Re: How to tell if there's data waiting on a NON-blocking Apache connection?

Posted by Stas Bekman <st...@stason.org>.
Ken Simpson wrote:
>>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:
> 
> 
> Right on -- that would give us _everything_ we need.

but it'll work only on unix, isn't it?

>>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.
> 
> 
> What would this incantation look like in Perl-land?

use Apache::Connection;
$sock = $c->client_socket;
http://perl.apache.org/docs/2.0/api/Apache/Connection.html#C_client_socket_


-- 
__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com

-- 
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


Re: How to tell if there's data waiting on a NON-blocking Apache connection?

Posted by Ken Simpson <ks...@larch.mailchannels.com>.
> 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:

Right on -- that would give us _everything_ we need.

> 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.

What would this incantation look like in Perl-land?

TTUL
Ken

-- 
MailChannels: Control Your Email
http://www.mailchannels.com

Ken Simpson, CEO
+1-604-729-1741

-- 
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


Re: How to tell if there's data waiting on a NON-blocking Apache connection?

Posted by Stas Bekman <st...@stason.org>.
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);

ok, I've looked at APR::Poll and it'll require time to expose it, which I 
don't have at the moment. So you can try to do it yourselves or remind us 
to do that later (probably after 2.0 release).

Meanwhile, the following patch (against the current cvs) will give you the 
fd as Glenn has suggested, you'd use it as:

use APR::OS ();
my $fd = APR::OS::sock_get($c->client_socket);
warn "got: socket fd $fd\n";

Most likely this won't become part of the API for the reasons discussed so 
far in this thread (portability), but it should get you going for now.

Index: xs/APR/OS/APR__OS.h
===================================================================
RCS file: /home/cvs/modperl-2.0/xs/APR/OS/APR__OS.h,v
retrieving revision 1.3
diff -u -r1.3 APR__OS.h
--- xs/APR/OS/APR__OS.h	4 Mar 2004 06:01:09 -0000	1.3
+++ xs/APR/OS/APR__OS.h	18 Aug 2004 23:28:27 -0000
@@ -21,3 +21,12 @@
      return 0;
  #endif
  }
+
+static MP_INLINE int mpxs_APR__OS_sock_get(pTHX_ apr_socket_t *socket)
+{
+    apr_os_sock_t fd;
+    MP_RUN_CROAK(apr_os_sock_get(&fd, socket),
+                 "APR::OS::sock_get");
+
+    return (int)fd;
+}
Index: xs/maps/apr_functions.map
===================================================================
RCS file: /home/cvs/modperl-2.0/xs/maps/apr_functions.map,v
retrieving revision 1.83
diff -u -r1.83 apr_functions.map
--- xs/maps/apr_functions.map	15 Jul 2004 06:23:21 -0000	1.83
+++ xs/maps/apr_functions.map	18 Aug 2004 23:28:27 -0000
@@ -613,7 +613,8 @@
  -apr_os_exp_time_get
  -apr_os_file_get
  -apr_os_imp_time_get
--apr_os_sock_get
+~apr_os_sock_get
+ mpxs_APR__OS_sock_get
  -apr_os_thread_get
  -apr_os_threadkey_get
  -apr_os_sock_make
Index: xs/tables/current/ModPerl/FunctionTable.pm
===================================================================
RCS file: /home/cvs/modperl-2.0/xs/tables/current/ModPerl/FunctionTable.pm,v
retrieving revision 1.173
diff -u -r1.173 FunctionTable.pm
--- xs/tables/current/ModPerl/FunctionTable.pm	16 Jul 2004 01:10:46 -0000 
1.173
+++ xs/tables/current/ModPerl/FunctionTable.pm	18 Aug 2004 23:28:27 -0000
@@ -2,7 +2,7 @@

  # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  # ! WARNING: generated by ModPerl::ParseSource/0.01
-# !          Thu Jul 15 16:55:01 2004
+# !          Wed Aug 18 16:07:19 2004
  # !          do NOT edit, any changes will be lost !
  # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

@@ -1799,6 +1799,24 @@
      ]
    },
    {
+    'return_type' => 'void',
+    'name' => 'modperl_errsv_prepend',
+    'args' => [
+      {
+        'type' => 'PerlInterpreter *',
+        'name' => 'my_perl'
+      },
+      {
+        'type' => 'const char *',
+        'name' => 'pat'
+      },
+      {
+        'type' => '...',
+        'name' => 'arg2'
+      }
+    ]
+  },
+  {
      'return_type' => 'char *',
      'name' => 'modperl_file2package',
      'args' => [
@@ -5466,6 +5484,24 @@
        {
          'type' => 'apr_pool_t *',
          'name' => 'p'
+      }
+    ]
+  },
+  {
+    'return_type' => 'int',
+    'name' => 'mpxs_APR__OS_sock_get',
+    'attr' => [
+      'static',
+      '__inline__'
+    ],
+    'args' => [
+      {
+        'type' => 'PerlInterpreter *',
+        'name' => 'my_perl'
+      },
+      {
+        'type' => 'apr_socket_t *',
+        'name' => 'socket'
        }
      ]
    },


-- 
__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com

-- 
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


Re: How to tell if there's data waiting on a NON-blocking Apache connection?

Posted by Glenn Strauss <gs...@gluelogic.com>.
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:

$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. :)


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.


Cheers,
Glenn

-- 
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


Re: How to tell if there's data waiting on a NON-blocking Apache connection?

Posted by Ken Simpson <ks...@larch.mailchannels.com>.
> 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.

> >How much work is it to write the mappings for APR::Poll? I've never
> >done it before but.. well we could give it a shot!
> 
> What C functions do you need to be exposed? it should be really quick if 
> it can be exposed as is, without needing to write a special glue code...

The polling interface can poll files or sockets. For our application,
all we care about is sockets, but perhaps for completeness the
implementation should allow polling of files too.

These methods would need to be exposed to Perl:

 apr_pollset_create  -- Create a set of things to poll.
 apr_pollset_add     -- Add something to a set.
 apr_pollset_remove  -- Remove something from a set.
 apr_pollset_poll    -- Poll the set in a particular way.
 apr_pollset_destroy -- Destroy the set.

We would also need to a way of filling in the apr_pollfd_t type
(i.e. polling file descriptor):

  struct apr_pollfd_t {
     apr_pool_t *p;              /**< associated pool */
     apr_datatype_e desc_type;   /**< descriptor type */
     apr_int16_t reqevents;      /**< requested events */
     apr_int16_t rtnevents;      /**< returned events */
     apr_descriptor desc;        /**< @see apr_descriptor */
     void *client_data;          /**< allows app to associate context */
  };

The desc field is a union that either contains a pointer to a socket
or a file (apr_file_t or apr_socket_t -- take your pick). The
client_data field is just a handy storage box for arbitrary data you
might want to use when you poll your file or socket.

And we'd also need this enum exposed as constants:

 typedef enum { 
     APR_NO_DESC,                /**< nothing here */
     APR_POLL_SOCKET,            /**< descriptor refers to a socket */
     APR_POLL_FILE,              /**< descriptor refers to a file */
     APR_POLL_LASTDESC           /**< descriptor is the last one in the list */
 } apr_datatype_e ;

And of course some other #defines.

TTUL
Ken

-- 
MailChannels: Control Your Email
http://www.mailchannels.com

Ken Simpson, CEO
+1-604-729-1741

-- 
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


Re: How to tell if there's data waiting on a NON-blocking Apache connection?

Posted by Stas Bekman <st...@stason.org>.
Ken Simpson wrote:
>>$c->client_socket gives you the socket object, now I suppose you want to 
>>poll() it for read. Unfortunately we haven't exposed APR::Poll yet. Take a 
>>look at the C API:
>>
>>http://lxr.webperf.org/source.cgi/srclib/apr/include/apr_poll.h
>>http://docx.webperf.org/apr__poll_8h.html
>>http://docx.webperf.org/group__apr__poll.html
>>
>>Is that what you are after?
> 
> 
> Yes, this is exactly what we need. Ideally, the APR interface should
> support the operations supported by IO::Select -- but it appears to.

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.

> How much work is it to write the mappings for APR::Poll? I've never
> done it before but.. well we could give it a shot!

What C functions do you need to be exposed? it should be really quick if 
it can be exposed as is, without needing to write a special glue code...

-- 
__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com

-- 
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


Re: How to tell if there's data waiting on a NON-blocking Apache connection?

Posted by Ken Simpson <ks...@larch.mailchannels.com>.
> $c->client_socket gives you the socket object, now I suppose you want to 
> poll() it for read. Unfortunately we haven't exposed APR::Poll yet. Take a 
> look at the C API:
> 
> http://lxr.webperf.org/source.cgi/srclib/apr/include/apr_poll.h
> http://docx.webperf.org/apr__poll_8h.html
> http://docx.webperf.org/group__apr__poll.html
> 
> Is that what you are after?

Yes, this is exactly what we need. Ideally, the APR interface should
support the operations supported by IO::Select -- but it appears to.

How much work is it to write the mappings for APR::Poll? I've never
done it before but.. well we could give it a shot!

TTUL
Ken

-- 
MailChannels: Control Your Email
http://www.mailchannels.com

Ken Simpson, CEO
+1-604-729-1741

-- 
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


Re: How to tell if there's data waiting on a NON-blocking Apache connection?

Posted by Stas Bekman <st...@stason.org>.
Ken Simpson wrote:
> Oops -- the subject line was wrong last time. Let's try again:
> 
> If all I have is an Apache::Connection object, is there a way to tell
> whether data is available from the connection's socket in the case
> where the connection has been put into nonblocking mode.

$c->client_socket gives you the socket object, now I suppose you want to 
poll() it for read. Unfortunately we haven't exposed APR::Poll yet. Take a 
look at the C API:

http://lxr.webperf.org/source.cgi/srclib/apr/include/apr_poll.h
http://docx.webperf.org/apr__poll_8h.html
http://docx.webperf.org/group__apr__poll.html

Is that what you are after?

-- 
__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com

-- 
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