Exiting blocked threads (socket.accept)

Tim tim at unknownMailAddress.com
Thu Mar 28 03:23:17 PDT 2013


On Thursday, 28 March 2013 at 07:57:07 UTC, Martin Drašar wrote:
> Dne 27.3.2013 22:38, Tim napsal(a):
>> 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:
>
> Hi,
>
> To use message passing, you have to use the std.concurrency 
> module and then jump through some hoops to execute the code in 
> your class in separate thread. Right now, you are using 
> core.thread which is lower level than std.concurrency. 
> Definitely check the page Ali sent you.
>
> I have altered your code a bit to send the interrupt to the 
> thread using a socketpair. I had to change the signal code, 
> because it was not working on my windows box (I wasn't sure 
> what to import).
>
> This code still relies on a variable set inside the signal 
> handler, because writing to a socket is not nothrow. You could 
> overcome this by using the pipe as Sean suggested.
>
> Martin
>
> import std.socket;
> import core.thread;
> import core.stdc.signal;
> import std.stdio;
>
> __gshared Socket readSock;
> __gshared Socket writeSock;
> __gshared bool stopServer = false;
>
> class Connection : Thread {
>   private Socket pSocket;
>   void run() {
>     ptrdiff_t received;
>     ubyte[0x10] buffer;
>
>     SocketSet ss = new SocketSet();
>
>   mainloop:
>     while(1) {
>
>       ss.reset();
>       ss.add(pSocket);
>       ss.add(readSock);
>
>       if (Socket.select(ss, null, null) > 0) {
>
>         if (ss.isSet(pSocket))
>         {
>           received = pSocket.receive(buffer);
>           writeln("Received data");
>           // process data
>         }
>         else if (ss.isSet(readSock))
>         {
>           writeln("Received interrupt");
>           break mainloop;
>         }
>       }
>     }
>     pSocket.close();
>   }
>   this(Socket s) {
>     super(&run);
>     pSocket = s;
>   }
> }
>
> extern (C) void terminateServer(int s) nothrow {
>   stopServer = true;
> }
>
> void main() {
>
>   signal(SIGINT, &terminateServer);
>
>   TcpSocket s = new TcpSocket();
>   s.bind(new InternetAddress(2100));
>   s.listen(0);
>
>   auto pair = socketPair();
>
>   readSock  = pair[0];
>   writeSock = pair[1];
>
>   SocketSet ss = new SocketSet();
>
>   while (!stopServer)
>   {
>     ss.reset();
>     ss.add(s);
>
>     if (Socket.select(ss, null, null, dur!"msecs"(20)) > 0)
>     {
>       writeln("Received new connection");
>       (new Connection(s.accept)).start();
>     }
>   }
>
>   writeSock.send([1]);
>
>   s.shutdown(SocketShutdown.BOTH);
>   s.close();
>
>   writeln("Finished");
> }

Thanks Martin and Ali. Your solution works as long as I use the 
receive()-method, but what about using SocketStreams? I replaced 
socket.receive() with socketStream.readLine() which isn't broken 
by the solution above...


More information about the Digitalmars-d-learn mailing list