diff --git a/source/doap/client/client.d b/source/doap/client/client.d index 3e83367..a38ffe7 100644 --- a/source/doap/client/client.d +++ b/source/doap/client/client.d @@ -111,8 +111,13 @@ public class CoapClient // Shutdown the messaging layer this.messaging.close(); - // TODO: We must wake up other sleeprs with an error - // (somehow, pass it in, flag set) + // Cancel all active request futures + this.requestsLock.lock(); + foreach(CoapRequest curReq; outgoingRequests) + { + curReq.future.cancel(); + } + this.requestsLock.unlock(); } /** diff --git a/source/doap/client/package.d b/source/doap/client/package.d index 85e0e58..40a1ba2 100644 --- a/source/doap/client/package.d +++ b/source/doap/client/package.d @@ -1,4 +1,4 @@ module doap.client; public import doap.client.client : CoapClient; -public import doap.client.request : CoapRequestBuilder, CoapRequestFuture; \ No newline at end of file +public import doap.client.request : CoapRequestBuilder, CoapRequestFuture, RequestState; \ No newline at end of file diff --git a/source/doap/client/request.d b/source/doap/client/request.d index 0b4b182..139f352 100644 --- a/source/doap/client/request.d +++ b/source/doap/client/request.d @@ -257,6 +257,29 @@ package class CoapRequestBuilder import core.sync.mutex : Mutex; import core.sync.condition : Condition; + +/** + * The state of a `CoapRequestFuture` + */ +public enum RequestState +{ + /** + * The future has been created + */ + CREATED, + + /** + * The future has completed + * successfully + */ + COMPLETED, + + /** + * The future was cancelled + */ + CANCELLED +} + /** * This is returned to the user when he * does a finalizing call on a `CoapRequestBuilder` @@ -277,7 +300,12 @@ public class CoapRequestFuture * This is filled in by the * messaging layer. */ - private CoapPacket response; + private CoapPacket response; // TODO: Volatility? + + /** + * State of the future + */ + private RequestState state; // TODO: Volatility? /** * Mutex (for the condition to use) @@ -298,6 +326,7 @@ public class CoapRequestFuture */ package this() { + this.state = RequestState.CREATED; this.mutex = new Mutex(); this.condition = new Condition(mutex); } @@ -316,6 +345,23 @@ public class CoapRequestFuture // Set the received response this.response = response; + // Set completion state + this.state = RequestState.COMPLETED; + + // Wake up the sleepers + this.condition.notifyAll(); + } + + /** + * Cancels this future such that + * all calls to `get()` will + * unblock and throw an exception + */ + package void cancel() + { + // Set cancelled state + this.state = RequestState.CANCELLED; + // Wake up the sleepers this.condition.notifyAll(); } @@ -324,6 +370,8 @@ public class CoapRequestFuture * Blocks until the response is received * * Returns: the response as a `CoapPacket` + * Throws: + * CoapException on cancelled request */ public CoapPacket get() { @@ -337,7 +385,16 @@ public class CoapRequestFuture // Upon waking up release lock this.mutex.unlock(); - return this.response; + // If successfully completed + if(this.state == RequestState.COMPLETED) + { + return this.response; + } + // On error + else + { + throw new CoapException("Request future cancelled"); + } } public CoapPacket get(Duration timeout) @@ -361,4 +418,14 @@ public class CoapRequestFuture throw new CoapException("Timed out whilst waiting"); } } + + /** + * Returns the state of this future + * + * Returns: the state + */ + public RequestState getState() + { + return this.state; + } } \ No newline at end of file diff --git a/source/doap/protocol/packet.d b/source/doap/protocol/packet.d index 2432e91..160aed2 100644 --- a/source/doap/protocol/packet.d +++ b/source/doap/protocol/packet.d @@ -89,6 +89,10 @@ public class CoapPacket } // FIXME: Add options encoding + foreach(CoapOption option; orderOptions()) + { + encoded ~= encodeOption(option); + } // Set the payload marker encoded ~= PAYLOAD_MARKER; @@ -99,6 +103,20 @@ public class CoapPacket return encoded; } + // TODO: Make public in the future + private static ubyte[] encodeOption(CoapOption option) + { + // TODO: Implement this + return []; + } + + private CoapOption[] orderOptions() + { + // TODO: Implement ordering here + return this.options; + } + + public void setType(MessageType type) { this.type = type;