From: | Garrett Goebel <garrett [...] scriptpro.com> |
To: | Garrett Goebel <garrett [...] scriptpro.com>, 'Rocco Caputo' <troc [...] netrus.net>, poe [...] perl.org |
Cc: | bug-POE [...] rt.cpan.org |
Subject: | RE: Win32: WSA_OVERLAPPED_IO and non-blocking connect() |
Date: | Thu, 7 Nov 2002 15:47:38 -0600 |
Message body is not shown because sender requested not to inline it.
I think I've figured it out... a setsockopt call to change the SO_OPENTYPE
attribute to clear out any /SO_SYNC*/ values appears to work. At least my
simple tcp echo client now works under WinNT4.0sp6a, and I now pass test
10_wheels_tcp which had previously failed.
I've attached and inlined the patch for POE::Wheel::SocketFactory. Please
look it over.
As my patch appears to turn on the overlapped attributes for all successive
sockets... it might not be the optimal solution. But it works for me ;)
A better Win32 approach would probably be to:
o create a dummy socket
o cache the value of SO_OPENTYPE
o set the overlapped io attribute
o close dummy socket
o create our sock
o create a dummy socket
o restore previous value of SO_OPENTYPE
o close dummy socket
This way we'd only be turning on the overlap attribute for the socket we
created... and not all subsequent sockets.
--- SocketFactory.pm Thu Nov 07 14:57:27 2002
+++ SocketFactory.cgg Thu Nov 07 14:55:48 2002
@@ -38,7 +38,8 @@
# know you've broken his module.
# Provide dummy POSIX constants for systems that don't have them. Use
-# http://support.microsoft.com/support/kb/articles/Q150/5/37.asp for
+# http://msdn.microsoft.com/library/en-us/winsock/winsock/
+# windows_sockets_error_codes_2.asp
# the POSIX error numbers.
BEGIN {
if ($^O eq 'MSWin32') {
@@ -47,6 +48,19 @@
eval '*EWOULDBLOCK = sub { 10035 };';
eval '*F_GETFL = sub { 0 };';
eval '*F_SETFL = sub { 0 };';
+ eval '*SO_OPENTYPE = sub { 0x7008 };';
+ eval '*SO_SYNCHRONOUS_ALERT = sub { 0x10 };';
+ eval '*SO_SYNCHRONOUS_NONALERT = sub { 0x20 };';
+
+ # Turn on socket overlapped io attribute per MSKB: Q181611
+ eval <<'EOF';
+ socket(POE, AF_INET, SOCK_STREAM, getprotobyname('tcp'))
+ or die "socket failed: $!";
+ my $optval = unpack("I",getsockopt(POE, SOL_SOCKET, SO_OPENTYPE));
+ $optval &= ~(SO_SYNCHRONOUS_ALERT|SO_SYNCHRONOUS_NONALERT);
+ setsockopt(POE, SOL_SOCKET, SO_OPENTYPE, $optval);
+ close POE;
+EOF
}
unless (exists $INC{"Socket6.pm"}) {
@@ -394,7 +408,7 @@
my %params = @_;
- # The calling conventio experienced a hard deprecation.
+ # The calling convention experienced a hard deprecation.
croak "wheels no longer require a kernel reference as their first
parameter"
if (@_ && (ref($_[0]) eq 'POE::Kernel'));
--
Garrett Goebel
IS Development Specialist
ScriptPro Direct: 913.403.5261
5828 Reeds Road Main: 913.384.1008
Mission, KS 66202 Fax: 913.384.2180
www.scriptpro.com garrett@scriptpro.com
Show quoted text
> -----Original Message-----
> From: Garrett Goebel [mailto:garrett@scriptpro.com]
> Sent: Thursday, November 07, 2002 10:37 AM
> To: 'Rocco Caputo'; poe@perl.org
> Cc: bug-POE@rt.cpan.org
> Subject: RE: Win32: WSA_OVERLAPPED_IO and non-blocking connect()
>
>
> Nothing really new except more citations of potentially relevant
> documentation.
>
> New comments all the way at the bottom...
>
>
> From: Rocco Caputo [mailto:troc@netrus.net]
> the socket is
> > On Wed, Nov 06, 2002 at 05:08:48PM -0600, Garrett Goebel wrote:
> http://archive.develooper.com/perl5-porters@perl.org/msg62779.html
> > > Rocco,
> > >
> > > I apologize for my ignorance in advanced. I've started
> > > re-reading "Network Programming with Perl". -Which I'd
> > > read once long ago, never used, and consequently have
> > > completely forgotten.
> > >
> > > I noticed your post to p5p on this issue back in August 2001:
> > >
> > >
> > > Where you use ioctl to flip the socket to non-blocking mode
> > > (as stolen from POE::Wheel::SocketFactory).
> > >
> > > I also noticed an interesting article:
> > > INFO: Socket Overlapped I/O Versus Blocking/Non-blocking Mode
> > > http://support.microsoft.com/default.aspx?scid=kb;en-us;Q181611
> > >
> > > Where it says:
> >
> > It's an excellent lead and one I'll be pursuing once I get this NT
> > machine set up. You may be right about "pie in the sky". If
> > ActiveState is correct, the overlapped mode is required so that the
> > socket will behave like a filehandle in all other respects.
> >
> > It's a shame that overlapped mode can't be changed after
> > > > Please note that once a socket is created, there is no way
> > > > to change the socket overlapped attribute. However, you can
> > > > call the setsockopt API with SO_OPENTYPE option on any socket
> > > > handles including an INVALID_SOCKET to change the overlapped
> > > > attributes for all successive socket calls in the same thread.
> > > > The default SO_OPENTYPE option value is 0, which sets the
> > > > overlapped attribute. All non-zero option values make the
> > > > socket synchronous and make it so that you cannot use a
> > > > completion function
> > >
> > > So I'm wondering if there's an exposed mechanism in perl to set
> > > this attribute similar to how you used ioctl to set the FIONBIO
> > > attribute? I'm not sure what "all successive socket calls"
> > > means... but I'm curious if having set this attribute, followed
> > > by the FIONBIO call to ioctl... you might be able to get that
> > > non-blocking connect?
> > >
> > > Its probably just one of those "pie in the sky" ideas which
> > > ignorance allows one to think is possible...
> > created. Otherwise I could treat the socket as
> non-overlapped for the
> > duration of the connect and then set it back to overlapping for I/O.
> >
> > I'm probably going to release 0.24 before getting to work on the
> > Windows issues again, if only because 0.24 is practically
> ready to go
> > now.
> >
> > Cc'd to bug-POE@rt.cpan.org for posterity.
>
>
> It seems pretty clear that overlapped and non-blocking io should be
> orthogonal, but have been implemented otherwise... as MS Knowledgebook
> article Q181611 states:
>
> > The socket overlapped I/O attribute is different from the
> > socket's blocking or non-blocking mode. Although the current
> > Winsock implementation requires overlapped I/O attribute for
> > non-blocking socket mode, they are conceptually independent
> > and their programming model is different too.
>
>
> In Q189171, it indicates that this behaviour changed between
> Winsock 1.1 and
> Winsock 2.0, from a default of overlapped to non-overlapped.
> The other 2
> references in MSDN show overlapped as the default.
>
> "socket" topic in the Windows Sockets: Platform SDK:
> > The socket that is created will have the overlapped attribute
> > as a default. For Microsoft operating systems, the Microsoft-
> > specific socket option, SO_OPENTYPE, defined in Mswsock.h can
> > affect this default.
>
> Q131623:
> > By default, all socket handles are opened as overlapped
> > handles so that asynchronous I/O can be performed on them.
> > However, in many situations you may find it preferable to
> > have nonoverlapped (synchronous) socket handles.
> >
> > For example, only nonoverlapped handles can be used with the
> > C run-time libraries or used as standard I/O handles for a
> > process. Under Windows NT and Windows 95, the SO_OPENTYPE
> > socket option allows an application to open non-overlapped
> > socket handles.
>
>
> So I assume problems like:
>
> Q179942 INFO: WSA_FLAG_OVERLAPPED Is Needed For Non-Blocking Sockets
>
> Exist because the assumption that a socket would default to
> overlapped io
> has been violated when that behaviour was changed... Which is
> probably why
> there doesn't appear to be a way to change the socket
> overlapped attribute.
> Implementation details which assumed overlapped io, and so
> provided means to
> turn it off. But which don't necessary garrauntee the reverse.
>
> --
> Garrett Goebel
> IS Development Specialist
>
> ScriptPro Direct: 913.403.5261
> 5828 Reeds Road Main: 913.384.1008
> Mission, KS 66202 Fax: 913.384.2180
> www.scriptpro.com garrett@scriptpro.com
>
Message body is not shown because it is too large.