Bug in std.socket

Brad Roberts braddr at bellevue.puremagic.com
Tue Apr 14 18:30:07 PDT 2009


Your code is inherently racy.  The client thread could attempt to connect 
before the server thread has finished the steps prior to accept.

Also, there's no second . in the version scheme for DMD, it's just 1.xxx 
or 2.xxx.

Later,
Brad

On Tue, 14 Apr 2009, Graham St Jack wrote:

> Forgive my ignorance, but can anyone tell me how to post a ticket for 
> phobos?
> 
> I want to report a bug in std.socket's TcpSocket.accept() (at least it 
> manifests itself there for me) introduced in D 2.0.27 and still there in 
> 2.0.28. The following code runs to completion in 2.026 and blocks on 
> accept in later compiler versions.
> 
> 
> import std.socket;
> import std.stdio;
> import core.thread;
> 
> 
> class Server {
>     private {
>         InternetAddress mAddress;
>         Thread          mThread;
>     }
> 
>     this(InternetAddress address) {
>         mAddress     = address;
>         mThread      = new Thread(&run);
>         mThread.name = "server".dup;
>         mThread.start;
>     }
> 
>     void join() {
>         mThread.join;
>     }
> 
>     void run() {
>         try {
>             writefln("server - setting up server socket");
>             auto listener = new TcpSocket();
>             listener.bind(mAddress);
>             listener.listen(5);
> 
>             // wait for a connection
>             writefln("server - waiting for a client connection");
>             auto socket = listener.accept();
>             writefln("server - got a client connection");
> 
>             // read some data and write it back
>             writefln("server - reading data from the client");
>             ubyte[100] data;
>             int qty = socket.receive(data);
>             writefln("server - writing the data back to the client");
>             socket.send(data[0..qty]);
>         }
>         catch (Exception ex) {
>             writefln("server - server got exception: %s", ex);
>         }
> 
>         // terminate
>         writefln("server - terminating");
>     }
> }
> 
> class Client {
>     private {
>         InternetAddress mAddress;
>         Thread          mThread;
>     }
> 
>     this(InternetAddress address) {
>         mAddress = address;
>         mThread = new Thread(&run);
>         mThread.name = "client".dup;
>         mThread.start;
>     }
> 
>     void join() {
>         mThread.join;
>     }
> 
>     void run() {
>         try {
>             // connect
>             writefln("client - connecting to server");
>             auto socket = new TcpSocket(mAddress);
>             writefln("client - connected to server");
> 
>             // send and receive some data
>             writefln("client - sending data to server");
>             ubyte[3] send_data;
>             send_data[0] = 41;
>             send_data[1] = 42;
>             send_data[2] = 43;
>             int qty = socket.send(send_data);
>             assert(qty == send_data.length);
>             writefln("client - receiving data from server");
>             ubyte[100] receive_data;
>             qty = socket.receive(receive_data);
>             writefln("client - got %s bytes from server", qty);
>         }
>         catch (Exception ex) {
>             writefln("client - client got exception %s", ex);
>         }
> 
>         // terminate
>         writefln("client - terminating");
>     }
> }
> 
> 
> 
> int main(string[] args) {
>     writefln("test starting");
> 
>     try {
>         InternetAddress address = new InternetAddress("localhost", 12345);
>         Server server = new Server(address);
>         Client client = new Client(address);
>         writefln("joining with server");
>         server.join;
>         writefln("joining with client");
>         client.join;
>         writefln("finished");
>     }
>     catch (Exception ex) {
>         writefln("unexpected exception %s", ex);
>     }
>     return 0;
> }
> 



More information about the Digitalmars-d mailing list