@@ -12,10 +12,12 @@ * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ + +#include #include #include #ifndef OF_AMIGAOS4 # include @@ -76,12 +78,14 @@ .task = FindTask(NULL), .sigBit = AllocSignal(-1) }; bool ret; - if (waitingTask.sigBit == -1) + if (waitingTask.sigBit == -1) { + errno = EAGAIN; return false; + } Forbid(); if (!of_mutex_unlock(mutex)) { FreeSignal(waitingTask.sigBit); @@ -148,16 +152,20 @@ ULONG mask; bool ret; NewList(&port.mp_MsgList); - if (waitingTask.sigBit == -1 || port.mp_SigBit == -1) + if (waitingTask.sigBit == -1 || port.mp_SigBit == -1) { + errno = EAGAIN; goto fail; + } if (OpenDevice("timer.device", UNIT_MICROHZ, - (struct IORequest *)&request, 0) != 0) + (struct IORequest *)&request, 0) != 0) { + errno = EAGAIN; goto fail; + } Forbid(); if (!of_mutex_unlock(mutex)) { Permit(); @@ -167,12 +175,24 @@ waitingTask.next = condition->waitingTasks; condition->waitingTasks = &waitingTask; SendIO((struct IORequest *)&request); - mask = Wait((1 << waitingTask.sigBit) | (1 << port.mp_SigBit)); - ret = of_mutex_lock(mutex); + mask = Wait((1ul << waitingTask.sigBit) | (1ul << port.mp_SigBit)); + if (mask & (1ul << waitingTask.sigBit)) + ret = of_mutex_lock(mutex); + else if (mask & (1ul << port.mp_SigBit)) { + ret = false; + errno = ETIMEDOUT; + } else { + /* + * This should not happen - it means something interrupted the + * Wait(), so the best we can do is return EINTR. + */ + ret = false; + errno = EINTR; + } condition->waitingTasks = waitingTask.next; if (!CheckIO((struct IORequest *)&request)) { AbortIO((struct IORequest *)&request); @@ -180,13 +200,10 @@ } CloseDevice((struct IORequest *)&request); Permit(); - if (!(mask & (1 << waitingTask.sigBit))) - goto fail; - FreeSignal(waitingTask.sigBit); FreeSignal(port.mp_SigBit); return ret; @@ -202,13 +219,15 @@ bool of_condition_free(of_condition_t *condition) { Forbid(); @try { - if (condition->waitingTasks != NULL) + if (condition->waitingTasks != NULL) { + errno = EBUSY; return false; + } } @finally { Permit(); } return true; }