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