Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   Related Pages  

Wefts::Subscription Class Reference

subscribe/notify model abstraction. More...

#include <wefts_subscription.h>

Collaboration diagram for Wefts::Subscription:

Collaboration graph
[legend]
List of all members.

Public Methods

 Subscription (bool fairPolicy=true)
 Initializes the internal data of the condition.

bool subscribe (double time=0, Referenced **result=0)
 Subscribe to this object for a given amount of seconds.

bool subscribeNow (double time=0, Referenced **result=0)
 Subscribe to this object, clearing all previous notifications.

void notify (Referenced *data=0)
 Notifies that the subscription needs attention.

void notifyAll (Referenced *data=0)
 Notifies all the waiting threads at once NotifyAll sends a notification (or a "proceed" request) to every thread that is waiting with subscribe() or subscribeNow() method at the moment of its call.

int subscribers ()
 Returns the count of the subscribers currently waiting for this object to get a notification.

void setPolicy (bool fair)
 Sets or resets fair policy.


Private Methods

bool subscribeInternal (double time, Referenced **result)

Private Attributes

FastCondition m_cond
std::list< Referenced * > m_items
std::list< pthread_t > m_waiting
bool m_front
 True if fair policy is set.


Detailed Description

subscribe/notify model abstraction.

This class implements subscribe/notify model, with late subscription capabilities and FIFO (fair scheduling) policy.

In this model there are two kind of thread agents: the subscribers and the notifiers. The formers are threads willing to receive a "news" about something that happened or something that should be processed. The notifiers are the threads that can detect when there is something that the subscirbers should know, and that can eventually produce some data suitable of processing by the subscribers. Usually, subscribers are served in a FIFO order: the first thread that has subscriber an object will receive the first available notification. This feature can be turned off so that the first subscriber that is able to wake up is served with the newest notification; what the first subscriber woken up will be depends on OS choices. This is suitable in tasks where all the subscribers are equivalent, so that overhead needed to select the first subscriber in line is removed.

This model allows late subscription; this means that a notification issued by a thread will be left pending if no subscriber is currently waiting at the moment; as soon as a trherad subscribe, it receives immediately the notified message without blocking. An arbitrary amount of notify() can be issued before an equal amount of subscribe() is served in this way. A subscribing thread will only have to wait if there aren't currently pending notifications.

However, late subscription model is optional and can be controller both by the notifiers and the subscribers. The subscribeNow() method will discard any pending notification, and will put the calling thread in wait for a new notify() that must be issued after that moment. The notifyAll() method will notify all the waiting subscribers altogether; if there isn't any subscriber waiting when notifyAll() is called, then the notification is not left pending; any subscription after a notifyAll() will block (unless other notify() messages were already pending before).

Subscription can be timed. A subscriber may block only for a certain amount of time, and then return the control to the calling thread if a notification is not issued in the meanwhile.

The most interesting part of the subscribe/notify model is that notifiers can present some data to the subscribers. An object of class Referenced can be passed to the subscriber receiving the notification. An application will subclass Referenced adding the data that it needs to be transferred to subscribers.

If a notifiers doesn't want to send any particular data to the subscriber, the subscriber will receive 0 as the reference parameter. If the subscriber fails to get a notification (because of a timeout or an interrupt), subscribe() will return false.

Reference class has also support for disposability. A notifier may issue some read-only data to the subscribers, and allocate this data i.e. in a private stack instead of creating a dynamic memory object that would be soon destroyed by the subscriber.

Also notifyAll() can send references of the notified object to the subscribers, as it will increment the reference count to the amount of the subscribed threads. Each subscriber must then use the value as a read-only data, and can dispose it by decrementing the reference count with the method decRef().

This class is pretty unefficient. In an enviroment where the notifiers and the subscribers have well known interactions, and limited complexity, it is better to just derive a new class from FastCondition, using its data as a mean to communicate between threads.

But this class does pretty efficiently ITS job, that is allowing threadsafe communication of subscribers and notifiers in complex patterns, expecially where the internal working of each agent of the process is isolated or abstracted.

Anyhow use this class to process relatively time-sparse data, as the synchronization of the subscribers and the notifiers may require several lock/signal cycles. Finally, this class works better if there is one subscriber and many notifiers than many soubscribers and one notifier; processing time of notifications is o( notifiers * subscribers^2 ) .

See also:
Referenced


Constructor & Destructor Documentation

Wefts::Subscription::Subscription bool    fairPolicy = true [inline]
 

Initializes the internal data of the condition.

Actually, the constructor does nothing.


Member Function Documentation

void Wefts::Subscription::notify Referenced   data = 0
 

Notifies that the subscription needs attention.

The notify() method leaves a notification so that the first thread that has subscribed in the past, or the first thread that will subscribe in the future, is immediately notified to proceed with elaboration. Notify() can also pass some data to the subscribers; if the parameter Referenced is given, that pointer will be returned by the subscribe() method in the waiting thread.

Parameters:
data  the data that must be returned by subscribe() or 0 for none.

void Wefts::Subscription::notifyAll Referenced   data = 0
 

Notifies all the waiting threads at once NotifyAll sends a notification (or a "proceed" request) to every thread that is waiting with subscribe() or subscribeNow() method at the moment of its call.

NotifyAll() can also pass some data to the subscribers; if the parameter Referenced is given, that will be returned by the subscribe() method in the waiting thread. For each subscription, a reference is added to data. If there aren't subscribers waiting when notifyAll() is called, then this notification is lost; notice that in this case, if the data passed as parameter is disposeable, it is destroyed anyway.

Parameters:
data  the data that must be returned by subscribe() or 0 for none.
See also:
subscribe() Referenced

void Wefts::Subscription::setPolicy bool    fair [inline]
 

Sets or resets fair policy.

A fair policy subscription is made so that the the subscibers are served in a FIFO queue; the first subscriber will get the first object that has been notified. If the policy is set to unfair, then the first subscribers that gets in control will get receive the notification.

Parameters:
fair  true to set policy to fair (FIFO), false to set it to unfair (OS dependant)

bool Wefts::Subscription::subscribe double    time = 0,
Referenced **    result = 0
 

Subscribe to this object for a given amount of seconds.

If time is set to zero, waits until a notify is issued, or until the wait is otherwise interrupted. If the timeout expires or the wait is interrupted, the method returns false, else it returns true. If the notification that has woken up the subscriber has a valid Referenced object, the result parameter will be filled with a valid poitner, else it will be set to 0.

Parameters:
time  maximum time to wait for a notification in seconds, or 0 to wait forever.
result  a pointer to a referenced object returned as notified object, if given. If not given, it is ignored.
Returns:
true if subscription is notified, false otherwise
See also:
Referenced

bool Wefts::Subscription::subscribeInternal double    time,
Referenced **    result
[private]
 

bool Wefts::Subscription::subscribeNow double    time = 0,
Referenced **    result = 0
 

Subscribe to this object, clearing all previous notifications.

This method works the same as subscribe(), except for the fact that all the pending notifications are removed before the thread begins to wait for new notifications.

Parameters:
time  time to wait for a notification in seconds
result  the notified object (if any) or 0. If not given, it is ignored.
Returns:
true on success or false on error or timeout
See also:
subscribe()

int Wefts::Subscription::subscribers   [inline]
 

Returns the count of the subscribers currently waiting for this object to get a notification.

Notice that the value returned could become invalid by the moment the calling thread is able to check or process it.


Member Data Documentation

FastCondition Wefts::Subscription::m_cond [private]
 

bool Wefts::Subscription::m_front [private]
 

True if fair policy is set.

std::list<Referenced *> Wefts::Subscription::m_items [private]
 

std::list<pthread_t> Wefts::Subscription::m_waiting [private]
 


The documentation for this class was generated from the following files:
Generated on Tue Aug 5 18:09:03 2003 for Wefts by doxygen1.2.18