Remove all trailing whitespace
sed 's/[ \t]*$//' -i **/*.d
This commit is contained in:
parent
3faa5f3bdc
commit
8f89733a86
|
@ -1237,7 +1237,7 @@ package class VibedScheduler : Scheduler {
|
||||||
|
|
||||||
final switch (st_concurrencyPrimitive) with (ConcurrencyPrimitive) {
|
final switch (st_concurrencyPrimitive) with (ConcurrencyPrimitive) {
|
||||||
case task: runTask(op); break;
|
case task: runTask(op); break;
|
||||||
case workerTask:
|
case workerTask:
|
||||||
static void wrapper(shared(void delegate()) op) {
|
static void wrapper(shared(void delegate()) op) {
|
||||||
(cast(void delegate())op)();
|
(cast(void delegate())op)();
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,7 +133,7 @@ unittest {
|
||||||
|
|
||||||
struct LockedConnection(Connection) {
|
struct LockedConnection(Connection) {
|
||||||
import vibe.core.task : Task;
|
import vibe.core.task : Task;
|
||||||
|
|
||||||
private {
|
private {
|
||||||
ConnectionPool!Connection m_pool;
|
ConnectionPool!Connection m_pool;
|
||||||
Task m_task;
|
Task m_task;
|
||||||
|
|
|
@ -661,7 +661,7 @@ void yield()
|
||||||
to call `switchToTask` will result in task starvation and resource leakage.
|
to call `switchToTask` will result in task starvation and resource leakage.
|
||||||
|
|
||||||
Params:
|
Params:
|
||||||
on_interrupt = If specified, is required to
|
on_interrupt = If specified, is required to
|
||||||
|
|
||||||
See_Also: `switchToTask`
|
See_Also: `switchToTask`
|
||||||
*/
|
*/
|
||||||
|
@ -1042,7 +1042,7 @@ struct Timer {
|
||||||
|
|
||||||
/** Resets the timer to the specified timeout
|
/** Resets the timer to the specified timeout
|
||||||
*/
|
*/
|
||||||
void rearm(Duration dur, bool periodic = false) nothrow
|
void rearm(Duration dur, bool periodic = false) nothrow
|
||||||
in { assert(dur > 0.seconds, "Negative timer duration specified."); }
|
in { assert(dur > 0.seconds, "Negative timer duration specified."); }
|
||||||
body { m_driver.set(m_id, dur, periodic ? dur : 0.seconds); }
|
body { m_driver.set(m_id, dur, periodic ? dur : 0.seconds); }
|
||||||
|
|
||||||
|
|
|
@ -410,7 +410,7 @@ struct FileStream {
|
||||||
if (m_fd != FileFD.invalid)
|
if (m_fd != FileFD.invalid)
|
||||||
eventDriver.files.addRef(m_fd);
|
eventDriver.files.addRef(m_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
~this()
|
~this()
|
||||||
{
|
{
|
||||||
if (m_fd != FileFD.invalid)
|
if (m_fd != FileFD.invalid)
|
||||||
|
|
|
@ -252,7 +252,7 @@ final class FileLogger : Logger {
|
||||||
Format infoFormat = Format.thread;
|
Format infoFormat = Format.thread;
|
||||||
|
|
||||||
/** Use escape sequences to color log output.
|
/** Use escape sequences to color log output.
|
||||||
|
|
||||||
Note that the terminal must support 256-bit color codes.
|
Note that the terminal must support 256-bit color codes.
|
||||||
*/
|
*/
|
||||||
bool useColors = false;
|
bool useColors = false;
|
||||||
|
|
|
@ -192,9 +192,9 @@ TCPConnection connectTCP(NetworkAddress addr, NetworkAddress bind_address = anyA
|
||||||
return () @trusted { // scope
|
return () @trusted { // scope
|
||||||
scope uaddr = new RefAddress(addr.sockAddr, addr.sockAddrLen);
|
scope uaddr = new RefAddress(addr.sockAddr, addr.sockAddrLen);
|
||||||
scope baddr = new RefAddress(bind_address.sockAddr, bind_address.sockAddrLen);
|
scope baddr = new RefAddress(bind_address.sockAddr, bind_address.sockAddrLen);
|
||||||
|
|
||||||
// FIXME: make this interruptible
|
// FIXME: make this interruptible
|
||||||
auto result = asyncAwaitUninterruptible!(ConnectCallback,
|
auto result = asyncAwaitUninterruptible!(ConnectCallback,
|
||||||
cb => eventDriver.sockets.connectStream(uaddr, baddr, cb)
|
cb => eventDriver.sockets.connectStream(uaddr, baddr, cb)
|
||||||
//cb => eventDriver.sockets.cancelConnect(cb)
|
//cb => eventDriver.sockets.cancelConnect(cb)
|
||||||
);
|
);
|
||||||
|
@ -511,7 +511,7 @@ struct TCPConnection {
|
||||||
@property bool empty() { return leastSize == 0; }
|
@property bool empty() { return leastSize == 0; }
|
||||||
@property ulong leastSize() { waitForData(); return m_context && m_context.readBuffer.length; }
|
@property ulong leastSize() { waitForData(); return m_context && m_context.readBuffer.length; }
|
||||||
@property bool dataAvailableForRead() { return waitForData(0.seconds); }
|
@property bool dataAvailableForRead() { return waitForData(0.seconds); }
|
||||||
|
|
||||||
void close()
|
void close()
|
||||||
nothrow {
|
nothrow {
|
||||||
//logInfo("close %s", cast(int)m_fd);
|
//logInfo("close %s", cast(int)m_fd);
|
||||||
|
@ -522,7 +522,7 @@ struct TCPConnection {
|
||||||
m_context = null;
|
m_context = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool waitForData(Duration timeout = Duration.max)
|
bool waitForData(Duration timeout = Duration.max)
|
||||||
{
|
{
|
||||||
mixin(tracer);
|
mixin(tracer);
|
||||||
|
@ -602,7 +602,7 @@ mixin(tracer);
|
||||||
auto res = asyncAwait!(IOCallback,
|
auto res = asyncAwait!(IOCallback,
|
||||||
cb => eventDriver.sockets.write(m_socket, bytes, mode, cb),
|
cb => eventDriver.sockets.write(m_socket, bytes, mode, cb),
|
||||||
cb => eventDriver.sockets.cancelWrite(m_socket));
|
cb => eventDriver.sockets.cancelWrite(m_socket));
|
||||||
|
|
||||||
switch (res[1]) {
|
switch (res[1]) {
|
||||||
default:
|
default:
|
||||||
throw new Exception("Error writing data to socket.");
|
throw new Exception("Error writing data to socket.");
|
||||||
|
@ -667,7 +667,7 @@ private void loopWithTimeout(alias LoopBody, ExceptionType = Exception)(Duration
|
||||||
do {
|
do {
|
||||||
if (LoopBody(timeout))
|
if (LoopBody(timeout))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (timeout != Duration.max) {
|
if (timeout != Duration.max) {
|
||||||
auto prev = now;
|
auto prev = now;
|
||||||
now = Clock.currTime(UTC());
|
now = Clock.currTime(UTC());
|
||||||
|
@ -722,7 +722,7 @@ struct UDPConnection {
|
||||||
Context* m_context;
|
Context* m_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
private this(ref NetworkAddress bind_address)
|
private this(ref NetworkAddress bind_address)
|
||||||
{
|
{
|
||||||
scope baddr = new RefAddress(bind_address.sockAddr, bind_address.sockAddrLen);
|
scope baddr = new RefAddress(bind_address.sockAddr, bind_address.sockAddrLen);
|
||||||
m_socket = eventDriver.sockets.createDatagramSocket(baddr, null);
|
m_socket = eventDriver.sockets.createDatagramSocket(baddr, null);
|
||||||
|
|
|
@ -391,7 +391,7 @@ struct GenericPath(F) {
|
||||||
|
|
||||||
/** Constructs a path from an input range of `Segment`s.
|
/** Constructs a path from an input range of `Segment`s.
|
||||||
|
|
||||||
Throws:
|
Throws:
|
||||||
Since path segments are pre-validated, this constructor does not
|
Since path segments are pre-validated, this constructor does not
|
||||||
throw an exception.
|
throw an exception.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -158,8 +158,8 @@ class LocalTaskSemaphore
|
||||||
LocalManualEvent m_signal;
|
LocalManualEvent m_signal;
|
||||||
}
|
}
|
||||||
|
|
||||||
this(uint max_locks)
|
this(uint max_locks)
|
||||||
{
|
{
|
||||||
m_maxLocks = max_locks;
|
m_maxLocks = max_locks;
|
||||||
m_signal = createManualEvent();
|
m_signal = createManualEvent();
|
||||||
}
|
}
|
||||||
|
@ -182,10 +182,10 @@ class LocalTaskSemaphore
|
||||||
than one.
|
than one.
|
||||||
*/
|
*/
|
||||||
bool tryLock()
|
bool tryLock()
|
||||||
{
|
{
|
||||||
if (available > 0)
|
if (available > 0)
|
||||||
{
|
{
|
||||||
m_locks++;
|
m_locks++;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -202,13 +202,13 @@ class LocalTaskSemaphore
|
||||||
|
|
||||||
if (tryLock())
|
if (tryLock())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ThreadWaiter w;
|
ThreadWaiter w;
|
||||||
w.priority = priority;
|
w.priority = priority;
|
||||||
w.seq = min(0, m_seq - w.priority);
|
w.seq = min(0, m_seq - w.priority);
|
||||||
if (++m_seq == uint.max)
|
if (++m_seq == uint.max)
|
||||||
rewindSeq();
|
rewindSeq();
|
||||||
|
|
||||||
() @trusted { m_waiters.insert(w); } ();
|
() @trusted { m_waiters.insert(w); } ();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -222,7 +222,7 @@ class LocalTaskSemaphore
|
||||||
|
|
||||||
/** Gives up an existing lock.
|
/** Gives up an existing lock.
|
||||||
*/
|
*/
|
||||||
void unlock()
|
void unlock()
|
||||||
{
|
{
|
||||||
assert(m_locks >= 1);
|
assert(m_locks >= 1);
|
||||||
m_locks--;
|
m_locks--;
|
||||||
|
@ -232,7 +232,7 @@ class LocalTaskSemaphore
|
||||||
|
|
||||||
// if true, a goes after b. ie. b comes out front()
|
// if true, a goes after b. ie. b comes out front()
|
||||||
/// private
|
/// private
|
||||||
static bool asc(ref ThreadWaiter a, ref ThreadWaiter b)
|
static bool asc(ref ThreadWaiter a, ref ThreadWaiter b)
|
||||||
{
|
{
|
||||||
if (a.priority != b.priority)
|
if (a.priority != b.priority)
|
||||||
return a.priority < b.priority;
|
return a.priority < b.priority;
|
||||||
|
@ -735,7 +735,7 @@ struct LocalManualEvent {
|
||||||
int wait(int emit_count) { return doWait!true(Duration.max, emit_count); }
|
int wait(int emit_count) { return doWait!true(Duration.max, emit_count); }
|
||||||
/// ditto
|
/// ditto
|
||||||
int wait(Duration timeout, int emit_count) { return doWait!true(timeout, emit_count); }
|
int wait(Duration timeout, int emit_count) { return doWait!true(timeout, emit_count); }
|
||||||
|
|
||||||
/** Same as $(D wait), but defers throwing any $(D InterruptException).
|
/** Same as $(D wait), but defers throwing any $(D InterruptException).
|
||||||
|
|
||||||
This method is annotated $(D nothrow) at the expense that it cannot be
|
This method is annotated $(D nothrow) at the expense that it cannot be
|
||||||
|
@ -905,7 +905,7 @@ struct ManualEvent {
|
||||||
int wait(int emit_count) shared { return doWaitShared!true(Duration.max, emit_count); }
|
int wait(int emit_count) shared { return doWaitShared!true(Duration.max, emit_count); }
|
||||||
/// ditto
|
/// ditto
|
||||||
int wait(Duration timeout, int emit_count) shared { return doWaitShared!true(timeout, emit_count); }
|
int wait(Duration timeout, int emit_count) shared { return doWaitShared!true(timeout, emit_count); }
|
||||||
|
|
||||||
/** Same as $(D wait), but defers throwing any $(D InterruptException).
|
/** Same as $(D wait), but defers throwing any $(D InterruptException).
|
||||||
|
|
||||||
This method is annotated $(D nothrow) at the expense that it cannot be
|
This method is annotated $(D nothrow) at the expense that it cannot be
|
||||||
|
@ -1183,7 +1183,7 @@ private struct ThreadLocalWaiter {
|
||||||
} else {
|
} else {
|
||||||
asyncAwaitAny!interruptible(timeout, waitable);
|
asyncAwaitAny!interruptible(timeout, waitable);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (waitable.cancelled) {
|
if (waitable.cancelled) {
|
||||||
removeWaiter();
|
removeWaiter();
|
||||||
return false;
|
return false;
|
||||||
|
@ -1481,7 +1481,7 @@ private struct TaskConditionImpl(bool INTERRUPTIBLE, LOCKABLE) {
|
||||||
* the actual functionality of their method calls.
|
* the actual functionality of their method calls.
|
||||||
*
|
*
|
||||||
* The method implementations are based on two static parameters
|
* The method implementations are based on two static parameters
|
||||||
* ($(D INTERRUPTIBLE) and $(D INTENT)), which are configured through
|
* ($(D INTERRUPTIBLE) and $(D INTENT)), which are configured through
|
||||||
* template arguments:
|
* template arguments:
|
||||||
*
|
*
|
||||||
* - $(D INTERRUPTIBLE) determines whether the mutex implementation
|
* - $(D INTERRUPTIBLE) determines whether the mutex implementation
|
||||||
|
@ -1498,12 +1498,12 @@ private struct ReadWriteMutexState(bool INTERRUPTIBLE)
|
||||||
{
|
{
|
||||||
/** The policy with which the mutex should operate.
|
/** The policy with which the mutex should operate.
|
||||||
*
|
*
|
||||||
* The policy determines how the acquisition of the locks is
|
* The policy determines how the acquisition of the locks is
|
||||||
* performed and can be used to tune the mutex according to the
|
* performed and can be used to tune the mutex according to the
|
||||||
* underlying algorithm in which it is used.
|
* underlying algorithm in which it is used.
|
||||||
*
|
*
|
||||||
* According to the provided policy, the mutex will either favor
|
* According to the provided policy, the mutex will either favor
|
||||||
* reading or writing tasks and could potentially starve the
|
* reading or writing tasks and could potentially starve the
|
||||||
* respective opposite.
|
* respective opposite.
|
||||||
*
|
*
|
||||||
* cf. $(D core.sync.rwmutex.ReadWriteMutex.Policy)
|
* cf. $(D core.sync.rwmutex.ReadWriteMutex.Policy)
|
||||||
|
@ -1515,7 +1515,7 @@ private struct ReadWriteMutexState(bool INTERRUPTIBLE)
|
||||||
/** Writers are prioritized, readers may be starved as a result. */
|
/** Writers are prioritized, readers may be starved as a result. */
|
||||||
PREFER_WRITERS
|
PREFER_WRITERS
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The intent with which a locking operation is performed.
|
/** The intent with which a locking operation is performed.
|
||||||
*
|
*
|
||||||
* Since both locks share the same underlying algorithms, the actual
|
* Since both locks share the same underlying algorithms, the actual
|
||||||
|
@ -1531,23 +1531,23 @@ private struct ReadWriteMutexState(bool INTERRUPTIBLE)
|
||||||
* hold a lock at any given time. */
|
* hold a lock at any given time. */
|
||||||
READ_WRITE = 1
|
READ_WRITE = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
private {
|
private {
|
||||||
//Queue counters
|
//Queue counters
|
||||||
/** The number of reading tasks waiting for the lock to become available. */
|
/** The number of reading tasks waiting for the lock to become available. */
|
||||||
shared(uint) m_waitingForReadLock = 0;
|
shared(uint) m_waitingForReadLock = 0;
|
||||||
/** The number of writing tasks waiting for the lock to become available. */
|
/** The number of writing tasks waiting for the lock to become available. */
|
||||||
shared(uint) m_waitingForWriteLock = 0;
|
shared(uint) m_waitingForWriteLock = 0;
|
||||||
|
|
||||||
//Lock counters
|
//Lock counters
|
||||||
/** The number of reading tasks that currently hold the lock. */
|
/** The number of reading tasks that currently hold the lock. */
|
||||||
uint m_activeReadLocks = 0;
|
uint m_activeReadLocks = 0;
|
||||||
/** The number of writing tasks that currently hold the lock (binary). */
|
/** The number of writing tasks that currently hold the lock (binary). */
|
||||||
ubyte m_activeWriteLocks = 0;
|
ubyte m_activeWriteLocks = 0;
|
||||||
|
|
||||||
/** The policy determining the lock's behavior. */
|
/** The policy determining the lock's behavior. */
|
||||||
Policy m_policy;
|
Policy m_policy;
|
||||||
|
|
||||||
//Queue Events
|
//Queue Events
|
||||||
/** The event used to wake reading tasks waiting for the lock while it is blocked. */
|
/** The event used to wake reading tasks waiting for the lock while it is blocked. */
|
||||||
shared(ManualEvent) m_readyForReadLock;
|
shared(ManualEvent) m_readyForReadLock;
|
||||||
|
@ -1557,7 +1557,7 @@ private struct ReadWriteMutexState(bool INTERRUPTIBLE)
|
||||||
/** The underlying mutex that gates the access to the shared state. */
|
/** The underlying mutex that gates the access to the shared state. */
|
||||||
Mutex m_counterMutex;
|
Mutex m_counterMutex;
|
||||||
}
|
}
|
||||||
|
|
||||||
this(Policy policy)
|
this(Policy policy)
|
||||||
{
|
{
|
||||||
m_policy = policy;
|
m_policy = policy;
|
||||||
|
@ -1567,10 +1567,10 @@ private struct ReadWriteMutexState(bool INTERRUPTIBLE)
|
||||||
}
|
}
|
||||||
|
|
||||||
@disable this(this);
|
@disable this(this);
|
||||||
|
|
||||||
/** The policy with which the lock has been created. */
|
/** The policy with which the lock has been created. */
|
||||||
@property policy() const { return m_policy; }
|
@property policy() const { return m_policy; }
|
||||||
|
|
||||||
version(RWMutexPrint)
|
version(RWMutexPrint)
|
||||||
{
|
{
|
||||||
/** Print out debug information during lock operations. */
|
/** Print out debug information during lock operations. */
|
||||||
|
@ -1580,17 +1580,17 @@ private struct ReadWriteMutexState(bool INTERRUPTIBLE)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
import std.stdio;
|
import std.stdio;
|
||||||
writefln("RWMutex: %s (%s), active: RO: %d, RW: %d; waiting: RO: %d, RW: %d",
|
writefln("RWMutex: %s (%s), active: RO: %d, RW: %d; waiting: RO: %d, RW: %d",
|
||||||
OP.leftJustify(10,' '),
|
OP.leftJustify(10,' '),
|
||||||
INTENT == LockingIntent.READ_ONLY ? "RO" : "RW",
|
INTENT == LockingIntent.READ_ONLY ? "RO" : "RW",
|
||||||
m_activeReadLocks, m_activeWriteLocks,
|
m_activeReadLocks, m_activeWriteLocks,
|
||||||
m_waitingForReadLock, m_waitingForWriteLock
|
m_waitingForReadLock, m_waitingForWriteLock
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
catch (Throwable t){}
|
catch (Throwable t){}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** An internal shortcut method to determine the queue event for a given intent. */
|
/** An internal shortcut method to determine the queue event for a given intent. */
|
||||||
@property ref auto queueEvent(LockingIntent INTENT)()
|
@property ref auto queueEvent(LockingIntent INTENT)()
|
||||||
{
|
{
|
||||||
|
@ -1599,7 +1599,7 @@ private struct ReadWriteMutexState(bool INTERRUPTIBLE)
|
||||||
else
|
else
|
||||||
return m_readyForWriteLock;
|
return m_readyForWriteLock;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** An internal shortcut method to determine the queue counter for a given intent. */
|
/** An internal shortcut method to determine the queue counter for a given intent. */
|
||||||
@property ref auto queueCounter(LockingIntent INTENT)()
|
@property ref auto queueCounter(LockingIntent INTENT)()
|
||||||
{
|
{
|
||||||
|
@ -1608,13 +1608,13 @@ private struct ReadWriteMutexState(bool INTERRUPTIBLE)
|
||||||
else
|
else
|
||||||
return m_waitingForWriteLock;
|
return m_waitingForWriteLock;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** An internal shortcut method to determine the current emitCount of the queue counter for a given intent. */
|
/** An internal shortcut method to determine the current emitCount of the queue counter for a given intent. */
|
||||||
int emitCount(LockingIntent INTENT)()
|
int emitCount(LockingIntent INTENT)()
|
||||||
{
|
{
|
||||||
return queueEvent!INTENT.emitCount();
|
return queueEvent!INTENT.emitCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** An internal shortcut method to determine the active counter for a given intent. */
|
/** An internal shortcut method to determine the active counter for a given intent. */
|
||||||
@property ref auto activeCounter(LockingIntent INTENT)()
|
@property ref auto activeCounter(LockingIntent INTENT)()
|
||||||
{
|
{
|
||||||
|
@ -1623,8 +1623,8 @@ private struct ReadWriteMutexState(bool INTERRUPTIBLE)
|
||||||
else
|
else
|
||||||
return m_activeWriteLocks;
|
return m_activeWriteLocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** An internal shortcut method to wait for the queue event for a given intent.
|
/** An internal shortcut method to wait for the queue event for a given intent.
|
||||||
*
|
*
|
||||||
* This method is used during the `lock()` operation, after a
|
* This method is used during the `lock()` operation, after a
|
||||||
* `tryLock()` operation has been unsuccessfully finished.
|
* `tryLock()` operation has been unsuccessfully finished.
|
||||||
|
@ -1638,8 +1638,8 @@ private struct ReadWriteMutexState(bool INTERRUPTIBLE)
|
||||||
else
|
else
|
||||||
return queueEvent!INTENT.waitUninterruptible(count);
|
return queueEvent!INTENT.waitUninterruptible(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** An internal shortcut method to notify tasks waiting for the lock to become available again.
|
/** An internal shortcut method to notify tasks waiting for the lock to become available again.
|
||||||
*
|
*
|
||||||
* This method is called whenever the number of owners of the mutex hits
|
* This method is called whenever the number of owners of the mutex hits
|
||||||
* zero; this is basically the counterpart to `wait()`.
|
* zero; this is basically the counterpart to `wait()`.
|
||||||
|
@ -1656,12 +1656,12 @@ private struct ReadWriteMutexState(bool INTERRUPTIBLE)
|
||||||
{ //If a writer unlocks the mutex, notify both readers and writers
|
{ //If a writer unlocks the mutex, notify both readers and writers
|
||||||
if (atomicLoad(m_waitingForReadLock) > 0)
|
if (atomicLoad(m_waitingForReadLock) > 0)
|
||||||
m_readyForReadLock.emit();
|
m_readyForReadLock.emit();
|
||||||
|
|
||||||
if (atomicLoad(m_waitingForWriteLock) > 0)
|
if (atomicLoad(m_waitingForWriteLock) > 0)
|
||||||
m_readyForWriteLock.emit();
|
m_readyForWriteLock.emit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** An internal method that performs the acquisition attempt in different variations.
|
/** An internal method that performs the acquisition attempt in different variations.
|
||||||
*
|
*
|
||||||
* Since both locks rely on a common TaskMutex object which gates the access
|
* Since both locks rely on a common TaskMutex object which gates the access
|
||||||
|
@ -1669,15 +1669,15 @@ private struct ReadWriteMutexState(bool INTERRUPTIBLE)
|
||||||
* than for simple mutex variants. This method will thus be performing the
|
* than for simple mutex variants. This method will thus be performing the
|
||||||
* `tryLock()` operation in two variations, depending on the callee:
|
* `tryLock()` operation in two variations, depending on the callee:
|
||||||
*
|
*
|
||||||
* If called from the outside ($(D WAIT_FOR_BLOCKING_MUTEX) = false), the method
|
* If called from the outside ($(D WAIT_FOR_BLOCKING_MUTEX) = false), the method
|
||||||
* will instantly fail if the underlying mutex is locked (i.e. during another
|
* will instantly fail if the underlying mutex is locked (i.e. during another
|
||||||
* `tryLock()` or `unlock()` operation), in order to guarantee the fastest
|
* `tryLock()` or `unlock()` operation), in order to guarantee the fastest
|
||||||
* possible locking attempt.
|
* possible locking attempt.
|
||||||
*
|
*
|
||||||
* If used internally by the `lock()` method ($(D WAIT_FOR_BLOCKING_MUTEX) = true),
|
* If used internally by the `lock()` method ($(D WAIT_FOR_BLOCKING_MUTEX) = true),
|
||||||
* the operation will wait for the mutex to be available before deciding if
|
* the operation will wait for the mutex to be available before deciding if
|
||||||
* the lock can be acquired, since the attempt would anyway be repeated until
|
* the lock can be acquired, since the attempt would anyway be repeated until
|
||||||
* it succeeds. This will prevent frequent retries under heavy loads and thus
|
* it succeeds. This will prevent frequent retries under heavy loads and thus
|
||||||
* should ensure better performance.
|
* should ensure better performance.
|
||||||
*/
|
*/
|
||||||
@trusted bool tryLock(LockingIntent INTENT, bool WAIT_FOR_BLOCKING_MUTEX)()
|
@trusted bool tryLock(LockingIntent INTENT, bool WAIT_FOR_BLOCKING_MUTEX)()
|
||||||
|
@ -1685,7 +1685,7 @@ private struct ReadWriteMutexState(bool INTERRUPTIBLE)
|
||||||
//Log a debug statement for the attempt
|
//Log a debug statement for the attempt
|
||||||
version(RWMutexPrint)
|
version(RWMutexPrint)
|
||||||
printInfo!("tryLock",INTENT)();
|
printInfo!("tryLock",INTENT)();
|
||||||
|
|
||||||
//Try to acquire the lock
|
//Try to acquire the lock
|
||||||
static if (!WAIT_FOR_BLOCKING_MUTEX)
|
static if (!WAIT_FOR_BLOCKING_MUTEX)
|
||||||
{
|
{
|
||||||
|
@ -1694,43 +1694,43 @@ private struct ReadWriteMutexState(bool INTERRUPTIBLE)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_counterMutex.lock();
|
m_counterMutex.lock();
|
||||||
|
|
||||||
scope(exit)
|
scope(exit)
|
||||||
m_counterMutex.unlock();
|
m_counterMutex.unlock();
|
||||||
|
|
||||||
//Log a debug statement for the attempt
|
//Log a debug statement for the attempt
|
||||||
version(RWMutexPrint)
|
version(RWMutexPrint)
|
||||||
printInfo!("checkCtrs",INTENT)();
|
printInfo!("checkCtrs",INTENT)();
|
||||||
|
|
||||||
//Check if there's already an active writer
|
//Check if there's already an active writer
|
||||||
if (m_activeWriteLocks > 0)
|
if (m_activeWriteLocks > 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//If writers are preferred over readers, check whether there
|
//If writers are preferred over readers, check whether there
|
||||||
//currently is a writer in the waiting queue and abort if
|
//currently is a writer in the waiting queue and abort if
|
||||||
//that's the case.
|
//that's the case.
|
||||||
static if (INTENT == LockingIntent.READ_ONLY)
|
static if (INTENT == LockingIntent.READ_ONLY)
|
||||||
if (m_policy.PREFER_WRITERS && m_waitingForWriteLock > 0)
|
if (m_policy.PREFER_WRITERS && m_waitingForWriteLock > 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//If we are locking the mutex for writing, make sure that
|
//If we are locking the mutex for writing, make sure that
|
||||||
//there's no reader active.
|
//there's no reader active.
|
||||||
static if (INTENT == LockingIntent.READ_WRITE)
|
static if (INTENT == LockingIntent.READ_WRITE)
|
||||||
if (m_activeReadLocks > 0)
|
if (m_activeReadLocks > 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//We can successfully acquire the lock!
|
//We can successfully acquire the lock!
|
||||||
//Log a debug statement for the success.
|
//Log a debug statement for the success.
|
||||||
version(RWMutexPrint)
|
version(RWMutexPrint)
|
||||||
printInfo!("lock",INTENT)();
|
printInfo!("lock",INTENT)();
|
||||||
|
|
||||||
//Increase the according counter
|
//Increase the according counter
|
||||||
//(number of active readers/writers)
|
//(number of active readers/writers)
|
||||||
//and return a success code.
|
//and return a success code.
|
||||||
activeCounter!INTENT += 1;
|
activeCounter!INTENT += 1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Attempt to acquire the lock for a given intent.
|
/** Attempt to acquire the lock for a given intent.
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
|
@ -1743,7 +1743,7 @@ private struct ReadWriteMutexState(bool INTERRUPTIBLE)
|
||||||
//TaskMutex - fail if it is already blocked.
|
//TaskMutex - fail if it is already blocked.
|
||||||
return tryLock!(INTENT,false)();
|
return tryLock!(INTENT,false)();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Acquire the lock for the given intent; yield and suspend until the lock has been acquired. */
|
/** Acquire the lock for the given intent; yield and suspend until the lock has been acquired. */
|
||||||
@trusted void lock(LockingIntent INTENT)()
|
@trusted void lock(LockingIntent INTENT)()
|
||||||
{
|
{
|
||||||
|
@ -1755,29 +1755,29 @@ private struct ReadWriteMutexState(bool INTERRUPTIBLE)
|
||||||
atomicOp!"+="(queueCounter!INTENT,1);
|
atomicOp!"+="(queueCounter!INTENT,1);
|
||||||
scope(exit)
|
scope(exit)
|
||||||
atomicOp!"-="(queueCounter!INTENT,1);
|
atomicOp!"-="(queueCounter!INTENT,1);
|
||||||
|
|
||||||
//Try to lock the mutex
|
//Try to lock the mutex
|
||||||
auto locked = tryLock!(INTENT,true)();
|
auto locked = tryLock!(INTENT,true)();
|
||||||
if (locked)
|
if (locked)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//Retry until we successfully acquired the lock
|
//Retry until we successfully acquired the lock
|
||||||
while(!locked)
|
while(!locked)
|
||||||
{
|
{
|
||||||
version(RWMutexPrint)
|
version(RWMutexPrint)
|
||||||
printInfo!("wait",INTENT)();
|
printInfo!("wait",INTENT)();
|
||||||
|
|
||||||
count = wait!INTENT(count);
|
count = wait!INTENT(count);
|
||||||
locked = tryLock!(INTENT,true)();
|
locked = tryLock!(INTENT,true)();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Unlock the mutex after a successful acquisition. */
|
/** Unlock the mutex after a successful acquisition. */
|
||||||
@trusted void unlock(LockingIntent INTENT)()
|
@trusted void unlock(LockingIntent INTENT)()
|
||||||
{
|
{
|
||||||
version(RWMutexPrint)
|
version(RWMutexPrint)
|
||||||
printInfo!("unlock",INTENT)();
|
printInfo!("unlock",INTENT)();
|
||||||
|
|
||||||
debug assert(activeCounter!INTENT > 0);
|
debug assert(activeCounter!INTENT > 0);
|
||||||
|
|
||||||
synchronized(m_counterMutex)
|
synchronized(m_counterMutex)
|
||||||
|
@ -1789,7 +1789,7 @@ private struct ReadWriteMutexState(bool INTERRUPTIBLE)
|
||||||
{
|
{
|
||||||
version(RWMutexPrint)
|
version(RWMutexPrint)
|
||||||
printInfo!("notify",INTENT)();
|
printInfo!("notify",INTENT)();
|
||||||
|
|
||||||
notify!INTENT();
|
notify!INTENT();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1800,20 +1800,20 @@ private struct ReadWriteMutexState(bool INTERRUPTIBLE)
|
||||||
*
|
*
|
||||||
* This mutex can be used in exchange for a $(D core.sync.mutex.ReadWriteMutex),
|
* This mutex can be used in exchange for a $(D core.sync.mutex.ReadWriteMutex),
|
||||||
* but does not block the event loop in contention situations. The `reader` and `writer`
|
* but does not block the event loop in contention situations. The `reader` and `writer`
|
||||||
* members are used for locking. Locking the `reader` mutex allows access to multiple
|
* members are used for locking. Locking the `reader` mutex allows access to multiple
|
||||||
* readers at once, while the `writer` mutex only allows a single writer to lock it at
|
* readers at once, while the `writer` mutex only allows a single writer to lock it at
|
||||||
* any given time. Locks on `reader` and `writer` are mutually exclusive (i.e. whenever a
|
* any given time. Locks on `reader` and `writer` are mutually exclusive (i.e. whenever a
|
||||||
* writer is active, no readers can be active at the same time, and vice versa).
|
* writer is active, no readers can be active at the same time, and vice versa).
|
||||||
*
|
*
|
||||||
* Notice:
|
* Notice:
|
||||||
* Mutexes implemented by this class cannot be interrupted
|
* Mutexes implemented by this class cannot be interrupted
|
||||||
* using $(D vibe.core.task.Task.interrupt()). The corresponding
|
* using $(D vibe.core.task.Task.interrupt()). The corresponding
|
||||||
* InterruptException will be deferred until the next blocking
|
* InterruptException will be deferred until the next blocking
|
||||||
* operation yields the event loop.
|
* operation yields the event loop.
|
||||||
*
|
*
|
||||||
* Use $(D InterruptibleTaskReadWriteMutex) as an alternative that can be
|
* Use $(D InterruptibleTaskReadWriteMutex) as an alternative that can be
|
||||||
* interrupted.
|
* interrupted.
|
||||||
*
|
*
|
||||||
* cf. $(D core.sync.mutex.ReadWriteMutex)
|
* cf. $(D core.sync.mutex.ReadWriteMutex)
|
||||||
*/
|
*/
|
||||||
class TaskReadWriteMutex
|
class TaskReadWriteMutex
|
||||||
|
@ -1823,29 +1823,29 @@ class TaskReadWriteMutex
|
||||||
alias LockingIntent = State.LockingIntent;
|
alias LockingIntent = State.LockingIntent;
|
||||||
alias READ_ONLY = LockingIntent.READ_ONLY;
|
alias READ_ONLY = LockingIntent.READ_ONLY;
|
||||||
alias READ_WRITE = LockingIntent.READ_WRITE;
|
alias READ_WRITE = LockingIntent.READ_WRITE;
|
||||||
|
|
||||||
/** The shared state used by the reader and writer mutexes. */
|
/** The shared state used by the reader and writer mutexes. */
|
||||||
State m_state;
|
State m_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The policy with which the mutex should operate.
|
/** The policy with which the mutex should operate.
|
||||||
*
|
*
|
||||||
* The policy determines how the acquisition of the locks is
|
* The policy determines how the acquisition of the locks is
|
||||||
* performed and can be used to tune the mutex according to the
|
* performed and can be used to tune the mutex according to the
|
||||||
* underlying algorithm in which it is used.
|
* underlying algorithm in which it is used.
|
||||||
*
|
*
|
||||||
* According to the provided policy, the mutex will either favor
|
* According to the provided policy, the mutex will either favor
|
||||||
* reading or writing tasks and could potentially starve the
|
* reading or writing tasks and could potentially starve the
|
||||||
* respective opposite.
|
* respective opposite.
|
||||||
*
|
*
|
||||||
* cf. $(D core.sync.rwmutex.ReadWriteMutex.Policy)
|
* cf. $(D core.sync.rwmutex.ReadWriteMutex.Policy)
|
||||||
*/
|
*/
|
||||||
alias Policy = State.Policy;
|
alias Policy = State.Policy;
|
||||||
|
|
||||||
/** A common baseclass for both of the provided mutexes.
|
/** A common baseclass for both of the provided mutexes.
|
||||||
*
|
*
|
||||||
* The intent for the according mutex is specified through the
|
* The intent for the according mutex is specified through the
|
||||||
* $(D INTENT) template argument, which determines if a mutex is
|
* $(D INTENT) template argument, which determines if a mutex is
|
||||||
* used for read or write locking.
|
* used for read or write locking.
|
||||||
*/
|
*/
|
||||||
final class Mutex(LockingIntent INTENT): core.sync.mutex.Mutex, Lockable
|
final class Mutex(LockingIntent INTENT): core.sync.mutex.Mutex, Lockable
|
||||||
|
@ -1859,17 +1859,17 @@ class TaskReadWriteMutex
|
||||||
}
|
}
|
||||||
alias Reader = Mutex!READ_ONLY;
|
alias Reader = Mutex!READ_ONLY;
|
||||||
alias Writer = Mutex!READ_WRITE;
|
alias Writer = Mutex!READ_WRITE;
|
||||||
|
|
||||||
Reader reader;
|
Reader reader;
|
||||||
Writer writer;
|
Writer writer;
|
||||||
|
|
||||||
this(Policy policy = Policy.PREFER_WRITERS)
|
this(Policy policy = Policy.PREFER_WRITERS)
|
||||||
{
|
{
|
||||||
m_state = State(policy);
|
m_state = State(policy);
|
||||||
reader = new Reader();
|
reader = new Reader();
|
||||||
writer = new Writer();
|
writer = new Writer();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The policy with which the lock has been created. */
|
/** The policy with which the lock has been created. */
|
||||||
@property Policy policy() const { return m_state.policy; }
|
@property Policy policy() const { return m_state.policy; }
|
||||||
}
|
}
|
||||||
|
@ -1878,7 +1878,7 @@ class TaskReadWriteMutex
|
||||||
*
|
*
|
||||||
* This class supports the use of $(D vibe.core.task.Task.interrupt()) while
|
* This class supports the use of $(D vibe.core.task.Task.interrupt()) while
|
||||||
* waiting in the `lock()` method.
|
* waiting in the `lock()` method.
|
||||||
*
|
*
|
||||||
* cf. $(D core.sync.mutex.ReadWriteMutex)
|
* cf. $(D core.sync.mutex.ReadWriteMutex)
|
||||||
*/
|
*/
|
||||||
class InterruptibleTaskReadWriteMutex
|
class InterruptibleTaskReadWriteMutex
|
||||||
|
@ -1890,31 +1890,31 @@ class InterruptibleTaskReadWriteMutex
|
||||||
alias LockingIntent = State.LockingIntent;
|
alias LockingIntent = State.LockingIntent;
|
||||||
alias READ_ONLY = LockingIntent.READ_ONLY;
|
alias READ_ONLY = LockingIntent.READ_ONLY;
|
||||||
alias READ_WRITE = LockingIntent.READ_WRITE;
|
alias READ_WRITE = LockingIntent.READ_WRITE;
|
||||||
|
|
||||||
/** The shared state used by the reader and writer mutexes. */
|
/** The shared state used by the reader and writer mutexes. */
|
||||||
State m_state;
|
State m_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The policy with which the mutex should operate.
|
/** The policy with which the mutex should operate.
|
||||||
*
|
*
|
||||||
* The policy determines how the acquisition of the locks is
|
* The policy determines how the acquisition of the locks is
|
||||||
* performed and can be used to tune the mutex according to the
|
* performed and can be used to tune the mutex according to the
|
||||||
* underlying algorithm in which it is used.
|
* underlying algorithm in which it is used.
|
||||||
*
|
*
|
||||||
* According to the provided policy, the mutex will either favor
|
* According to the provided policy, the mutex will either favor
|
||||||
* reading or writing tasks and could potentially starve the
|
* reading or writing tasks and could potentially starve the
|
||||||
* respective opposite.
|
* respective opposite.
|
||||||
*
|
*
|
||||||
* cf. $(D core.sync.rwmutex.ReadWriteMutex.Policy)
|
* cf. $(D core.sync.rwmutex.ReadWriteMutex.Policy)
|
||||||
*/
|
*/
|
||||||
alias Policy = State.Policy;
|
alias Policy = State.Policy;
|
||||||
|
|
||||||
/** A common baseclass for both of the provided mutexes.
|
/** A common baseclass for both of the provided mutexes.
|
||||||
*
|
*
|
||||||
* The intent for the according mutex is specified through the
|
* The intent for the according mutex is specified through the
|
||||||
* $(D INTENT) template argument, which determines if a mutex is
|
* $(D INTENT) template argument, which determines if a mutex is
|
||||||
* used for read or write locking.
|
* used for read or write locking.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
final class Mutex(LockingIntent INTENT): core.sync.mutex.Mutex, Lockable
|
final class Mutex(LockingIntent INTENT): core.sync.mutex.Mutex, Lockable
|
||||||
{
|
{
|
||||||
|
@ -1927,17 +1927,17 @@ class InterruptibleTaskReadWriteMutex
|
||||||
}
|
}
|
||||||
alias Reader = Mutex!READ_ONLY;
|
alias Reader = Mutex!READ_ONLY;
|
||||||
alias Writer = Mutex!READ_WRITE;
|
alias Writer = Mutex!READ_WRITE;
|
||||||
|
|
||||||
Reader reader;
|
Reader reader;
|
||||||
Writer writer;
|
Writer writer;
|
||||||
|
|
||||||
this(Policy policy = Policy.PREFER_WRITERS)
|
this(Policy policy = Policy.PREFER_WRITERS)
|
||||||
{
|
{
|
||||||
m_state = State(policy);
|
m_state = State(policy);
|
||||||
reader = new Reader();
|
reader = new Reader();
|
||||||
writer = new Writer();
|
writer = new Writer();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The policy with which the lock has been created. */
|
/** The policy with which the lock has been created. */
|
||||||
@property Policy policy() const { return m_state.policy; }
|
@property Policy policy() const { return m_state.policy; }
|
||||||
}
|
}
|
|
@ -77,7 +77,7 @@ struct Task {
|
||||||
}
|
}
|
||||||
|
|
||||||
package @property ref ThreadInfo tidInfo() @system { return m_fiber ? taskFiber.tidInfo : s_tidInfo; } // FIXME: this is not thread safe!
|
package @property ref ThreadInfo tidInfo() @system { return m_fiber ? taskFiber.tidInfo : s_tidInfo; } // FIXME: this is not thread safe!
|
||||||
|
|
||||||
@property Tid tid() @trusted { return tidInfo.ident; }
|
@property Tid tid() @trusted { return tidInfo.ident; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,7 +341,7 @@ final package class TaskFiber : Fiber {
|
||||||
import std.concurrency : Tid, thisTid;
|
import std.concurrency : Tid, thisTid;
|
||||||
import std.encoding : sanitize;
|
import std.encoding : sanitize;
|
||||||
import vibe.core.core : isEventLoopRunning, recycleFiber, taskScheduler, yield;
|
import vibe.core.core : isEventLoopRunning, recycleFiber, taskScheduler, yield;
|
||||||
|
|
||||||
version (VibeDebugCatchAll) alias UncaughtException = Throwable;
|
version (VibeDebugCatchAll) alias UncaughtException = Throwable;
|
||||||
else alias UncaughtException = Exception;
|
else alias UncaughtException = Exception;
|
||||||
try {
|
try {
|
||||||
|
@ -725,7 +725,7 @@ package struct TaskScheduler {
|
||||||
|
|
||||||
/** Holds execution until the task gets explicitly resumed.
|
/** Holds execution until the task gets explicitly resumed.
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
void hibernate()
|
void hibernate()
|
||||||
{
|
{
|
||||||
|
|
|
@ -47,7 +47,7 @@ shared class TaskPool {
|
||||||
threads.length = thread_count;
|
threads.length = thread_count;
|
||||||
foreach (i; 0 .. thread_count) {
|
foreach (i; 0 .. thread_count) {
|
||||||
WorkerThread thr;
|
WorkerThread thr;
|
||||||
() @trusted {
|
() @trusted {
|
||||||
thr = new WorkerThread(this);
|
thr = new WorkerThread(this);
|
||||||
thr.name = format("vibe-%s", i);
|
thr.name = format("vibe-%s", i);
|
||||||
thr.start();
|
thr.start();
|
||||||
|
@ -338,7 +338,7 @@ nothrow @safe:
|
||||||
bool consume(ref TaskFuncInfo tfi)
|
bool consume(ref TaskFuncInfo tfi)
|
||||||
{
|
{
|
||||||
import std.algorithm.mutation : swap;
|
import std.algorithm.mutation : swap;
|
||||||
|
|
||||||
if (m_queue.empty) return false;
|
if (m_queue.empty) return false;
|
||||||
swap(tfi, m_queue.front);
|
swap(tfi, m_queue.front);
|
||||||
m_queue.popFront();
|
m_queue.popFront();
|
||||||
|
|
|
@ -61,7 +61,7 @@ struct Waitable(CB, alias wait, alias cancel, on_result...)
|
||||||
|
|
||||||
bool cancelled;
|
bool cancelled;
|
||||||
auto waitCallback(Callback cb) nothrow { return wait(cb); }
|
auto waitCallback(Callback cb) nothrow { return wait(cb); }
|
||||||
|
|
||||||
static if (is(ReturnType!waitCallback == void))
|
static if (is(ReturnType!waitCallback == void))
|
||||||
void cancelCallback(Callback cb) nothrow { cancel(cb); }
|
void cancelCallback(Callback cb) nothrow { cancel(cb); }
|
||||||
else
|
else
|
||||||
|
|
|
@ -163,7 +163,7 @@ struct InterfaceProxy(I) if (is(I == interface)) {
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
mixin(impl());
|
mixin(impl());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -440,7 +440,7 @@ template checkInterfaceConformance(T, I) {
|
||||||
}
|
}
|
||||||
alias checkMemberConformance = impl!0;
|
alias checkMemberConformance = impl!0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template impl(size_t i) {
|
template impl(size_t i) {
|
||||||
static if (i < Members.length) {
|
static if (i < Members.length) {
|
||||||
static if (__traits(compiles, __traits(getMember, I, Members[i])))
|
static if (__traits(compiles, __traits(getMember, I, Members[i])))
|
||||||
|
|
|
@ -70,13 +70,13 @@ void runTest()
|
||||||
remove(bar);
|
remove(bar);
|
||||||
watcher = Path(dir).watchDirectory(Yes.recursive);
|
watcher = Path(dir).watchDirectory(Yes.recursive);
|
||||||
write(foo, null);
|
write(foo, null);
|
||||||
sleep(1.seconds);
|
sleep(1.seconds);
|
||||||
write(foo, [0, 1]);
|
write(foo, [0, 1]);
|
||||||
sleep(100.msecs);
|
sleep(100.msecs);
|
||||||
remove(foo);
|
remove(foo);
|
||||||
|
|
||||||
write(bar, null);
|
write(bar, null);
|
||||||
sleep(1.seconds);
|
sleep(1.seconds);
|
||||||
write(bar, [0, 1]);
|
write(bar, [0, 1]);
|
||||||
sleep(100.msecs);
|
sleep(100.msecs);
|
||||||
remove(bar);
|
remove(bar);
|
||||||
|
|
|
@ -20,7 +20,7 @@ void test()
|
||||||
assert(gotit);
|
assert(gotit);
|
||||||
sleep(10.msecs);
|
sleep(10.msecs);
|
||||||
});
|
});
|
||||||
|
|
||||||
t.tid.send(10);
|
t.tid.send(10);
|
||||||
t.tid.send(11); // never received
|
t.tid.send(11); // never received
|
||||||
t.join();
|
t.join();
|
||||||
|
@ -43,9 +43,9 @@ void test()
|
||||||
|
|
||||||
t3.tid.send(13);
|
t3.tid.send(13);
|
||||||
sleep(10.msecs);
|
sleep(10.msecs);
|
||||||
|
|
||||||
logInfo("Success.");
|
logInfo("Success.");
|
||||||
|
|
||||||
exitEventLoop(true);
|
exitEventLoop(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ void main()
|
||||||
} // expected
|
} // expected
|
||||||
}, conn);
|
}, conn);
|
||||||
auto wt = runTask!TCPConnection((conn) {
|
auto wt = runTask!TCPConnection((conn) {
|
||||||
sleep(1.msecs); // give the connection time to establish
|
sleep(1.msecs); // give the connection time to establish
|
||||||
try {
|
try {
|
||||||
conn.write(buf);
|
conn.write(buf);
|
||||||
assert(false, "Expected read() to throw an exception.");
|
assert(false, "Expected read() to throw an exception.");
|
||||||
|
|
Loading…
Reference in a new issue