Active Objects perform their task separated in time (control flow) and space (data) from the rest of the program. More...
#include <active-objects.h>


Public Member Functions | |
| void | push (message d) |
| void | push (vector< message > v) |
| virtual | ~ActiveObject () |
| virtual bool | terminated () |
Protected Member Functions | |
| ActiveObject (string name) | |
| elementResult | deactivate () |
| virtual bool | run (bool handle_as_many_as_possible) |
| virtual bool | handle () |
| virtual elementResult | handle (message) |
Protected Attributes | |
| deque< message > | handling |
| Scheduler * | scheduler |
Active Objects perform their task separated in time (control flow) and space (data) from the rest of the program.
Active objects do not share data between each other and they can only be accessed through message transfer (push). As a simple (but powerful) process model they allow the encapsulation of logical processes into syntactic units. Looking at the code we know automatically which thread will run through which section. Within an active object we can be sure of the following conditions:
When using an active object we know that
An active object can be locked to gain access to its outgoing queues (if these are present). When an active object is locked, it does not mean that the object cannot run. It merely means, that the incoming and outgoing queues are locked. To avoid concurrency problems at this front, the active object will copy the messages that require handling to a separate queue before calling handle.
| ActiveObject< message >::ActiveObject | ( | string | name | ) | [inline, protected] |
All active objects have a name, which can be used during debugging. the scheduler can be filled in, if not, a standard SpawnWhenActivated scheduler will be assigned.
| virtual ActiveObject< message >::~ActiveObject | ( | ) | [inline, virtual] |
Deletes the object. This method checks that the object is effectively deactivated. If not, it will throw an error
| elementResult ActiveObject< message >::deactivate | ( | ) | [inline, protected] |
Tells the object to no longer start a thread when a message arrives It also signals that the handle() routine should stop its work as well. The result of deactivate is always Done, which can be passed back to the outer handler directly. E.g:
elementResult terminate() { ... return deactive(); }
| virtual elementResult ActiveObject< message >::handle | ( | message | ) | [inline, protected, virtual] |
The standard queue handler (handle()), looks at each element in turn for each element it calls handle(T), which should return one of the following states
The standard implementation of this method prints an error and crashes.
| virtual bool ActiveObject< message >::handle | ( | ) | [inline, protected, virtual] |
This method will be called in its own (virtual) thread, to handle a collection of messages. The messages to be handled are listed in the protected handle field. That queue can be accessed and manipulated as necessary. This method should return true when it can perform more work or false when it has nothing more to do (handling empty for instance, or no useful message left in handling). The standard implementation will take the front of the handling queue and present it to the more specific handle(T) member. Based on the return of that function a decision is made for the specif handling element.
Reimplemented in ActiveFragmentCreator.
Referenced by ActiveObject< Smart< ActiveIndexReader_msg_ > >::handle().
| void ActiveObject< message >::push | ( | vector< message > | v | ) | [inline] |
Pushes a list of messages atomically into the incoming queue. The handling is of course not guaranteed to have the same boundaries as the atomic pushes.
| void ActiveObject< message >::push | ( | message | d | ) | [inline] |
Pushes a message to be processed asynchronously. This method can be publicly accessed and is the main access point to send a message to the active object. If the object should start in response to the message, it will contact the scheduler. This object will acquire the active object lock, push the message and release the lock.
Referenced by ActiveObject< Smart< ActiveIndexReader_msg_ > >::handle().
| virtual bool ActiveObject< message >::run | ( | bool | handle_as_many_as_possible | ) | [inline, protected, virtual] |
This method is called from within the scheduler. It should perform the runnable action, which in this case it the handling of messages. If handle_as_many_as_possible, it should perform as many steps as possible before returning. If not, it should return asap. This function should return true if a next call is required, false otherwise. The handle_as_many_as_possible is useful for speed purposes. If called from within a real thread, then there is no point int returning control once in a while to the calling thread. On the other hand, if called from within a virtual thunk based scheduler then it probably better to return control as often as possible. This function works closely together with the run method, which is the one that should be called from within a scheduler.
Implements Runnable.
| virtual bool ActiveObject< message >::terminated | ( | ) | [inline, virtual] |
returns true when there is no longer a scheduler. This function is used by the scheduler to detect that the object has been terminated. If so the scheduler will notify someone else of this fact.
Implements Runnable.
deque<message> ActiveObject< message >::handling [protected] |
To make the locking window as small as possible, we use two queues. The incoming queue accepts incoming messages and can only be altered when the active object is synchronized. The handling queue can be modified only by the active object and will contain the transferred messages from the incoming queue when handling messages.
Referenced by ActiveObject< Smart< ActiveIndexReader_msg_ > >::handle().
Scheduler* ActiveObject< message >::scheduler [protected] |
Describes the scheduler that will be contacted when this object requires activation. If the scheduler is set to NULL then the active object has been deactivated. Only when an object is deactivated can it be destroyed.
Referenced by ActiveObject< Smart< ActiveIndexReader_msg_ > >::ActiveObject(), ActiveObject< Smart< ActiveIndexReader_msg_ > >::deactivate(), ActiveObject< Smart< ActiveIndexReader_msg_ > >::terminated(), and ActiveObject< Smart< ActiveIndexReader_msg_ > >::~ActiveObject().
1.6.2