Reading List

The Selfish Gene
The Psychopath Test: A Journey Through the Madness Industry
Bad Science
The Feynman Lectures on Physics
The Theory of Everything: The Origin and Fate of the Universe


ifknot's favorite books »

Monday 17 March 2014

Part (3/3): A general purpose thread-safe internally synchronized message queue.

Proxies: Who's wearing the trousers? 

TL;DR I want to be able to do this:

producer_active_object(enqueuer_proxy(concurrent_queue));
consumer_active_object(dequeuer_proxy(concurrent_queue));

Today' reference will mostly be:
The proxy pattern[1] provides restricted or modified access to hidden or protected resources. There are a few subsets of proxies:
  • remote proxy
  • virtual proxy
  • protection proxy
  • smart reference
The kind of proxy that the message_queue type needs is combination of the last 2 that offers:
  • Access to the head and tail of the message queue via its various private enqueue and dequeue member functions.
  • Counting the number of references to the message queue and closing it down when either there are no more interested consumer(s) or the producer(s) have finished producing. 
Okay so the design choices are to either:
  1. Have a zoo of some_message_queue types each with member functions for generating their own proxies that use the extremely useful friendship C++ language feature[2]
  2. Select a specific some_message_queue policy from the zoo and wrap it in a generic message_queue type which dishes out the head and tail proxies.
Well at least there is no goat in this problem so in true Monty Hall style 
"Let's see what's behind door number 2..." 

Okay so here is the design description:
  • A concurrent_queue wrapper shared_queue locked up tighter than a chastity belt.
  • 2 concurrent_queue befriended enqueuer and dequeuer proxies that template specialise on the queue type but both have the key of friendship to shared_queue's chastity.
  • 3(+) queue interfaces (for wait, try & timed wait queue access) carrying queue closure semantics.
And the class diagram that results:
libfbp queue package class diagram (created with GenMyModel)
Here is how to use these classes:

Producing this output:

1,2,3,4,5,

6,7,8,9,10, (°□°)╯︵ ┻━┻ Access to resource is closed!

The queue sharing shared_queue class that manages dequeuer(s) and enqueuer(s) and closes the underlying queue as appropriate:

The dequeuer class:

Full code for all the interacting queue classes at:  github.com/ifknot/libfbp

References:
[1] Wikipedia Proxy Pattern
[2] When should you use 'friend' in C++?

No comments:

Post a Comment