core.stdc.errno should probably expose the per-thread errno, but it doesn't. Using the _errno() function instead of the errno macro in errno.c is one way to fix it. Or possibly defining _MT when compiling the C parts of phobos.
Test case below is only tested with DMD 2.047, but this issue is present in both druntime and Phobos 1.x. Build with -version=fix to see the fix in action.
---
import core.thread;
import core.stdc.errno : EDOM;
import core.stdc.math;
import std.stdio;
version (fix) { }
else {
import core.stdc.errno;
}
version (fix) {
extern (C) int* _errno();
int errno() { return *_errno(); }
int errno(int v) { return *_errno() = v; }
}
void main()
{
pow(-1, 1.5); // sets EDOM (33)
assert(errno == EDOM);
Thread t = new Thread({
assert(errno == 0); // fails if using phobos errno
});
t.start();
t.join();
assert(errno == EDOM);
}
---
I stumpled across this when working on a D wrapper for a C library that uses errno.
Comment #1 by razvan.nitu1305 — 2017-07-07T08:41:31Z
This is actually a druntime bug since errno isn't defined in phobos, but in this example you could use it because std.stdio has a public import of core.stdc.
Comment #2 by razvan.nitu1305 — 2017-07-07T08:42:17Z
Don't mind my previous comment, it is unfinished and it was before actually running the example.
Comment #3 by dlang-bugzilla — 2017-07-07T14:29:46Z
(In reply to RazvanN from comment #2)
> Don't mind my previous comment,
I guess this should remain open, then.
Comment #4 by andrei — 2017-07-07T18:46:02Z
This is a reproducible problem on Windows (at least with wine). We use a C small file in druntime (src/core/stdc/errno.c) to make sure we use the C macro. Far as I can tell the same technique is used across Windows and Posix, which indicates the problem is with dmc's stdlib.
Comment #5 by robert.schadek — 2024-12-01T16:13:26Z