tnetdial.nim 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. discard """
  2. cmd: "nim c --threads:on $file"
  3. exitcode: 0
  4. output: "OK"
  5. """
  6. import os, net, nativesockets, asyncdispatch
  7. import std/[assertions, typedthreads]
  8. ## Test for net.dial
  9. const port = Port(28431)
  10. proc initIPv6Server(hostname: string, port: Port): AsyncFD =
  11. let fd = createNativeSocket(AF_INET6)
  12. setSockOptInt(fd, SOL_SOCKET, SO_REUSEADDR, 1)
  13. var aiList = getAddrInfo(hostname, port, AF_INET6)
  14. if bindAddr(fd, aiList.ai_addr, aiList.ai_addrlen.SockLen) < 0'i32:
  15. freeAddrInfo(aiList)
  16. raiseOSError(osLastError())
  17. freeAddrInfo(aiList)
  18. if listen(fd) != 0:
  19. raiseOSError(osLastError())
  20. setBlocking(fd, false)
  21. var serverFd = fd.AsyncFD
  22. register(serverFd)
  23. result = serverFd
  24. # Since net.dial is synchronous, we use main thread to setup server,
  25. # and dial to it from another thread.
  26. proc testThread() {.thread.} =
  27. let fd = net.dial("::1", port)
  28. var s = newString(5)
  29. doAssert fd.recv(addr s[0], 5) == 5
  30. if s == "Hello":
  31. echo "OK"
  32. fd.close()
  33. proc test() =
  34. let serverFd = initIPv6Server("::1", port)
  35. var t: Thread[void] = default(Thread[void])
  36. createThread(t, testThread)
  37. var done = false
  38. serverFd.accept().callback = proc(fut: Future[AsyncFD]) =
  39. serverFd.closeSocket()
  40. if not fut.failed:
  41. let fd = fut.read()
  42. fd.send("Hello").callback = proc() =
  43. fd.closeSocket()
  44. done = true
  45. while not done:
  46. poll()
  47. joinThread(t)
  48. # this would cause #13132 `for i in 0..<10000: test()`
  49. test()