summary refs log tree commit diff stats
path: root/lib/pure/asyncdispatch.nim
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pure/asyncdispatch.nim')
-rw-r--r--lib/pure/asyncdispatch.nim47
1 files changed, 26 insertions, 21 deletions
diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim
index 2c00f4b59..84b0ebbf8 100644
--- a/lib/pure/asyncdispatch.nim
+++ b/lib/pure/asyncdispatch.nim
@@ -328,11 +328,18 @@ when defined(windows) or defined(nimdoc):
 
   proc recv*(socket: TAsyncFD, size: int,
              flags: int = 0): PFuture[string] =
-    ## Reads ``size`` bytes from ``socket``. Returned future will complete once
-    ## all of the requested data is read. If socket is disconnected during the
-    ## recv operation then the future may complete with only a part of the
-    ## requested data read. If socket is disconnected and no data is available
-    ## to be read then the future will complete with a value of ``""``.
+    ## Reads **up to** ``size`` bytes from ``socket``. Returned future will
+    ## complete once all the data requested is read, a part of the data has been
+    ## read, or the socket has disconnected in which case the future will
+    ## complete with a value of ``""`.
+
+
+    # Things to note:
+    #   * When WSARecv completes immediately then ``bytesReceived`` is very
+    #     unreliable.
+    #   * Still need to implement message-oriented socket disconnection,
+    #     '\0' in the message currently signifies a socket disconnect. Who
+    #     knows what will happen when someone sends that to our socket.
     verifyPresence(socket)
     var retFuture = newFuture[string]()
     
@@ -350,8 +357,8 @@ when defined(windows) or defined(nimdoc):
             if bytesCount == 0 and dataBuf.buf[0] == '\0':
               retFuture.complete("")
             else:
-              var data = newString(size)
-              copyMem(addr data[0], addr dataBuf.buf[0], size)
+              var data = newString(bytesCount)
+              copyMem(addr data[0], addr dataBuf.buf[0], bytesCount)
               retFuture.complete($data)
           else:
             retFuture.fail(newException(EOS, osErrorMsg(errcode)))
@@ -378,8 +385,15 @@ when defined(windows) or defined(nimdoc):
       # ~ http://msdn.microsoft.com/en-us/library/ms741688%28v=vs.85%29.aspx
     else:
       # Request to read completed immediately.
-      var data = newString(size)
-      copyMem(addr data[0], addr dataBuf.buf[0], size)
+      # From my tests bytesReceived isn't reliable.
+      let realSize =
+        if bytesReceived == 0:
+          size
+        else:
+          bytesReceived
+      assert dataBuf.buf[0] != '\0'
+      var data = newString(realSize)
+      copyMem(addr data[0], addr dataBuf.buf[0], realSize)
       retFuture.complete($data)
       # We don't deallocate ``ol`` here because even though this completed
       # immediately poll will still be notified about its completion and it will
@@ -646,8 +660,7 @@ else:
     
     proc cb(sock: TAsyncFD): bool =
       result = true
-      let netSize = size - sizeRead
-      let res = recv(sock.TSocketHandle, addr readBuffer[sizeRead], netSize,
+      let res = recv(sock.TSocketHandle, addr readBuffer[0], size,
                      flags.cint)
       #echo("recv cb res: ", res)
       if res < 0:
@@ -659,17 +672,9 @@ else:
       elif res == 0:
         #echo("Disconnected recv: ", sizeRead)
         # Disconnected
-        if sizeRead == 0:
-          retFuture.complete("")
-        else:
-          readBuffer.setLen(sizeRead)
-          retFuture.complete(readBuffer)
+        retFuture.complete("")
       else:
-        sizeRead.inc(res)
-        if res != netSize:
-          result = false # We want to read all the data requested.
-        else:
-          retFuture.complete(readBuffer)
+        retFuture.complete(readBuffer)
       #echo("Recv cb result: ", result)
   
     addRead(socket, cb)