Title: RE: Win32: WSA_OVERLAPPED_IO and non-blocking connect()

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          [EMAIL PROTECTED]



> -----Original Message-----
> From: Garrett Goebel [mailto:[EMAIL PROTECTED]]
> Sent: Thursday, November 07, 2002 10:37 AM
> To: 'Rocco Caputo'; [EMAIL PROTECTED]
> Cc: [EMAIL PROTECTED]
> 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:[EMAIL PROTECTED]]
> > On Wed, Nov 06, 2002 at 05:08:48PM -0600, Garrett Goebel wrote:
> > > 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:
> > >  
> http:[EMAIL PROTECTED]/msg62779.html
> > >
> > > 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:
> > > > 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...
> >
> > 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
> the socket is
> > 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 [EMAIL PROTECTED] 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          [EMAIL PROTECTED]
>

 

Attachment: SF.patch
Description: Binary data

Reply via email to