@@ -90,6 +90,7 @@ $(LREF environment), $(LREF thisProcessID) and $(LREF thisThreadID).
90
90
module std.process ;
91
91
92
92
import core.thread : ThreadID;
93
+ import core.sync.rwmutex ;
93
94
94
95
version (Posix )
95
96
{
@@ -160,6 +161,13 @@ private
160
161
// Environment variable manipulation.
161
162
// =============================================================================
162
163
164
+ shared ReadWriteMutex mutex;
165
+
166
+ shared static this ()
167
+ {
168
+ mutex = new shared ReadWriteMutex (mutex.Policy.PREFER_READERS );
169
+ }
170
+
163
171
/**
164
172
Manipulates _environment variables using an associative-array-like
165
173
interface.
@@ -259,12 +267,14 @@ static:
259
267
import std.exception : enforce, errnoEnforce;
260
268
if (value is null )
261
269
{
270
+ // Note: remove needs write lock
262
271
remove(name);
263
272
return value;
264
273
}
265
- if ( core.sys.posix.stdlib.setenv (name.tempCString(), value.tempCString(), 1 ) != - 1 )
274
+ synchronized (mutex.writer )
266
275
{
267
- return value;
276
+ if (core.sys.posix.stdlib.setenv (name.tempCString(), value.tempCString(), 1 ) != - 1 )
277
+ return value;
268
278
}
269
279
// The default errno error message is very uninformative
270
280
// in the most common case, so we handle it manually.
@@ -277,6 +287,8 @@ static:
277
287
else version (Windows )
278
288
{
279
289
import std.windows.syserror : wenforce;
290
+
291
+ synchronized (mutex.writer)
280
292
wenforce(
281
293
SetEnvironmentVariableW(name.tempCStringW(), value.tempCStringW()),
282
294
);
@@ -296,8 +308,9 @@ static:
296
308
multi-threaded programs. See e.g.
297
309
$(LINK2 https://www.gnu.org/software/libc/manual/html_node/Environment-Access.html#Environment-Access, glibc).
298
310
*/
299
- void remove (scope const (char )[] name) @trusted nothrow @nogc
311
+ void remove (scope const (char )[] name) @trusted // nothrow @nogc
300
312
{
313
+ synchronized (mutex.writer)
301
314
version (Windows ) SetEnvironmentVariableW(name.tempCStringW(), null );
302
315
else version (Posix ) core.sys.posix.stdlib.unsetenv (name.tempCString());
303
316
else static assert (0 );
@@ -329,6 +342,8 @@ static:
329
342
{
330
343
if (name is null )
331
344
return false ;
345
+
346
+ synchronized (mutex.reader)
332
347
version (Posix )
333
348
return core.sys.posix.stdlib.getenv (name.tempCString()) ! is null ;
334
349
else version (Windows )
@@ -363,6 +378,8 @@ static:
363
378
{
364
379
import std.conv : to;
365
380
string [string ] aa;
381
+
382
+ synchronized (mutex.reader)
366
383
version (Posix )
367
384
{
368
385
auto environ = getEnvironPtr;
@@ -428,12 +445,13 @@ private:
428
445
// Retrieves the environment variable. Calls `sink` with a
429
446
// temporary buffer of OS characters, or `null` if the variable
430
447
// doesn't exist.
431
- void getImpl (scope const (char )[] name, scope void delegate (const (OSChar)[]) @safe sink) @trusted
448
+ void getImpl (scope const (char )[] name, scope void delegate (scope const (OSChar)[]) @safe sink) @trusted
432
449
{
433
450
// fix issue https://issues.dlang.org/show_bug.cgi?id=24549
434
451
if (name is null )
435
452
return sink (null );
436
453
454
+ synchronized (mutex.reader)
437
455
version (Windows )
438
456
{
439
457
// first we ask windows how long the environment variable is,
0 commit comments