@@ -7,6 +7,7 @@ package kotlinx.coroutines
7
7
import kotlinx.cinterop.*
8
8
import platform.posix.*
9
9
import kotlin.coroutines.*
10
+ import kotlin.native.concurrent.*
10
11
11
12
/* *
12
13
* Runs new coroutine and **blocks** current thread _interruptibly_ until its completion.
@@ -33,7 +34,7 @@ import kotlin.coroutines.*
33
34
public actual fun <T > runBlocking (context : CoroutineContext , block : suspend CoroutineScope .() -> T ): T {
34
35
val contextInterceptor = context[ContinuationInterceptor ]
35
36
val eventLoop: EventLoop ?
36
- var newContext: CoroutineContext = context // todo: kludge for data flow analysis error
37
+ val newContext: CoroutineContext
37
38
if (contextInterceptor == null ) {
38
39
// create or use private event loop if no dispatcher is specified
39
40
eventLoop = ThreadLocalEventLoop .eventLoop
@@ -57,24 +58,21 @@ private class BlockingCoroutine<T>(
57
58
override val isScopedCoroutine: Boolean get() = true
58
59
59
60
@Suppress(" UNCHECKED_CAST" )
60
- fun joinBlocking (): T = memScoped {
61
+ fun joinBlocking (): T {
61
62
try {
62
63
eventLoop?.incrementUseCount()
63
- val timespec = alloc< timespec> ()
64
64
while (true ) {
65
65
val parkNanos = eventLoop?.processNextEvent() ? : Long .MAX_VALUE
66
66
// note: process next even may loose unpark flag, so check if completed before parking
67
67
if (isCompleted) break
68
- timespec.tv_sec = (parkNanos / 1000000000L ).convert() // 1e9 ns -> sec
69
- timespec.tv_nsec = (parkNanos % 1000000000L ).convert() // % 1e9
70
- nanosleep(timespec.ptr, null )
68
+ Worker .current.park(parkNanos / 1000L )
71
69
}
72
70
} finally { // paranoia
73
71
eventLoop?.decrementUseCount()
74
72
}
75
73
// now return result
76
74
val state = state.unboxState()
77
75
(state as ? CompletedExceptionally )?.let { throw it.cause }
78
- state as T
76
+ return state as T
79
77
}
80
78
}
0 commit comments