@@ -27,14 +27,16 @@ import java.util.concurrent.atomic.AtomicBoolean
2727import scala .concurrent .duration .Duration
2828import scala .concurrent .{Await , Promise }
2929import scala .util .{Failure , Success }
30+ import scala .annotation .internal .sharable
31+ import scala .compiletime .uninitialized
3032
3133object FileUtils {
3234 def newAsyncBufferedWriter (path : Path , charset : Charset = StandardCharsets .UTF_8 .nn, options : Array [OpenOption ] = NO_OPTIONS , threadsafe : Boolean = false ): LineWriter = {
3335 val encoder : CharsetEncoder = charset.newEncoder
34- val writer = new OutputStreamWriter (Files .newOutputStream(path, options : _ * ), encoder)
36+ val writer = new OutputStreamWriter (Files .newOutputStream(path, options* ), encoder)
3537 newAsyncBufferedWriter(new BufferedWriter (writer), threadsafe)
3638 }
37- def newAsyncBufferedWriter (underlying : Writer , threadsafe : Boolean ): LineWriter = {
39+ def newAsyncBufferedWriter (underlying : Writer , threadsafe : Boolean ): LineWriter = {
3840 val async = new AsyncBufferedWriter (underlying)
3941 if (threadsafe) new ThreadsafeWriter (async) else async
4042 }
@@ -71,7 +73,10 @@ object FileUtils {
7173
7274 }
7375
74- private object AsyncBufferedWriter {
76+ // FIXME: Potentially there is a false-positive error under -Ycheck-reentrant?
77+ // [error] possible data race involving globally reachable variable isReadOnly in class CharBuffer: Boolean
78+ // [error] possible data race involving globally reachable variable address in class Buffer: Long
79+ @ sharable private object AsyncBufferedWriter {
7580 private val Close = CharBuffer .allocate(0 )
7681 private val Flush = CharBuffer .allocate(0 )
7782 }
@@ -82,7 +87,7 @@ object FileUtils {
8287 background.ensureProcessed(current)
8388 current = allocate
8489 }
85- // allocate or reuse a CharArray which is guaranteed to have a backing array
90+ // allocate or reuse a CharArray which is guaranteed to have a backing array
8691 private def allocate : CharBuffer = {
8792 val reused = background.reuseBuffer
8893 if (reused eq null ) CharBuffer .allocate(bufferSize)
@@ -150,7 +155,7 @@ object FileUtils {
150155 // a failure detected will case an Failure, Success indicates a close
151156 val asyncStatus = Promise [Unit ]()
152157 private val scheduled = new AtomicBoolean
153- @ volatile var reuseBuffer : CharBuffer = _
158+ @ volatile var reuseBuffer : CharBuffer = uninitialized
154159
155160 def ensureProcessed (buffer : CharBuffer ): Unit = {
156161 if (asyncStatus.isCompleted) {
0 commit comments