Exiting blocked threads (socket.accept)
Tim
tim at unknownMailAddress.com
Wed Mar 27 14:38:10 PDT 2013
On Wednesday, 27 March 2013 at 20:16:39 UTC, Martin Drašar wrote:
> Dne 27.3.2013 18:51, Tim napsal(a):
>> That works as expected, except the fact that pressing CTRL+C
>> which stops
>> the while(!stopServer) doesn't terminate the mainloop in my
>> Connection-class (run()-method). This thread is blocked
>> because of the
>> receive()-method... but how can I force this thread to exit?
>> Is there
>> any chance to do that? I already tried to set the accepted
>> socket to
>> blocking(false) without any success...
>>
>> Thanks in advance for any reply!
>
> Hi Tim,
>
> you have to pass the termination information to the thread. It
> does not know about it and waits for receive() to return.
>
> You will have to employ the select() call to some extent.
>
> 1) You can have some form of global variable that indicates
> termination or you can send the termination info using
> Tid.send(). The code can then look like this:
>
> threadSocket.blocking(false);
> auto ss = new SocketSet();
> while (!shouldEnd)
> {
> ss.reset();
> ss.add(threadSocket);
>
> auto rc = Socket.select(ss, null, null, dur!"msecs"(timeout));
> if (rc == 1)
> {
> // process your data
> }
> }
>
> And it would take at most timeout miliseconds for thread to
> react to termination message.
>
> 2) Use what Sean Kelly wrote. Either using a pipe or socketpair.
>
> Martin
Thanks! I've never used message passing and I'm currently a bit
confused how it works (I came from the Java-area where message
passing isn't necessary for something like that)... are there any
information/examples about message passing? I sill can't get it
to work... I changed my code as follows:
class Connection : Thread {
private Socket pSocket;
void run() {
ptrdiff_t received;
ubyte[0x10] buffer;
SocketSet ss = new SocketSet();
mainloop:
while(!stopServer) {
ss.reset();
ss.add(pSocket);
if (Socket.select(ss, null, null, dur!"msecs"(10)) > 0) {
received = pSocket.receive(buffer);
// do some more stuff here
if (buffer[0 .. received] == "QUIT")
break mainloop;
}
}
}
this(Socket s) {
super(&run);
pSocket = s;
}
}
extern(C) void terminateServer(int s) {
stopServer = true;
}
private bool stopServer = false;
void main() {
sigaction_t sig;
sig.sa_handler = &terminateServer;
sigemptyset(&sig.sa_mask);
sig.sa_flags = 0;
sigaction(SIGINT, &sig, null);
TcpSocket s = new TcpSocket();
s.bind(new InternetAddress(2100));
//s.blocking(false);
s.listen(0);
SocketSet ss = new SocketSet();
while(!stopServer) {
ss.reset();
ss.add(s);
if (Socket.select(ss, null, null, dur!"msecs"(10)) > 0)
(new Connection(s.accept)).start();
}
writeln("Server stopped");
s.shutdown(SocketShutdown.BOTH);
s.close();
}
Alright... let's connect to the server... the server accepts,
creates an instance of Connection and starts a new thread. Now...
I set stopServer to true (CTRL+C). This should stop the server
and I also get the message in my main()-method that the server
stopped. But the other thread (Connection-thread) doesn't
terminate... it runs as long as the connection to the client is
alive... by killing the connection from the client-side, the
connection thread also terminates (and throws an exception).
More information about the Digitalmars-d-learn
mailing list