[Vm-dev] [OpenSmalltalk/opensmalltalk-vm] Unix(macOS) SocketPlugin: (7deac02)

Eliot Miranda notifications at github.com
Fri Oct 9 07:28:52 UTC 2020


Tobias,  you need to read the code to see why we can't ditch aioPoll.  Perhaps we could ditch the select call in socketWritable, but we would need to test on all platforms.  However, here's how you can see that select does indeed answer 0 for a writable socket on macOS (I'm using 10.13.6).

1. compile a debug VM using the version immediately before this commit, making sure the build supplies -DAIO_DEBUG.
2. run with logging turned on, e.g.
    $ ../build.macos64x64/squeak.cog.spur/SqueakDebug.app/Contents/MacOS/Squeak -aiolog trunk6-64.image
3. run the following in a workspace
```	| tcpSend tcpRecv sendProc recvProc  |
	[
		|  address port opt send1 recv2 sent |
		address := NetNameResolver addressForName: '127.0.0.1' timeout: 20.
		port := 31259.
		tcpSend := Socket newTCP.
		tcpSend setOption: 'SO_REUSEADDR' value: 1.
		self assert: 0 = tcpSend socketError description: 'Error occured while setting SO_REUSEADDR'.
		opt := tcpSend getOption: 'SO_REUSEADDR'.
		self assert: opt first isZero & opt last isZero not description: 'SO_REUSEADDR couldn''t be set'.
		tcpSend setOption: 'SO_REUSEPORT' value: 1.
		self assert: 0 = tcpSend socketError description: 'Error occured while setting SO_REUSEPORT'.
		opt := tcpSend getOption: 'SO_REUSEPORT'.
		self assert: opt first isZero & opt last isZero not description: 'SO_REUSEPORT couldn''t be set'.
		"tcpSend setOption: 'TCP_NODELAY' value: 1."
		send1 := UUID new.

		tcpRecv := Socket newTCP.
		tcpRecv setOption: 'SO_REUSEADDR' value: 1.
		self assert: 0 = tcpRecv socketError.
		tcpRecv setOption: 'SO_REUSEPORT' value: 1.
		self assert: 0 = tcpRecv socketError.
		tcpRecv setPort: port.
		self assert: port = tcpRecv localPort.
		recv2 := UUID new.

		recvProc := [| received |
			received := 0.
			tcpRecv waitForConnectionFor: 200000.
			[received < 16] whileTrue:
				[received := received + (tcpRecv receiveDataInto: recv2 startingAt: received + 1)
				"No need to yield here, because #receiveDataInto:startingAt: will either wait on the readSemaphore of the socket or signal an error." ]
			] newProcess.
		sendProc := [tcpSend connectTo: address port: port.
					   sent := tcpSend sendData: send1] newProcess.
		recvProc resume.
		sendProc resume.
		(Delay forMilliseconds: 200) wait.
		self 
			assert: sendProc isTerminated description: 'sendProc hasn''t terminated till the deadline';
			assert: recvProc isTerminated description: 'recvProc hasn''t terminated till the deadline';
			assert: 16 = sent description: ('{1} bytes were sent instead of 16' format: { sent });
			assert: send1 = recv2  description: 'sent and received bytes differ']
	ensure:
		[tcpSend ifNotNil: [ tcpSend destroy ].
		tcpRecv ifNotNil: [ tcpRecv destroy ].
		sendProc ifNotNil: [ sendProc terminate ].
		recvProc ifNotNil: [ recvProc terminate ]]```
4. notice how in the log you see
```   32032    0 sqUnixSocket.c:1141 sqSocketSendDone(16) !socketWritable
   32032    0 aio.c:521 aioHandle(16, dataHandler, 5/AIO_WX)
   32032    0 sqUnixSocket.c:749 socketStatus 16: Connected O_ASYNC|O_NONBLOCK
   32032    0 sqUnixSocket.c:480 dataHandler(16=16, 0x7ff901521f30, 4/AIO_W)
   32032    0 sqUnixSocket.c:499 notify 16 write
   32032    0 sqUnixSocket.c:1141 sqSocketSendDone(16) !socketWritable
   32032    0 aio.c:521 aioHandle(16, dataHandler, 5/AIO_WX)
   32032    0 sqUnixSocket.c:749 socketStatus 16: Connected O_ASYNC|O_NONBLOCK
   32032    0 sqUnixSocket.c:480 dataHandler(16=16, 0x7ff901521f30, 4/AIO_W)
   32032    0 sqUnixSocket.c:499 notify 16 write
   32032    0 sqUnixSocket.c:1141 sqSocketSendDone(16) !socketWritable
   32032    0 aio.c:521 aioHandle(16, dataHandler, 5/AIO_WX)
   32032    0 sqUnixSocket.c:749 socketStatus 16: Connected O_ASYNC|O_NONBLOCK
   32032    0 sqUnixSocket.c:480 dataHandler(16=16, 0x7ff901521f30, 4/AIO_W)
   32032    0 sqUnixSocket.c:499 notify 16 write
   32032    0 sqUnixSocket.c:1141 sqSocketSendDone(16) !socketWritable
   32032    0 aio.c:521 aioHandle(16, dataHandler, 5/AIO_WX)...```

and each line that says ```sqUnixSocket.c:1141 sqSocketSendDone(16) !socketWritable``` is proof that select is returning 0.  It comes form this:
```static int
socketWritable(int s)
{
  struct timeval tv = { 0, 0 }; // i.e. poll
  fd_set fds;

  FD_ZERO(&fds);
  FD_SET(s, &fds);
#ifdef AIO_DEBUG
  { int r = select(1, 0, &fds, 0, &tv);
    if (r < 0)
        perror("socketWritable: select(1,0,&fd,0,&poll)");
    return r > 0;
  }
#else
  return select(1, 0, &fds, 0, &tv) > 0;
#endif
}```
i.e. ```r > 0``` is always false, and since there is no output from the perror we can conclude that select must be answering 0.

Now compile a VM from this commit and see that the example now works and that the log looks healthy:
```  413959    0 sqUnixSocket.c:788 listenOnPortBacklogSize(18, 1)
  413959    0 aio.c:452 aioEnable(18): Elicit SIGIO via O_ASYNC/fcntl
  413959    0 aio.c:521 aioHandle(18, acceptHandler, 3/AIO_RX)
  413959    0 sqUnixSocket.c:757 socketStatus 18: WaitingForConnection O_ASYNC|O_NONBLOCK
  413959    0 sqUnixSocket.c:757 socketStatus 18: WaitingForConnection O_ASYNC|O_NONBLOCK
  413959    0 sqUnixSocket.c:757 socketStatus 16: Unconnected !fcntl(fd,F_GETFL,0) !!
  413959    0 sqUnixSocket.c:2226 connectToAddressSize(16)
  413959    0 aio.c:452 aioEnable(16): Elicit SIGIO via O_ASYNC/fcntl
  413959    0 sqUnixSocket.c:2245 connect() => -1
  413959    0 aio.c:521 aioHandle(16, connectHandler, 5/AIO_WX)
  413961    2 sqUnixSocket.c:757 socketStatus 16: WaitingForConnection O_ASYNC|O_NONBLOCK
  413961    0 sqUnixSocket.c:445 connectHandler(16, 0x7fd0b34e2b90, 4)
  413961    0 sqUnixSocket.c:470 notify 16 conn
  413961    0 sqUnixSocket.c:388 acceptHandler(18, 0x7fd0b34e2ca0 ,2)
  413961    0 aio.c:565 aioDisable(18)
  413961    0 aio.c:545 aioSuspend(18)
  413961    0 aio.c:452 aioEnable(19): Elicit SIGIO via O_ASYNC/fcntl
  413961    0 sqUnixSocket.c:435 notify 19 conn
  413961    0 sqUnixSocket.c:757 socketStatus 19: Connected O_ASYNC|O_NONBLOCK
  413961    0 aio.c:521 aioHandle(19, dataHandler, 3/AIO_RX)
  413961    0 sqUnixSocket.c:1134 receiveDataAvailable(19) -> false [aioHandle is set]
  413961    0 sqUnixSocket.c:757 socketStatus 19: Connected O_ASYNC|O_NONBLOCK
  413961    0 sqUnixSocket.c:757 socketStatus 16: Connected O_ASYNC|O_NONBLOCK
  413961    0 sqUnixSocket.c:1151 sqSocketSendDone(16) !socketWritable
  413961    0 aio.c:521 aioHandle(16, dataHandler, 5/AIO_WX)
  413961    0 sqUnixSocket.c:757 socketStatus 16: Connected O_ASYNC|O_NONBLOCK
  413961    0 sqUnixSocket.c:481 dataHandler(16=16, 0x7fd0b34e2b90, 4/AIO_W)
  413961    0 sqUnixSocket.c:501 notify 16 write
  413961    0 sqUnixSocket.c:1242 TCP sendData(16, 16)
  413961    0 sqUnixSocket.c:1262 sendData(16) done = 16
  413961    0 sqUnixSocket.c:481 dataHandler(19=19, 0x7fd0b34e2ca0, 2/AIO_R)
  413961    0 sqUnixSocket.c:498 notify 19 read
  413961    0 sqUnixSocket.c:1120 receiveDataAvailable(19) -> true
  413961    0 sqUnixSocket.c:1208 receiveData(19) done = 16
  414163  202 sqUnixSocket.c:757 socketStatus 16: Connected O_ASYNC|O_NONBLOCK
  414163    0 sqUnixSocket.c:1000 destroy(16)
  414163    0 sqUnixSocket.c:983 abortConnection(16)
  414163    0 sqUnixSocket.c:945 closeConnection(16)
  414163    0 aio.c:565 aioDisable(16)
  414163    0 aio.c:545 aioSuspend(16)
  414163    0 sqUnixSocket.c:965 closeConnection: disconnected
  414163    0 sqUnixSocket.c:757 socketStatus 19: Connected O_ASYNC|O_NONBLOCK
  414163    0 sqUnixSocket.c:1000 destroy(19)
  414163    0 sqUnixSocket.c:983 abortConnection(19)
  414163    0 sqUnixSocket.c:945 closeConnection(19)
  414163    0 aio.c:565 aioDisable(19)
  414163    0 aio.c:545 aioSuspend(19)
  414163    0 sqUnixSocket.c:965 closeConnection: disconnected```

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/OpenSmalltalk/opensmalltalk-vm/commit/7deac028aeeb769c8782242fc23bebdfaaa58e3d#commitcomment-43098105
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20201009/efbafeef/attachment-0001.html>


More information about the Vm-dev mailing list