<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 12pt;
font-family:Calibri
}
--></style></head>
<body class='hmmessage'><div dir='ltr'>Realize that the socket API is almost identical<br>on Win32 and Posix. And the Modula-3 libraries<br>are therefore almost identical -- unfortunately duplicated..<br><br><br>SocketPosix.m3:<br><br><br>PROCEDURE InitStream (fd: CARDINAL)<br>  RAISES {OSError.E} =<br>  (* We assume that the runtime ignores SIGPIPE signals *)<br>  VAR<br>    one : int := 1;<br>    linger := struct_linger{1, 1};<br>  BEGIN<br>    EVAL setsockopt(fd, SOL_SOCKET, SO_LINGER,<br>                    ADR(linger), BYTESIZE(linger));<br>    EVAL setsockopt(fd, IPPROTO_TCP, TCP_NODELAY,<br>                    ADR(one), BYTESIZE(one));<br><br>    MakeNonBlocking (fd);<br>  END InitStream;<br><br><br>PROCEDURE MakeNonBlocking (fd: INTEGER)<br>  RAISES {OSError.E} =<br>  VAR<br>    old_mode := fcntl (fd, F_GETFL, 0);<br>    new_mode := Word.Or (old_mode, M3_NONBLOCK);  <br>  BEGIN<br>    IF fcntl (fd, F_SETFL, new_mode) = -1 THEN<br>      IOError (Unexpected);<br>    END;<br>  END MakeNonBlocking;<br><br><br>SocketWin32.m3<br>PROCEDURE InitSock (sock: SOCKET) =<br>  (* We assume that the runtime ignores SIGPIPE signals *)<br>  VAR<br>    one: int := 1;<br>    linger := struct_linger{0, 0};<br>  BEGIN<br>    EVAL setsockopt (sock, SOL_SOCKET, SO_LINGER,<br>                     ADR(linger), BYTESIZE(linger));<br><br>    (**** WinSock documentation warns that this may cause problems<br>    ****)<br>    EVAL setsockopt (sock, IPPROTO_TCP, TCP_NODELAY,<br>                     ADR(one), BYTESIZE(one));<br>  END InitSock;<br><br><br><br>The meaning of struct_linger is the SAME on Posix and Win32.<br>The fact that Modula-3 passes "opposite" parameters is clearly broken.<br><br><br><br>so, obvious questions:<br>  Do we need either setsockopt?<br>  Clearly if we use SO_LINGER, we should use the same parameters.<br>  TCP_NODELAY seems to be generally discouraged. But it seems to<br>  usually have a real meaning, and removing it here would break things?<br>  In particular, it, like, turns off buffering. It means if you do<br>  write with just one byte, it will be sent immediately. If that is<br>  the "last" byte for a "while", ok. If you are making a series of<br>  small writes, it pays very much to coalesce them into fewer larger writes,<br>  at the cost of delaying the earlier writes.<br>  <br><br>Here is an example of implicity discouraging it:<br><br><br>http://smalltalk.gnu.org/project/issue/119<br><br>"The tcp delay, aka. nagles algorithm has it's applications and disabling<br>it should be done only in special applications (eg. where low-latency for is required) IMO.<br>"<br><br><br>Doing this unconditionally for all sockets seems wrong.<br><br><br><br>On the other hand:<br>http://en.wikipedia.org/wiki/Nagle%27s_algorithm<br><br><br>paraphrasing part of it: As long as the application does not issue small writes, it is ok.<br><br><br>At least this part we do the same for Posix and Win32.<br><br><br><br> - Jay<br><br><br>                                           </div></body>
</html>