diff --git a/README.md b/README.md index dec93a2..dd275f4 100644 --- a/README.md +++ b/README.md @@ -23,9 +23,9 @@ dub add birchwood Birchwood depends on the following D libraries: -* `libsnooze` (atleast 1.0.0-beta) -* `eventy` (atleast 0.4.0) -* `dlog` (atleast 0.3.19) +* `libsnooze` (at least 1.2.0-beta) +* `eventy` (at least 0.4.0) +* `dlog` (at least 0.3.19) ## Usage diff --git a/dub.json b/dub.json index b7a3312..4973ba2 100644 --- a/dub.json +++ b/dub.json @@ -7,7 +7,7 @@ "dependencies": { "dlog": ">=0.3.19", "eventy": ">=0.4.0", - "libsnooze": ">=1.0.0-beta" + "libsnooze": ">=1.2.0-beta" }, "description": "A sane IRC framework for the D language", "license": "LGPL-3.0", diff --git a/source/birchwood/client/client.d b/source/birchwood/client/client.d index 9948794..112d957 100644 --- a/source/birchwood/client/client.d +++ b/source/birchwood/client/client.d @@ -19,6 +19,8 @@ import birchwood.client.receiver : ReceiverThread; import birchwood.client.sender : SenderThread; import birchwood.client.events; +import libsnooze.exceptions : SnoozeError; + import dlog; package __gshared Logger logger; @@ -807,22 +809,12 @@ public class Client : Thread /* Register default handler */ initEvents(); - // /** - // * Initialize the ready events for both the - // * receive and send queue managers, then after - // * doing so start both managers and spin for - // * both of them to enter a ready state (i.e. - // * they have ensured a waiting-pipe pair for - // * libsnooze exists) - // */ - /* Set the running status to true */ running = true; /* Start the receive queue and send queue managers */ this.receiver.start(); this.sender.start(); - // while(!receiver.isReady() || !sender.isReady()) {} /* Start the socket read-decode loop */ this.start(); @@ -838,6 +830,10 @@ public class Client : Thread { throw new BirchwoodException(ErrorType.INTERNAL_FAILURE, e.toString()); } + catch(SnoozeError e) + { + throw new BirchwoodException(ErrorType.INTERNAL_FAILURE, e.toString()); + } } // TODO: Do actual liveliness check here else diff --git a/source/birchwood/client/exceptions.d b/source/birchwood/client/exceptions.d index 5564f3d..36b7456 100644 --- a/source/birchwood/client/exceptions.d +++ b/source/birchwood/client/exceptions.d @@ -18,7 +18,10 @@ public enum ErrorType /** * This could occur from errors with `Eventy` * when setting up the signal handlers and - * event types + * event types. It can also occur if `libsnooze` + * has an error which would occur when calling + * `ensure(Thread)` for the `Receiver` and `Sender` + * threads */ INTERNAL_FAILURE, diff --git a/source/birchwood/client/receiver.d b/source/birchwood/client/receiver.d index ce106be..a0bafa2 100644 --- a/source/birchwood/client/receiver.d +++ b/source/birchwood/client/receiver.d @@ -48,7 +48,6 @@ public final class ReceiverThread : Thread * to be processed and received */ private Event receiveEvent; - // private bool hasEnsured; /** * The associated IRC client @@ -61,13 +60,17 @@ public final class ReceiverThread : Thread * * Params: * client = the Client to associate with + * Throws: + * `SnoozeError` on failure to construct an + * `Event` or ensure ourselves */ this(Client client) { super(&recvHandlerFunc); this.client = client; - this.receiveEvent = new Event(); // TODO: Catch any libsnooze error here - this.recvQueueLock = new Mutex(); + this.receiveEvent = new Event(); + this.recvQueueLock = new Mutex(); + this.receiveEvent.ensure(this); } /** @@ -88,10 +91,6 @@ public final class ReceiverThread : Thread /* Unlock queue */ recvQueueLock.unlock(); - // TODO: Add a "register" function which can initialize pipes - // ... without needing a wait, we'd need a ready flag though - // ... for receiver's thread start - /** * Wake up all threads waiting on this event * (if any, and if so it would only be the receiver) @@ -115,21 +114,6 @@ public final class ReceiverThread : Thread { // TODO: We could look at libsnooze wait starvation or mutex racing (future thought) - - // // Do a once-off call to `ensure()` here which then only runs once and - // // ... sets a `ready` flag for the Client to spin on. This ensures that - // // ... when the first received messages will be able to cause a wait - // // ... to immediately unblock rather than letting wait() register itself - // // ... and then require another receiveQ call to wake it up and process - // // ... the initial n messages + m new ones resulting in the second call - // if(hasEnsured == false) - // { - // receiveEvent.ensure(); - // hasEnsured = true; - // } - - // TODO: See above notes about libsnooze behaviour due - // ... to usage in our context try { receiveEvent.wait(); @@ -151,9 +135,7 @@ public final class ReceiverThread : Thread } continue; } - - - + /* Lock the receieve queue */ recvQueueLock.lock(); diff --git a/source/birchwood/client/sender.d b/source/birchwood/client/sender.d index 98769f6..2af5a1e 100644 --- a/source/birchwood/client/sender.d +++ b/source/birchwood/client/sender.d @@ -40,7 +40,6 @@ public final class SenderThread : Thread * to be processed and sent */ private Event sendEvent; - // private bool hasEnsured; /** * The associated IRC client @@ -53,13 +52,17 @@ public final class SenderThread : Thread * * Params: * client = the Client to associate with + * Throws: + * `SnoozeError` on failure to construct an + * `Event` or ensure ourselves */ this(Client client) { super(&sendHandlerFunc); this.client = client; - this.sendEvent = new Event(); // TODO: Catch any libsnooze error here + this.sendEvent = new Event(); this.sendQueueLock = new Mutex(); + this.sendEvent.ensure(this); } /** @@ -80,10 +83,6 @@ public final class SenderThread : Thread /* Unlock queue */ sendQueueLock.unlock(); - // TODO: Add a "register" function which can initialize pipes - // ... without needing a wait, we'd need a ready flag though - // ... for sender's thread start - /** * Wake up all threads waiting on this event * (if any, and if so it would only be the sender) @@ -91,7 +90,6 @@ public final class SenderThread : Thread sendEvent.notifyAll(); } - /** * The send queue worker function */ @@ -99,24 +97,10 @@ public final class SenderThread : Thread { while(client.running) { - // // Do a once-off call to `ensure()` here which then only runs once and - // // ... sets a `ready` flag for the Client to spin on. This ensures that - // // ... when the first sent messages will be able to cause a wait - // // ... to immediately unblock rather than letting wait() register itself - // // ... and then require another sendQ call to wake it up and process - // // ... the initial n messages + m new ones resulting in the second call - // if(hasEnsured == false) - // { - // sendEvent.ensure(); - // hasEnsured = true; - // } - // TODO: We could look at libsnooze wait starvation or mutex racing (future thought) /* TODO: handle normal messages (xCount with fakeLagInBetween) */ - // TODO: See above notes about libsnooze behaviour due - // ... to usage in our context try { sendEvent.wait(); @@ -140,13 +124,6 @@ public final class SenderThread : Thread } - - - // TODO: After the above call have a once-off call to `ensure()` here - // ... which then only runs once and sets a `ready` flag for the Client - // ... to spin on - - /* Lock queue */ sendQueueLock.lock();