#REFACTORING by Stefan Reise
class: Socket
removed:
#nonBlockingNextPutAll:
#primNonBlockingNextPutAll:
#setNonBlocking
--- a/Socket.st Fri Jan 31 14:00:51 2020 +0100
+++ b/Socket.st Fri Jan 31 15:45:45 2020 +0100
@@ -1,5 +1,3 @@
-"{ Encoding: utf8 }"
-
"
COPYRIGHT (c) 1992 by Claus Gittinger
All Rights Reserved
@@ -4375,160 +4373,6 @@
^ self setSocketOption:#'TCP_NODELAY' argument:aBoolean argument:nil.
! !
-!Socket methodsFor:'support websocket windows'!
-
-nonBlockingNextPutAll:someBytes
- "all sockets created under windows os are blocking.
-
- in case for web sockets,
- concurrent write actions needs to be supported properly,
- therefor the socket must be forced to be non blocking.
-
- especially if the client and the server are running within the same stx,
- because stx can not read from the socket, when the write is blocking -> freeze forever
-
- it does not help to just wait before a blocking write action,
- because the other web socket side could do write actions between our wait and our write action,
- in this case (the usual case) our write action will block even with the pre called wait
-
- by forcing the socket to be non blocking, we simply call the write action,
- the primitiv #send returns a 'would block' flag if it would block, then we wait and try again"
-
- |bytes countRemainingBytesToWrite result|
-
- OperatingSystem isMSWINDOWSlike ifFalse:[
- self error:'this method is for windows os only'.
- ].
-
- bytes := someBytes asByteArray.
- countRemainingBytesToWrite := bytes size.
-
- [
- result := self primNonBlockingNextPutAll:bytes. "/ may just writes a subset or may 0 -> would block
- result >= 0 "/ 0 or more bytes has been written
- and:[result ~= countRemainingBytesToWrite] "/ there are remaining bytes to write
- ] whileTrue:[
- result > 0 ifTrue:[
- bytes := bytes copyFrom:result + 1.
- countRemainingBytesToWrite := bytes size.
- ].
-
- "/ timeout does not matter, we wait infinitv
- self writeWaitWithTimeoutMs:1000.
- ].
-
- "Created: / 30-01-2020 / 16:35:08 / Stefan Reise"
- "Modified (comment): / 31-01-2020 / 13:59:12 / Stefan Reise"
-!
-
-primNonBlockingNextPutAll:someBytes
- "all sockets created under windows os are blocking.
-
- in case for web sockets,
- concurrent write actions needs to be supported properly,
- therefor the socket must be forced to be non blocking.
-
- especially if the client and the server are running within the same stx,
- because stx can not read from the socket, when the write is blocking -> freeze forever
-
- it does not help to just wait before a blocking write action,
- because the other web socket side could do write actions between our wait and our write action,
- in this case (the usual case) our write action will block even with the pre called wait
-
- by forcing the socket to be non blocking, we simply call the write action,
- the primitiv #send returns a 'would block' flag if it would block, then we wait and try again"
-
- |bytes byteLength returnValue|
-
- OperatingSystem isMSWINDOWSlike ifFalse:[
- self error:'this method is for windows os only'.
- ].
-
- bytes := someBytes asExternalBytes.
- byteLength := bytes size.
-
- "
- -1 error
- 0 0 bytes sent or would block -> try again after wait
- > 0 bytes sent (recall myself with the remaining bytes)
- "
- returnValue := -1.
-
- %{
- int sendResult;
- int wsaErrorNo;
- char *pBytes = __externalAddressVal(bytes);
- SOCKET socket = SOCKET_FROM_FILE_OBJECT(__INST(handle));
-
- sendResult = send(socket, pBytes, __intVal(byteLength), 0);
- if (sendResult == SOCKET_ERROR) {
- wsaErrorNo = WSAGetLastError();
- if (wsaErrorNo == WSAEWOULDBLOCK) {
- returnValue = __MKSMALLINT(0);
- } else {
- console_printf("send failed with: %d\n", wsaErrorNo);
- }
- } else {
- returnValue = __MKSMALLINT(sendResult);
- }
- %}.
-
- returnValue < 0 ifTrue:[
- self primitiveFailed.
- ].
-
- ^ returnValue
-
- "Created: / 30-01-2020 / 16:36:01 / Stefan Reise"
- "Modified: / 31-01-2020 / 11:53:01 / Stefan Reise"
- "Modified (format): / 31-01-2020 / 13:59:56 / Stefan Reise"
-!
-
-setNonBlocking
- "all sockets created under windows os are blocking.
-
- in case for web sockets,
- concurrent write actions needs to be supported properly,
- therefor the socket must be forced to be non blocking.
-
- especially if the client and the server are running within the same stx,
- because stx can not read from the socket, when the write is blocking -> freeze forever
-
- it does not help to just wait before a blocking write action,
- because the other web socket side could do write actions between our wait and our write action,
- in this case (the usual case) our write action will block even with the pre called wait
-
- by forcing the socket to be non blocking, we simply call the write action,
- the primitiv #send returns a 'would block' flag if it would block, then we wait and try again"
-
- |succeeded|
-
- OperatingSystem isMSWINDOWSlike ifFalse:[
- self error:'this method is for windows os only'.
- ].
-
- succeeded := false.
-
- %{
- int result;
- u_long nonBlocking = 1;
- SOCKET socket = SOCKET_FROM_FILE_OBJECT(__INST(handle));
-
- result = ioctlsocket(socket, FIONBIO, &nonBlocking);
- if (result == SOCKET_ERROR) {
- console_printf("ioctlsocket failed with %d\n", WSAGetLastError());
- } else {
- succeeded = true;
- }
- %}.
-
- succeeded ifFalse:[
- self primitiveFailed.
- ].
-
- "Created: / 31-01-2020 / 11:23:48 / Stefan Reise"
-! !
-
!Socket methodsFor:'waiting'!
waitForNewConnectionOrDataOnAny:otherConnections timeout:secondsOrTimeDurationOrNil