From 4d0e89016a8452cbe7c2a3c80095b716515ff8e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Ludwig?= Date: Sun, 18 Dec 2016 23:34:23 +0100 Subject: [PATCH] Fix TaskPipeImpl.waitForData with timeout to actually time out. Fixes #1605. --- source/vibe/stream/taskpipe.d | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/source/vibe/stream/taskpipe.d b/source/vibe/stream/taskpipe.d index 3db50505e5..d39af37980 100644 --- a/source/vibe/stream/taskpipe.d +++ b/source/vibe/stream/taskpipe.d @@ -106,13 +106,20 @@ private final class TaskPipeImpl { /** Blocks until at least one byte of data has been written to the pipe. */ - void waitForData(Duration timeout = 0.seconds) + void waitForData(Duration timeout = Duration.max) { + import std.datetime : Clock, SysTime, UTC; + bool have_timeout = timeout > 0.seconds && timeout != Duration.max; + SysTime now = Clock.currTime(UTC()); + SysTime timeout_target; + if (have_timeout) timeout_target = now + timeout; + synchronized (m_mutex) { - while (m_buffer.empty && !m_closed) { - if (timeout > 0.seconds) - m_condition.wait(timeout); + while (m_buffer.empty && !m_closed && (!have_timeout || now < timeout_target)) { + if (have_timeout) + m_condition.wait(timeout_target - now); else m_condition.wait(); + now = Clock.currTime(UTC()); } } } @@ -201,3 +208,16 @@ unittest { // issue #1501 - deadlock in TaskPipe joiner.join(); } } + +unittest { // issue # + auto t = runTask({ + auto tp = new TaskPipeImpl; + tp.waitForData(10.msecs); + exitEventLoop(); + }); + runTask({ + sleep(500.msecs); + assert(!t.running, "TaskPipeImpl.waitForData didn't timeout."); + }); + runEventLoop(); +}