Socket.st
changeset 5441 bdf6b4e8c68b
parent 5440 ad4949b2bd09
child 5442 c3fa7c4f818f
--- a/Socket.st	Fri Jan 31 15:45:45 2020 +0100
+++ b/Socket.st	Wed Feb 05 15:14:27 2020 +0100
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
 "
  COPYRIGHT (c) 1992 by Claus Gittinger
 	      All Rights Reserved
@@ -4373,6 +4375,91 @@
     ^ self setSocketOption:#'TCP_NODELAY' argument:aBoolean argument:nil.
 ! !
 
+!Socket methodsFor:'support websocket'!
+
+nonBlockingNextPutAll:someBytes
+    "should be replaced in the calles by #nextPutAll:
+     but currently #nextPutAll is broken / unstable
+     only called by WebSocketStream #criticalSocketNextPutAll:"
+
+    |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 infinitiv (due to loop)   
+        self writeWaitWithTimeoutMs:1000.
+    ].
+
+    "Created: / 30-01-2020 / 16:35:08 / Stefan Reise"
+    "Modified (comment): / 05-02-2020 / 15:13:39 / Stefan Reise"
+!
+
+primNonBlockingNextPutAll:someBytes
+    "should be replaced in the calles by #nextPutAll:
+     but currently #nextPutAll is broken / unstable
+     only called by WebSocketStream #criticalSocketNextPutAll:"
+
+    |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 (comment): / 05-02-2020 / 15:12:49 / Stefan Reise"
+! !
+
 !Socket methodsFor:'waiting'!
 
 waitForNewConnectionOrDataOnAny:otherConnections timeout:secondsOrTimeDurationOrNil