@@ -27,14 +27,16 @@ import java.util.concurrent.atomic.AtomicBoolean
27
27
import scala .concurrent .duration .Duration
28
28
import scala .concurrent .{Await , Promise }
29
29
import scala .util .{Failure , Success }
30
+ import scala .annotation .internal .sharable
31
+ import scala .compiletime .uninitialized
30
32
31
33
object FileUtils {
32
34
def newAsyncBufferedWriter (path : Path , charset : Charset = StandardCharsets .UTF_8 .nn, options : Array [OpenOption ] = NO_OPTIONS , threadsafe : Boolean = false ): LineWriter = {
33
35
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)
35
37
newAsyncBufferedWriter(new BufferedWriter (writer), threadsafe)
36
38
}
37
- def newAsyncBufferedWriter (underlying : Writer , threadsafe : Boolean ): LineWriter = {
39
+ def newAsyncBufferedWriter (underlying : Writer , threadsafe : Boolean ): LineWriter = {
38
40
val async = new AsyncBufferedWriter (underlying)
39
41
if (threadsafe) new ThreadsafeWriter (async) else async
40
42
}
@@ -71,7 +73,10 @@ object FileUtils {
71
73
72
74
}
73
75
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 {
75
80
private val Close = CharBuffer .allocate(0 )
76
81
private val Flush = CharBuffer .allocate(0 )
77
82
}
@@ -82,7 +87,7 @@ object FileUtils {
82
87
background.ensureProcessed(current)
83
88
current = allocate
84
89
}
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
86
91
private def allocate : CharBuffer = {
87
92
val reused = background.reuseBuffer
88
93
if (reused eq null ) CharBuffer .allocate(bufferSize)
@@ -150,7 +155,7 @@ object FileUtils {
150
155
// a failure detected will case an Failure, Success indicates a close
151
156
val asyncStatus = Promise [Unit ]()
152
157
private val scheduled = new AtomicBoolean
153
- @ volatile var reuseBuffer : CharBuffer = _
158
+ @ volatile var reuseBuffer : CharBuffer = uninitialized
154
159
155
160
def ensureProcessed (buffer : CharBuffer ): Unit = {
156
161
if (asyncStatus.isCompleted) {
0 commit comments