| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- namespace PF {
- /** Queue of paths to be processed by the system */
- class ThreadControlQueue
- {
- Path head;
- Path tail;
- /** Create a new queue with the specified number of receivers.
- * It is important that the number of receivers is fixed.
- * Properties like AllReceiversBlocked rely on knowing the exact number of receivers using the Pop (or PopNoBlock) methods.
- */
- public ThreadControlQueue (int numReceivers) {
- }
- /** True if the queue is empty */
- public bool IsEmpty {
- get {
- return head == null;
- }
- }
- /** Push a path to the front of the queue */
- public void PushFront (Path path) {
- if (tail == null) {// (tail == null) ==> (head == null)
- head = path;
- tail = path;
- } else {
- path.next = head;
- head = path;
- }
- }
- /** Push a path to the end of the queue */
- public void Push (Path path) {
- if (tail == null) {// (tail == null) ==> (head == null)
- head = path;
- tail = path;
- } else {
- tail.next = path;
- tail = path;
- }
- }
- /** Pops the next item off the queue.
- * This call will block if there are no items in the queue or if the queue is currently blocked.
- *
- * \returns A Path object, guaranteed to be not null.
- * \throws QueueTerminationException if #TerminateReceivers has been called.
- * \throws System.InvalidOperationException if more receivers get blocked than the fixed count sent to the constructor
- */
- public Path Pop ()
- {
- if (this.head == null)
- {
- return null;
- }
- Path p = head;
- var newHead = head.next;
- if (newHead == null)
- {
- tail = null;
- }
- head.next = null;
- head = newHead;
- return p;
- }
- /** Pops the next item off the queue, this call will not block.
- * To ensure stability, the caller must follow this pattern.
- * 1. Call PopNoBlock(false), if a null value is returned, wait for a bit (e.g yield return null in a Unity coroutine)
- * 2. try again with PopNoBlock(true), if still null, wait for a bit
- * 3. Repeat from step 2.
- *
- * \throws QueueTerminationException if #TerminateReceivers has been called.
- * \throws System.InvalidOperationException if more receivers get blocked than the fixed count sent to the constructor
- */
- public Path PopNoBlock (bool blockedBefore)
- {
- if (this.head == null)
- {
- return null;
- }
- Path p = head;
- var newHead = head.next;
- if (newHead == null) {
- tail = null;
- }
- head.next = null;
- head = newHead;
- return p;
- }
- }
- }
|