RejectedSoftware Forums

Sign up

listenTCP

Looks like callback task from listenTCP owns read context of connection. But is it possible to write data from another task?

Re: listenTCP

Am 21.08.2013 15:40, schrieb Jack Applegame:

Looks like callback task from listenTCP owns read context of connection. But is it possible to write data from another task?

Since 0.7.16 TCPConnection instances are only owned as long as they
are in use (e.g. while read() or write() are in progress) and the
read part of a connection is independent of the write part. So as long
as you make sure that no two threads read concurrently or write
concurrently, the connection can be shared by any number of tasks.

Re: listenTCP

Strange. This example crashes (Windows 7 64bit, dmd 2.063.2, driver: libevent):

import vibe.d;

shared static this() {
    runTask({
        sleep(1.seconds);
        listenTCP(8000, (conn){
            accept(conn);
        }, "127.0.0.1");
        auto conn = connectTCP("127.0.0.1", 8000);
        logInfo("client: connected");
        conn.write("client: hello");
        logInfo("client: sent");
        ubyte[13] buf;
        conn.read(buf);
        logInfo("client: received '%s'", cast(string)buf);
    });
}
void accept(TCPConnection conn) {
    // Trying send and receive in new task
    runTask({
        conn.write("server: hello");
        logInfo("server: sent");
        logInfo("server: accepted");
        ubyte[13] buf;
        conn.read(buf);
        logInfo("server: received '%s'", cast(string)buf);
    });
}

package.json:

{
    "name": "test",
    "dependencies": {
        "vibe-d":       "~master",
    }
}

If to comment runTask in accept functions, assertion disappears.

Re: listenTCP

On Wed, 21 Aug 2013 19:23:48 GMT, Jack Applegame wrote:

Strange. This example crashes (Windows 7 64bit, dmd 2.063.2, driver: libevent):

From a quick look, I didn't figure out why it crashes, but the reason why it doesn't work is that the task that calls the delegate passed to listenTCP will close the connection once that delegate returns. The proper fix would be to wait for the manually started task to finish. Modified source with a join() call added:

import vibe.d;

shared static this() {
    runTask({
        sleep(1.seconds);
        listenTCP(8000, (conn){
            accept(conn);
        }, "127.0.0.1");
        auto conn = connectTCP("127.0.0.1", 8000);
        logInfo("client: connected");
        conn.write("client: hello");
        logInfo("client: sent");
        ubyte[13] buf;
        conn.read(buf);
        logInfo("client: received '%s'", cast(string)buf);
    });
}
void accept(TCPConnection conn) {
    // Trying send and receive in new task
    runTask({
        conn.write("server: hello");
        logInfo("server: sent");
        logInfo("server: accepted");
        ubyte[13] buf;
        conn.read(buf);
        logInfo("server: received '%s'", cast(string)buf);
    }).join();
}

Re: listenTCP

On Wed, 21 Aug 2013 19:56:54 GMT, Sönke Ludwig wrote:

the reason why it doesn't work is that the task that calls the delegate passed to listenTCP will close the connection once that delegate returns. The proper fix would be to wait for the manually started task to finish. Modified source with a join() call added

Yes! Now it works.

vibe.d is really awesome project and it is a pity that it is impossible to donate. :(