From 3fb9a91cbea160f058889d4a66fd3b4d2e6b6fce Mon Sep 17 00:00:00 2001 From: cheatfate Date: Tue, 29 May 2018 12:59:39 +0300 Subject: [PATCH] Investigated Transport close bug and fixed it. Removed old integrated tests and hexdump Removed trailing whitespaces. --- asyncdispatch2/handles.nim | 4 +- asyncdispatch2/hexdump.nim | 92 -------------------------- asyncdispatch2/sendfile.nim | 12 ++-- asyncdispatch2/timer.nim | 2 +- asyncdispatch2/transports/common.nim | 2 +- asyncdispatch2/transports/datagram.nim | 4 +- asyncdispatch2/transports/stream.nim | 6 ++ tests/test2.nim | 13 ---- tests/test3.nim | 10 --- tests/test4.nim | 11 --- tests/testdatagram.nim | 4 +- 11 files changed, 20 insertions(+), 140 deletions(-) delete mode 100644 asyncdispatch2/hexdump.nim delete mode 100644 tests/test2.nim delete mode 100644 tests/test3.nim delete mode 100644 tests/test4.nim diff --git a/asyncdispatch2/handles.nim b/asyncdispatch2/handles.nim index 6ff514c9..d90beb5d 100644 --- a/asyncdispatch2/handles.nim +++ b/asyncdispatch2/handles.nim @@ -43,7 +43,7 @@ proc setSockOpt*(socket: AsyncFD, level, optname, optval: int): bool = if setsockopt(SocketHandle(socket), cint(level), cint(optname), addr(value), sizeof(value).SockLen) < 0'i32: result = false - + proc getSockOpt*(socket: AsyncFD, level, optname: int, value: var int): bool = ## `getsockopt()` for integer options. var res: cint @@ -89,7 +89,7 @@ proc wrapAsyncSocket*(sock: SocketHandle): AsyncFD = close(sock) return asyncInvalidSocket result = AsyncFD(sock) - register(result) + register(result) proc closeAsyncSocket*(s: AsyncFD) {.inline.} = ## Closes asynchronous socket handle ``s``. diff --git a/asyncdispatch2/hexdump.nim b/asyncdispatch2/hexdump.nim deleted file mode 100644 index 38498d94..00000000 --- a/asyncdispatch2/hexdump.nim +++ /dev/null @@ -1,92 +0,0 @@ -# -# Copyright (c) 2016 Eugene Kabanov -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. - -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -# - -from strutils import toHex, repeat - -proc dumpHex*(pbytes: pointer, nbytes: int, items = 1, ascii = true): string = - ## Return hexadecimal memory dump representation pointed by ``p``. - ## ``nbytes`` - number of bytes to show - ## ``items`` - number of bytes in group (supported ``items`` count is - ## 1, 2, 4, 8) - ## ``ascii`` - if ``true`` show ASCII representation of memory dump. - result = "" - let hexSize = items * 2 - var i = 0 - var slider = pbytes - var asciiText = "" - while i < nbytes: - if i %% 16 == 0: - result = result & toHex(cast[BiggestInt](slider), - sizeof(BiggestInt) * 2) & ": " - var k = 0 - while k < items: - var ch = cast[ptr char](cast[uint](slider) + k.uint)[] - if ord(ch) > 31 and ord(ch) < 127: asciiText &= ch else: asciiText &= "." - inc(k) - case items: - of 1: - result = result & toHex(cast[BiggestInt](cast[ptr uint8](slider)[]), - hexSize) - of 2: - result = result & toHex(cast[BiggestInt](cast[ptr uint16](slider)[]), - hexSize) - of 4: - result = result & toHex(cast[BiggestInt](cast[ptr uint32](slider)[]), - hexSize) - of 8: - result = result & toHex(cast[BiggestInt](cast[ptr uint64](slider)[]), - hexSize) - else: - raise newException(ValueError, "Wrong items size!") - result = result & " " - slider = cast[pointer](cast[uint](slider) + items.uint) - i = i + items - if i %% 16 == 0: - result = result & " " & asciiText - asciiText.setLen(0) - result = result & "\n" - - if i %% 16 != 0: - var spacesCount = ((16 - (i %% 16)) div items) * (hexSize + 1) + 1 - result = result & repeat(' ', spacesCount) - result = result & asciiText - result = result & "\n" - -proc dumpHex*[T](v: openarray[T], items: int = 0, ascii = true): string = - ## Return hexadecimal memory dump representation of openarray[T] ``v``. - ## ``items`` - number of bytes in group (supported ``items`` count is - ## 0, 1, 2, 4, 8). If ``items`` is ``0`` group size will depend on - ## ``sizeof(T)``. - ## ``ascii`` - if ``true`` show ASCII representation of memory dump. - var i = 0 - if items == 0: - when sizeof(T) == 2: - i = 2 - elif sizeof(T) == 4: - i = 4 - elif sizeof(T) == 8: - i = 8 - else: - i = 1 - else: - i = items - result = dumpHex(unsafeAddr v[0], sizeof(T) * len(v), i, ascii) diff --git a/asyncdispatch2/sendfile.nim b/asyncdispatch2/sendfile.nim index 2d2c2007..f9709f57 100644 --- a/asyncdispatch2/sendfile.nim +++ b/asyncdispatch2/sendfile.nim @@ -15,23 +15,23 @@ when defined(nimdoc): ## copying is done within the kernel, ``sendfile()`` is more efficient than ## the combination of ``read(2)`` and ``write(2)``, which would require ## transferring data to and from user space. - ## + ## ## ``infd`` should be a file descriptor opened for reading and ## ``outfd`` should be a descriptor opened for writing. - ## + ## ## The ``infd`` argument must correspond to a file which supports ## ``mmap(2)``-like operations (i.e., it cannot be a socket). - ## + ## ## ``offset`` the file offset from which ``sendfile()`` will start reading ## data from ``infd``. - ## + ## ## ``count`` is the number of bytes to copy between the file descriptors. - ## + ## ## If the transfer was successful, the number of bytes written to ``outfd`` ## is returned. Note that a successful call to ``sendfile()`` may write ## fewer bytes than requested; the caller should be prepared to retry the ## call if there were unsent bytes. - ## + ## ## On error, ``-1`` is returned. when defined(linux) or defined(android): diff --git a/asyncdispatch2/timer.nim b/asyncdispatch2/timer.nim index a0c2c01a..3863ed53 100644 --- a/asyncdispatch2/timer.nim +++ b/asyncdispatch2/timer.nim @@ -26,7 +26,7 @@ elif defined(macosx): proc posix_gettimeofday(tp: var Timeval, unused: pointer = nil) {. importc: "gettimeofday", header: "".} - + proc fastEpochTime*(): uint64 {.inline.} = var t: Timeval posix_gettimeofday(t) diff --git a/asyncdispatch2/transports/common.nim b/asyncdispatch2/transports/common.nim index 947320f5..d297bf57 100644 --- a/asyncdispatch2/transports/common.nim +++ b/asyncdispatch2/transports/common.nim @@ -104,7 +104,7 @@ proc `$`*(address: TransportAddress): string = proc strAddress*(address: string): TransportAddress = ## Parses string representation of ``address``. - ## + ## ## IPv4 transport address format is ``a.b.c.d:port``. ## IPv6 transport address format is ``[::]:port``. var parts = address.rsplit(":", maxsplit = 1) diff --git a/asyncdispatch2/transports/datagram.nim b/asyncdispatch2/transports/datagram.nim index 4535b225..36456b1f 100644 --- a/asyncdispatch2/transports/datagram.nim +++ b/asyncdispatch2/transports/datagram.nim @@ -460,7 +460,7 @@ proc newDatagramTransport*(cbproc: DatagramCallback, bufSize: int = DefaultDatagramBufferSize ): DatagramTransport = ## Create new UDP datagram transport (IPv4). - ## + ## ## ``cbproc`` - callback which will be called, when new datagram received. ## ``remote`` - bind transport to remote address (optional). ## ``local`` - bind transport to local address (to serving incoming @@ -481,7 +481,7 @@ proc newDatagramTransport6*(cbproc: DatagramCallback, bufSize: int = DefaultDatagramBufferSize ): DatagramTransport = ## Create new UDP datagram transport (IPv6). - ## + ## ## ``cbproc`` - callback which will be called, when new datagram received. ## ``remote`` - bind transport to remote address (optional). ## ``local`` - bind transport to local address (to serving incoming diff --git a/asyncdispatch2/transports/stream.nim b/asyncdispatch2/transports/stream.nim index de0030d9..88658fff 100644 --- a/asyncdispatch2/transports/stream.nim +++ b/asyncdispatch2/transports/stream.nim @@ -539,6 +539,9 @@ else: proc writeStreamLoop(udata: pointer) {.gcsafe.} = var cdata = cast[ptr CompletionData](udata) + if not isNil(cdata) and cdata.fd == 0: + # Transport was closed earlier, exiting + return var transp = cast[UnixStreamTransport](cdata.udata) let fd = SocketHandle(cdata.fd) if len(transp.queue) > 0: @@ -584,6 +587,9 @@ else: proc readStreamLoop(udata: pointer) {.gcsafe.} = var cdata = cast[ptr CompletionData](udata) + if not isNil(cdata) and cdata.fd == 0: + # Transport was closed earlier, exiting + return var transp = cast[UnixStreamTransport](cdata.udata) let fd = SocketHandle(cdata.fd) while true: diff --git a/tests/test2.nim b/tests/test2.nim deleted file mode 100644 index 6dcf8274..00000000 --- a/tests/test2.nim +++ /dev/null @@ -1,13 +0,0 @@ -import asyncdispatch2 - -proc task() {.async.} = - await sleepAsync(10) - -when isMainModule: - var counter = 0 - var f = task() - while not f.finished: - inc(counter) - poll() - -echo counter diff --git a/tests/test3.nim b/tests/test3.nim deleted file mode 100644 index 94c165fa..00000000 --- a/tests/test3.nim +++ /dev/null @@ -1,10 +0,0 @@ -import asyncdispatch2 - -proc task() {.async.} = - await sleepAsync(1000) - -proc waitTask() {.async.} = - echo await withTimeout(task(), 100) - -when isMainModule: - waitFor waitTask() diff --git a/tests/test4.nim b/tests/test4.nim deleted file mode 100644 index f7a7d52e..00000000 --- a/tests/test4.nim +++ /dev/null @@ -1,11 +0,0 @@ -import ../asyncdispatch2 - -proc task() {.async.} = - if true: - raise newException(ValueError, "Test Error") - -proc waitTask() {.async.} = - await task() - -when isMainModule: - waitFor waitTask() diff --git a/tests/testdatagram.nim b/tests/testdatagram.nim index 5d472df3..bfad4971 100644 --- a/tests/testdatagram.nim +++ b/tests/testdatagram.nim @@ -10,9 +10,9 @@ import strutils, net, unittest import ../asyncdispatch2 const - TestsCount = 100000 + TestsCount = 10000 ClientsCount = 100 - MessagesCount = 1000 + MessagesCount = 100 proc client1(transp: DatagramTransport, pbytes: pointer, nbytes: int, raddr: TransportAddress, udata: pointer): Future[void] {.async.} =