diff --git a/index.d b/index.d index b7f5341ebd5..905ebf3cbbf 100644 --- a/index.d +++ b/index.d @@ -470,7 +470,6 @@ $(COMMENT $(LINK2 std_regex_internal_parser.html, std.regex.internal.parser)$(BR) $(LINK2 std_regex_internal_tests.html, std.regex.internal.tests)$(BR) $(LINK2 std_regex_internal_thompson.html, std.regex.internal.thompson)$(BR) - $(LINK2 std_stdiobase.html, std.stdiobase)$(BR) ) $(TD Internal modules. diff --git a/posix.mak b/posix.mak index 2080712aa9c..bce3e08f29b 100644 --- a/posix.mak +++ b/posix.mak @@ -227,7 +227,6 @@ EXTRA_MODULES_INTERNAL := $(addprefix std/, \ processinit scopebuffer test/dummyrange \ $(addprefix unicode_, comp decomp grapheme norm tables) \ ) \ - stdiobase \ ) EXTRA_MODULES += $(EXTRA_DOCUMENTABLES) $(EXTRA_MODULES_INTERNAL) diff --git a/std/stdio.d b/std/stdio.d index 9da7656a4f9..cf5eb48cd15 100644 --- a/std/stdio.d +++ b/std/stdio.d @@ -19,7 +19,6 @@ import std.algorithm.mutation; // copy import std.meta; // allSatisfy import std.range.primitives; // ElementEncodingType, empty, front, // isBidirectionalRange, isInputRange, put -import std.stdiobase; import std.traits; // isSomeChar, isSomeString, Unqual, isPointer import std.typecons; // Flag @@ -4522,70 +4521,82 @@ Initialize with a message and an error code. } } -extern(C) void std_stdio_static_this() +// Undocumented but public because the std* handles are aliasing it. +ref File makeGlobal(alias handle)() { - static import core.stdc.stdio; - //Bind stdin, stdout, stderr - __gshared File.Impl stdinImpl; - stdinImpl.handle = core.stdc.stdio.stdin; - .stdin._p = &stdinImpl; - // stdout - __gshared File.Impl stdoutImpl; - stdoutImpl.handle = core.stdc.stdio.stdout; - .stdout._p = &stdoutImpl; - // stderr - __gshared File.Impl stderrImpl; - stderrImpl.handle = core.stdc.stdio.stderr; - .stderr._p = &stderrImpl; -} + static __gshared File.Impl impl; + static __gshared File result; -//--------- -__gshared -{ - /** The standard input stream. - Bugs: - Due to $(LINK2 https://issues.dlang.org/show_bug.cgi?id=15768, bug 15768), - it is thread un-safe to reassign `stdin` to a different `File` instance - than the default. - */ - File stdin; - /// - @safe unittest + // Use an inline spinlock to make sure the initializer is only run once. + // We assume there will be at most uint.max / 2 threads trying to initialize + // `handle` at once and steal the high bit to indicate that the globals have + // been initialized. + static shared uint spinlock; + import core.atomic; + if (atomicLoad!(MemoryOrder.acq)(spinlock) <= uint.max / 2) { - // Read stdin, sort lines, write to stdout - import std.array : array; - import std.algorithm.sorting : sort; - import std.algorithm.mutation : copy; - import std.typecons : Yes; - - void main() { - stdin // read from stdin - .byLineCopy(Yes.keepTerminator) // copying each line - .array() // convert to array of lines - .sort() // sort the lines - .copy( // copy output of .sort to an OutputRange - stdout.lockingTextWriter()); // the OutputRange + for (;;) + { + if (atomicLoad!(MemoryOrder.acq)(spinlock) > uint.max / 2) + break; + if (atomicOp!"+="(spinlock, 1) == 1) + { + impl.handle = handle; + result._p = &impl; + atomicOp!"+="(spinlock, uint.max / 2); + break; + } + atomicOp!"-="(spinlock, 1); } } + return result; +} - /** - The standard output stream. - Bugs: - Due to $(LINK2 https://issues.dlang.org/show_bug.cgi?id=15768, bug 15768), - it is thread un-safe to reassign `stdout` to a different `File` instance - than the default. - */ - File stdout; - /** - The standard error stream. - Bugs: - Due to $(LINK2 https://issues.dlang.org/show_bug.cgi?id=15768, bug 15768), - it is thread un-safe to reassign `stderr` to a different `File` instance - than the default. - */ - File stderr; +/** The standard input stream. + Bugs: + Due to $(LINK2 https://issues.dlang.org/show_bug.cgi?id=15768, bug 15768), + it is thread un-safe to reassign `stdin` to a different `File` instance + than the default. +*/ +alias stdin = makeGlobal!(core.stdc.stdio.stdin); + +/// +@safe unittest +{ + // Read stdin, sort lines, write to stdout + import std.array : array; + import std.algorithm.sorting : sort; + import std.algorithm.mutation : copy; + import std.typecons : Yes; + + void main() { + stdin // read from stdin + .byLineCopy(Yes.keepTerminator) // copying each line + .array() // convert to array of lines + .sort() // sort the lines + .copy( // copy output of .sort to an OutputRange + stdout.lockingTextWriter()); // the OutputRange + } } +/** + The standard output stream. + Bugs: + Due to $(LINK2 https://issues.dlang.org/show_bug.cgi?id=15768, bug 15768), + it is thread un-safe to reassign `stdout` to a different `File` instance + than the default. +*/ +alias stdout = makeGlobal!(core.stdc.stdio.stdout); + +/** + The standard error stream. + Bugs: + Due to $(LINK2 https://issues.dlang.org/show_bug.cgi?id=15768, bug 15768), + it is thread un-safe to reassign `stderr` to a different `File` instance + than the default. +*/ +alias stderr = makeGlobal!(core.stdc.stdio.stderr); + @system unittest { static import std.file; diff --git a/std/stdiobase.d b/std/stdiobase.d deleted file mode 100644 index 4570a4c9c11..00000000000 --- a/std/stdiobase.d +++ /dev/null @@ -1,24 +0,0 @@ -// Written in the D programming language. - -/** - * The only purpose of this module is to do the static construction for - * std.stdio, to eliminate cyclic construction errors. - * - * Copyright: Copyright Andrei Alexandrescu 2008 - 2009. - * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). - * Authors: $(HTTP erdani.org, Andrei Alexandrescu) - * Source: $(PHOBOSSRC std/_stdiobase.d) - */ -/* Copyright Andrei Alexandrescu 2008 - 2009. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ -module std.stdiobase; - -extern(C) void std_stdio_static_this(); - -shared static this() -{ - std_stdio_static_this(); -} diff --git a/win32.mak b/win32.mak index 3a9f3b48d37..440bda2385b 100644 --- a/win32.mak +++ b/win32.mak @@ -108,7 +108,6 @@ SRC= \ # The separation is a workaround for bug 4904 (optlink bug 3372). SRC_STD_1= \ std\stdio.d \ - std\stdiobase.d \ std\string.d \ std\format.d \ std\file.d @@ -604,7 +603,6 @@ cov : $(SRC_TO_COMPILE) $(LIB) # cov del *.lst $(DMD) -conf= -cov=83 -unittest -main -run std\stdio.d - $(DMD) -conf= -cov=100 -unittest -main -run std\stdiobase.d $(DMD) -conf= -cov=95 -unittest -main -run std\string.d $(DMD) -conf= -cov=71 -unittest -main -run std\format.d $(DMD) -conf= -cov=83 -unittest -main -run std\file.d diff --git a/win64.mak b/win64.mak index 80bc8467ea0..99826d9c3c0 100644 --- a/win64.mak +++ b/win64.mak @@ -112,7 +112,6 @@ SRC= \ # The separation is a workaround for bug 4904 (optlink bug 3372). SRC_STD_1= \ std\stdio.d \ - std\stdiobase.d \ std\string.d \ std\format.d \ std\file.d