You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- SafeDisconn flag is present
&
- Cannot write to socket (because it is closed)
&
- socket.getFd() != osInvalidSocket (because its copied btween threads)
A solution would be explicit source control. E.g:
ifnot isBlockingErr:
let lastError =osLastError()
socketError(socket, lastError = lastError, flags = flags)
#But the user has no way of knowing that the socket is closed#And that they should remove the safe disconn flag break
or perhaps
ifnot isBlockingErr:
let lastError =osLastError()
socketError(socket, lastError = lastError, flags = flags)
attemps.inc()
if attempts > maxRetries:
raiseOSError(osLastError(), "Could not send all data.")
But this defeats the purpose of the safe disconn flag
Another way, more fitting way, would be to detect if its copied between threads, and get the new FD for it. Or, alternatively, just find a better way of testing if its open.
The text was updated successfully, but these errors were encountered:
It's not a deadlock. The problem with this code is that accept() is blocking while thread2() is exiting and nothing is going to process a new request.
The following code works:
import net
import os
var address =""var client: Socketlet globalSocket =newSocket()
globalSocket.setSockOpt(OptReusePort, true)
globalSocket.bindAddr(Port(7512))
globalSocket.listen()
var channel : Channel[Socket]
channel.open()
procthread1() {.gcsafe.} =whiletrue:
let recv = channel.tryRecv()
ifnot recv.dataAvailable:
sleep5continuevar socket : Socketvar data =Socket()
block scope:
let data = recv.msg
# To remove data from any shared scope after we deepcopydeepCopy(socket, data)
whiletrue:
ifnot socket.trySend("!!!\r\L"):
echo"Unable to send"
socket.close()
returnecho"send!"sleep500procthread2() {.gcsafe.} =
{.gcsafe.}:
sleep1000let socket =newSocket()
socket.connect("localhost", Port(7512))
whiletrue:
echo socket.recvLine()
sleep100
socket.close()
break
globalSocket.close
returnvar t1 : Thread[void]
var t2 : Thread[void]
createThread(t1, thread1)
createThread(t2, thread2)
var toThrSock: seq[Socket]
whiletrue:
try:
globalSocket.accept(client)
toThrSock.addSocket()
deepCopy(toThrSock[toThrSock.high], client)
channel.send(toThrSock[toThrSock.high])
except:
echo"Unable to accept request"joinThread(t1)
break
Description
Nim Version
2.2.0
Current Output
Expected Output
Known Workarounds
Remove the safedisconnect flag
Additional Information
So I know why this happens, and how to fix it. However, no PR due to the fact that I don't know what is an acceptable solution.
Nim/lib/pure/net.nim
Line 1763 in 8fe518e
The issue occurs under the following scenario
A solution would be explicit source control. E.g:
or perhaps
But this defeats the purpose of the safe disconn flag
Another way, more fitting way, would be to detect if its copied between threads, and get the new FD for it. Or, alternatively, just find a better way of testing if its open.
The text was updated successfully, but these errors were encountered: