Bug 9798 – The memory assigned in multithread is broken
Status
RESOLVED
Resolution
INVALID
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-03-23T10:15:00Z
Last change time
2013-03-23T16:38:06Z
Assigned to
nobody
Creator
zan77137
Comments
Comment #0 by zan77137 — 2013-03-23T10:15:18Z
This code doesn't work (github master HEAD):
-----------------------------------------
import std.socket, std.algorithm, std.concurrency, std.variant, std.typecons;
struct SendData { string id; string data; }
private bool receiveEx(T)(Socket sock, ref T dat)
{
import std.traits: isDynamicArray;
bool receiveExact(ubyte[] dat)
{
auto r = sock.receive(dat);
return r != 0 && r != Socket.ERROR;
}
static if (isDynamicArray!T)
{
uint len;
if (!receiveExact((cast(ubyte*)&len)[0..uint.sizeof]))
return false;
dat.length = len;
return receiveExact((cast(ubyte*)dat.ptr)[0..len*T.sizeof]);
}
else
{
return receiveExact((cast(ubyte*)&dat)[0..T.sizeof]);
}
}
private bool sendEx(T)(Socket sock, in T dat)
{
import std.traits: isDynamicArray;
static if (isDynamicArray!T)
{
auto len = cast(uint)dat.length;
return sock.send((cast(const ubyte*)&len)[0..uint.sizeof]) != Socket.ERROR
&& sock.send((cast(const ubyte*)dat.ptr)[0..len * T.sizeof]) != Socket.ERROR;
}
else
{
return !(sock.send((cast(const ubyte*)&dat)[0..T.sizeof]) == Socket.ERROR);
}
}
void entrySend(shared Socket ssock)
{
auto sock = cast()ssock;
receiveTimeout( dur!"msecs"(1),
(Variant arg)
{
auto msg = arg.get!(immutable(SendData)*)();
sock.sendEx(cast(uint)0);
sock.sendEx(msg.id);
sock.sendEx(msg.data);
});
}
void entryReceive(shared Socket ssock, void delegate(string, string) shared dg)
{
auto sock = cast()ssock;
uint msgid;
char[] id, data;
sock.receiveEx(msgid);
sock.receiveEx(id);
sock.receiveEx(data);
dg(id.assumeUnique(), data.assumeUnique());
}
unittest
{
import std.string, core.sync.barrier, core.thread;
auto barrier = new Barrier(2);
string msg;
auto socks = socketPair();
scope (exit)
{
socks[0].shutdown(SocketShutdown.BOTH), socks[0].close();
socks[1].shutdown(SocketShutdown.BOTH), socks[1].close();
}
auto dummy = new class
{
void onDataReceived(string id, string data) shared
{
msg = format("Client data received id[%s] data[%s]", id, data);
barrier.wait();
}
};
auto tidSS = spawn(&entrySend, cast(shared)socks[0]);
auto tidCR = spawn(&entryReceive, cast(shared)socks[1], &dummy.onDataReceived);
// server->client sendData
tidSS.send(new immutable SendData("aaaa", "xxxx"));
barrier.wait();
assert(msg == "Client data received id[aaaa] data[xxxx]", msg);
}
void main(){}
-----------------------------------------
$ dmd -unittest -debug -g -run main
[email protected](92): Client data received id[Clie] data[xxxx]
----------------
0x0041426D in onAssertErrorMsg
0x0040CC24 in void main.__modtest()
0x0041AA4D in extern (C) bool core.runtime.runModuleUnitTests().int __foreachbod
y344(ref object.ModuleInfo*)
0x00420CC7 in int rt.minfo.moduleinfos_apply(scope int delegate(ref object.Modul
eInfo*)).int __foreachbody549(ref rt.sections_win32.SectionGroup)
0x00414461 in _d_run_main
0x0040D630 in main
0x75B88543 in BaseThreadInitThunk
0x77B2AC69 in RtlInitializeExceptionChain
0x77B2AC3C in RtlInitializeExceptionChain
Comment #1 by repeatedly — 2013-03-23T13:38:56Z
This is not dmd bug.
> return receiveExact((cast(ubyte*)dat.ptr)[0..len*T.sizeof]);
and
> && sock.send((cast(const ubyte*)dat.ptr)[0..len * T.sizeof]) != Socket.ERROR;
have the bug.
You should use "(ForeachType!T).sizeof" instead of "T.sizeof".
Because "T.sizeof" is dynamic array object size, not array element size.