diff --git a/backend.native/tests/runtime/workers/worker4.kt b/backend.native/tests/runtime/workers/worker4.kt index 99fece9eef3..a6a20b207de 100644 --- a/backend.native/tests/runtime/workers/worker4.kt +++ b/backend.native/tests/runtime/workers/worker4.kt @@ -93,4 +93,28 @@ import kotlin.native.concurrent.* assertTrue(main.park(1000L * 1000 * 1000, process = true)) assertEquals(1, counter.value) } -} \ No newline at end of file +} + +@Test fun runTest6() { + // Ensure zero timeout works properly. + Worker.current.park(0, process = true) +} + +@Test fun runTest7() { + val counter = AtomicInt(0) + withWorker { + val f1 = execute(TransferMode.SAFE, { counter }) { counter -> + Worker.current.park(Long.MAX_VALUE / 1000L, process = true) + counter.increment() + } + // wait a bit + Worker.current.park(10_000L) + // submit a task + val f2 = execute(TransferMode.SAFE, { counter }) { counter -> + counter.increment() + } + f1.consume {} + f2.consume {} + assertEquals(2, counter.value) + } +} diff --git a/runtime/src/main/cpp/Worker.cpp b/runtime/src/main/cpp/Worker.cpp index 5a115c47bee..6b5bbf29aff 100644 --- a/runtime/src/main/cpp/Worker.cpp +++ b/runtime/src/main/cpp/Worker.cpp @@ -772,10 +772,15 @@ bool Worker::waitForQueueLocked(KLong timeoutMicroseconds, KLong* remaining) { if (timeoutMicroseconds >= 0) { closestToRun = timeoutMicroseconds < closestToRun || closestToRun < 0 ? timeoutMicroseconds : closestToRun; } - if (closestToRun > 0) { + if (closestToRun == 0) { + // Just no wait at all here. + } else if (closestToRun > 0) { struct timeval tv; struct timespec ts; gettimeofday(&tv, nullptr); + // Protect from potential overflow, cutting at 10_000_000 seconds, aka 115 days. + if (closestToRun > 10LL * 1000 * 1000 * 1000 * 1000) + closestToRun = 10LL * 1000 * 1000 * 1000 * 1000; KLong nsDelta = closestToRun * 1000LL; ts.tv_nsec = (tv.tv_usec * 1000LL + nsDelta) % 1000000000LL; ts.tv_sec = (tv.tv_sec * 1000000000LL + nsDelta) / 1000000000LL;