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

os::Looper Class Reference

#include <looper.h>

Inheritance diagram for os::Looper:

os::Handler os::Application os::Window os_priv::DirKeeper os::Alert os::FileRequester os::MenuWindow os::ProgressRequester List of all members.

Public Types

typedef std::map<int,Handler*> handler_map

Public Methods

 Looper (const std::string &cName, int nPriority=NORMAL_PRIORITY, int nPortSize=DEFAULT_PORT_SIZE)
 The looper constructor. More...

virtual ~Looper ()
 Looper destructor. More...

port_id GetMsgPort () const
 Obtain the low-level message port used by this looper. More...

thread_id GetThread () const
 Obtain the thread id of the looper thread. More...

proc_id GetProcess () const
 Obtain the process ID of the loopers thread. More...

status_t Lock ()
 Lock the looper object. More...

status_t Unlock ()
 Unlock the looper. More...

int GetLockCount (void) const
 Obtain the number of locks held on the looper. More...

thread_id GetLockingThread (void) const
 Obtaing the owner of the looper lock. More...

bool IsLocked () const
 Check if the looper lock is owned by the calling thread. More...

virtual thread_id Run ()
 Start and unlock the looper. More...

int Wait () const
status_t PostMessage (uint32 nCode)
 Deliver a message to the looper. More...

status_t PostMessage (Message *pcMsg)
 Deliver a message to the looper. More...

status_t PostMessage (uint32 cCode, Handler *pcHandler, Handler *pcReplyTo=NULL)
 Deliver a message to the looper. More...

status_t PostMessage (Message *pcMsg, Handler *pcHandler, Handler *pcReplyTo=NULL)
 Deliver a message to the looper. More...

void SpoolMessages ()
 Drain the low-level message port. More...

MessageGetCurrentMessage () const
 Obtaine the message currently being processed. More...

MessageDetachCurrentMessage ()
 Steal the current message. More...

virtual void DispatchMessage (Message *pcMessage, Handler *pcHandler)
 The loopers message handling callback. More...

virtual void Started ()
 Called by the looper thread before entering the message loop. More...

virtual bool Idle ()
 Hook called each time the message queue is drained. More...

MessageQueueGetMessageQueue () const
 Obtain the internal message queue used by the looper. More...

virtual bool OkToQuit ()
 Check if it is ok to break the loop. More...

virtual void Quit ()
 Unconditionally terminate the looper. More...

void AddTimer (Handler *pcTarget, int nID, bigtime_t nTimeout, bool bOneShot=true)
 Add a timer to the looper. More...

bool RemoveTimer (Handler *pcTarget, int nID)
 Delete a timer. More...

const handler_mapGetHandlerMap () const
 Get the internal handler list. More...

void AddHandler (Handler *pcHandler)
 Add a handler to the looper. More...

bool RemoveHandler (Handler *pcHandler)
 Remove a handler previously added by AddHandler(). More...

HandlerFindHandler (const std::string &cName) const
 Search the looper for a named handler. More...

int GetHandlerCount () const
 Obtain the count of handlers added to this looper. More...

void SetDefaultHandler (Handler *pcHandler)
 Set the default target for incomming messages. More...

HandlerGetDefaultHandler () const
 Obtain the default handler for the looper. More...


Friends

class  Application
class  Messenger
class  NodeMonitor

Detailed Description

Description:
See also:
Author(s):
Kurt Skauen (kurt@atheos.cx)


Member Typedef Documentation

typedef std::map< int, Handler *> os::Looper::handler_map
 


Constructor & Destructor Documentation

Looper::Looper ( const std::string & cName,
int nPriority = NORMAL_PRIORITY,
int nPortSize = DEFAULT_PORT_SIZE )
 

The looper constructor.

This is the only Looper constructor. It initiates the looper and create the needed message port and message queue, but it does not spawn a new thread. To actually start the message loop you must call Run(). Before the constructor returns it will lock the looper by calling Lock(). This means that before any other threads are able to access it you must call Unlock().

Parameters:
pzName   - Passed down to the Handler::Handler() constructor.
nPriority   - Stored for later usage as the looper-thread priority.
nPortSize   - Maximum number of pending messages.
See also:
Handler::Handler()
Author(s):
Kurt Skauen (kurt@atheos.cx)

Looper::~Looper ( ) [virtual]
 

Looper destructor.

See also:
Looper::Looper()
Author(s):
Kurt Skauen (kurt@atheos.cx)


Member Function Documentation

void Looper::AddHandler ( Handler * pcHandler )
 

Add a handler to the looper.

Description:
Adds a handler to the looper. In order to receive messages, and before it can be set as the default handler, a handler must be added to a looper. The handler must not be member of any looper when added.
Parameters:
pcHandler   - Pointer to the handler to be added.
See also:
RemoveHandler(), SetDefaultHandler()
Author(s):
Kurt Skauen (kurt@atheos.cx)

void Looper::AddTimer ( Handler * pcTarget,
int nID,
bigtime_t nPeriode,
bool bOneShot = true )
 

Add a timer to the looper.

Description:
Timers should be employed when you have a small task that should be run periodically, or that you would like to schedule some point ahead in time. A timer is targeted at a spesific handler, and will cause the Handler::TimerTick() function to be called each time the timer fire. You can add an arbritary number of timers to a looper. The Handler::TimerTick() will be called by the looper thread, with the looper locked.
Note:
As with every callbacks from the looper thread, you should not do any long-lasting computing in the Handler::TimerTick() function. The looper will not be able to handle any messages until the function returns. This can cause the application to feel unresponsive. If you have any long-lasting tasks, you hould spawn a new thread to get the job done.
Parameters:
pcTarget   - Must be a valid ponter to a handler belonging to this looper. This is the handler that will get it's TimerTick() member called.
nID   - An user defined ID that is passed to the TimerTick() function to make it possible to distinguish different timers.
nPeriode   - Time in micro seconds before the timer fires. If not in one-shot mode, the timer will be rescheduled with the same delay until manually removed.
bOneShot   - If true the timer will fire once, and then be removed. If false the timer will be continually rescheduled until removed by Looper::RemoveTimer().

See also:
Looper::RemoveTimer(),Handler::TimerTick()
Author(s):
Kurt Skauen (kurt@atheos.cx)

Message * Looper::DetachCurrentMessage ( )
 

Steal the current message.

Description:
GetCurrentMessage() does basically the same job as Looper::GetCurrentMessage() except that it detatch the message from the looper, preventing it from being automatically deleted. You are responsible of getting rid of it when done.
Returns:
Pointer to a message, or NULL if no message is currently being processed.
See also:
Looper::GetCurrentMessage()
Author(s):
Kurt Skauen (kurt@atheos.cx)

void Looper::DispatchMessage ( Message * pcMsg,
Handler * pcHandler ) [virtual]
 

The loopers message handling callback.

Description:
When a message arrives, the looper extract's it from the queue and call this member with the message as a parameter. The default implementation will attempt to pass the message on to a Handler through it's HandleMessage() member. The Handler that should receive the message is selected as follows:

If the message targets a specific Handler, that Handler will receive the message. DispatchMessage() can determine wether the message had a final destination by examining the pcHandler argument. I not NULL it points at the handler targeted by the message.

If the message destination however is not fully qualified DispatchMessage() attempts to pass the message on to the Default handler (as set through the Looper::SetDefaultHandler()).

If there is no final destination and no default handler, the Looper will handle the message itself by calling its own version of HandleMessage() (The looper is itself a Handler)

Not all messages are passed on to a handler. If the message code is M_QUIT the Looper::OkToQuit() member is called instead, and if it return true Looper::Quit() will be called, and the message loop terminated.

If you would like to handle certain messages directly by the looper, bypassing the normal scheduling you can overload DispatchMessage() to process messages before they are passed on to any handler. If you do so, you should call the loopers version of DispatchMessage() for each message you don't know how to handle.

Note:
The looper is automatically locked prior to calling this member.
Parameters:
pcMsg   - Pointer to the received messge. Note that this message will be deleted when DispatchMessage() returns, unless detatched from the looper through DetachCurrentMessage().
pcHandler   - Pointer to the handler targeted by this message. If the message was not targeted at any spesific handler this argument is NULL.
See also:
SetDefaultHandler(), GetDefaultHandler(), PostMessage(), GetCurrentMessage() , DetachCurrentMessage(), Handler::HandleMessage()
Author(s):
Kurt Skauen (kurt@atheos.cx)

Reimplemented in os::Window.

Handler * Looper::FindHandler ( const std::string & cName ) const
 

Search the looper for a named handler.

Description:
Return the handler named <pzName>, or NULL if there is no such handler added to the looper.
Parameters:
pzName   - The name to search for.
Returns:
Pointer to the handler if one was found, NULL otherwise
See also:
GetHandler(), GetHandlerCount(), GetHandlerIndex() , AddHandler(), RemoveHandler()
Author(s):
Kurt Skauen (kurt@atheos.cx)

Message * Looper::GetCurrentMessage ( ) const
 

Obtaine the message currently being processed.

Description:
This member can be called from within Looper::DispatchMessage() or the active handlers Handler::HandleMessage() to learn whitch message is currently being processed. Given the fact that the very same message is passed to both this members, you may wonder why you should ever need to call this function? The reason is that many of the classes derived from eighter Looper, or Handler will convert known messages to specialized callbacks. These callbacks are normally not passed the entire message, only the most used elements. If you should find yourself in the unlucky situation of needing one of the not so much used elements, this member is the solution.
Note:
The message will be automatically deleted when you return to the message loop. To avoid this you should use Looper::DetachCurrentMessage() instead.

Called outside the message loop this member will return NULL.

Returns:
Pointer to a message, or NULL if no message is currently being processed.
See also:
Looper::DetachCurrentMessage(), Looper::DispatchMessage() , Handler::HandleMessage()
Author(s):
Kurt Skauen (kurt@atheos.cx)

Handler * Looper::GetDefaultHandler ( ) const
 

Obtain the default handler for the looper.

Description:
Return the handler last set by SetDefaultHandler() or NULL if there currently is no default handler
Returns:
Pointer to the default handler.
See also:
SetDefaultHandler()
Author(s):
Kurt Skauen (kurt@atheos.cx)

int Looper::GetHandlerCount ( ) const
 

Obtain the count of handlers added to this looper.

Returns:
Number of handlers currently attached to the looper
See also:
GetHandler(), AddHandler(), RemoveHandler()
Author(s):
Kurt Skauen (kurt@atheos.cx)

const Looper::handler_map & Looper::GetHandlerMap ( ) const
 

Get the internal handler list.

Description:
You can use this member to gain read-only access to the internal stl map of handlers. The map key is an unique ID that is assigned to each handler in the system (unique accross process boundaries). This ID should be considered a implemntation detail and are of no value outside the looper/handler implemntation itself. You can still traverse the map to examine the handlers that currently populate the looper. You should always keep the looper locked while examining the map.
Returns:
const reference to the internal stl map of handlers.
See also:
FindHandler(), AddHandler(), RemoveHandler()
Author(s):
Kurt Skauen (kurt@atheos.cx)

int Looper::GetLockCount ( void ) const
 

Obtain the number of locks held on the looper.

Description:
Return the nest count (number of locks held by the owner) from the internal mutex used to protect the looper.
Warning:
This function is dangerous in that it is very hard to use without encountering race condition, and are generally not very useful. The reason for including it is that it in some cases can be a useful help when debuggin a looper.
Returns:
Loopers lock nest count.
See also:
Author(s):
Kurt Skauen (kurt@atheos.cx)

thread_id Looper::GetLockingThread ( void ) const
 

Obtaing the owner of the looper lock.

Description:
Returns the thread ID of the thread currently holding the looper lock. If the looper is not locked, -1 is returned.
Warning:
This function is dangerous in that it is very hard to use without encountering race condition, and are generally not very useful. The reason for including it is that it in some cases can be a useful help when debuggin a looper.
Returns:
The thread ID of the lock owner or -1 if the looper is not locked.
See also:
GetLockCount(), Lock(), Unlock()
Author(s):
Kurt Skauen (kurt@atheos.cx)

MessageQueue * Looper::GetMessageQueue ( ) const
 

Obtain the internal message queue used by the looper.

Description:
You should rarely need to examine the message queue yourself, but it can be useful in vertain situations. F.eks. some messages comes in such an overwelming amount, and are of a nature that you can miss some of them without any harm. It is then useful to be able to look through the message queue when such a message arrive to check if there is more of them waiting and if so throw away the current message, and wait for the next to crawl its way down the queue. An example of such messages are the M_MOUSE_MOVED message. You will propably call SpoolMessages() before calling this message (but after locking the looper) to make sure the queue contains all messages sent to the looper.
Returns:
A pointer to the internal MessageQueue object used by the looper.
See also:
DispatchMessage(), PostMessage()
Author(s):
Kurt Skauen (kurt@atheos.cx)

port_id Looper::GetMsgPort ( ) const
 

Obtain the low-level message port used by this looper.

Returns:
The port ID of the internal message port.
See also:
Looper::GetMessageQueue(),Looper::GetCurrentMessage()
Author(s):
Kurt Skauen (kurt@atheos.cx)

proc_id Looper::GetProcess ( ) const
 

Obtain the process ID of the loopers thread.

Returns:
A valid process ID if the loop is running, -1 otherwise.
See also:
Looper::GetThread()
Author(s):
Kurt Skauen (kurt@atheos.cx)

thread_id Looper::GetThread ( ) const
 

Obtain the thread id of the looper thread.

Returns:
A valid thread ID if the loop is running, -1 otherwise.
See also:
Looper::GetProcess()
Author(s):
Kurt Skauen (kurt@atheos.cx)

bool Looper::Idle ( ) [virtual]
 

Hook called each time the message queue is drained.

Description:
Normally the looper thread is blocked on the internal message queue waiting for messages. When one or more messages arrive it will wake up and process the messages. When all messages is processed it will first call Idle() and then go back looking for more messages. If Idle() returned false the thread will block until the next message arrive and if Idle() returned true it will just look for new messages without blocking and call Idle() again (after processing new messages if any).
Note:
The looper will not be able to process new messages until Idle() returns so it is very important to not do anything lengthy if the looper is part of for example an os::Window since that will make the application feel "unresponcive" to the user.

Returns:
The Idle() function should return true if it want to be called again imediatly after the looper has polled for new messages, or false if it don't want to be called until at least one more message has been processed.
See also:
HandleMessage(), DispatchMessage()
Author(s):
Kurt Skauen (kurt@atheos.cx)

Reimplemented in os_priv::DirKeeper.

bool Looper::IsLocked ( ) const
 

Check if the looper lock is owned by the calling thread.

Warning:
I can't think of any safe usage of this function, other than as a debugging aid.
Returns:
See also:
Looper::Lock(), Looper::Unlock()
Author(s):
Kurt Skauen (kurt@atheos.cx)

status_t Looper::Lock ( )
 

Lock the looper object.

Description:
Before calling almost any other function on a looper or one of it's derived classes, you must lock it by calling this member. You can nest calls to Lock() within the same thread, each call to Lock() will then require a corresponding call to Unlock() to release the looper.

Looper::Lock() will not be affected by singnals that don't kill the thread. It will keep on retrying until it succed, or the failure was to someting else than a signal.
Note:
You should avoid keeping the looper locked for an extended periode of time, since that will prevent it from handling any messages, and can cause the application to feel unresponsive.
Returns:
Return 0, unless someting realy bad happened.
See also:
Looper::Unlock()
Author(s):
Kurt Skauen (kurt@atheos.cx)

bool Looper::OkToQuit ( ) [virtual]
 

Check if it is ok to break the loop.

Description:
You can overload this function to affect how the looper will react to M_QUIT messages. When an M_QUIT message arrive the looper will call this function to figure out what to do. If it returns false the message is ignored. If it returns true the loop is terminated, the looper object deleted and the looper thread will exit.

Returns:
true if it is ok to terminate the looper, false otherwise.
See also:
Quit(), PostMessage()
Author(s):
Kurt Skauen (kurt@atheos.cx)

status_t Looper::PostMessage ( Message * pcMsg,
Handler * pcHandler,
Handler * pcReplyHandler = NULL )
 

Deliver a message to the looper.

Description:
Post a message to a specific handler. The message is targeted to the handler pointed at by pcHandler, and the reply is set to the handler pointed at by pcReplyTo.
Note:
The caller is responsible for deleting the message (It is not deleted or kept by the looper)

You may not pass NULL as the target, but you can send a pointer to the looper itself to force it to handle the message.
Parameters:
nCode   - The code that should be assigned to the sendt message
pcHandler   - Must point to a valid handler that will receive the message.
pcReplyTo   - If not NULL should point to the handler that should receive the reply sendt to the message.

Returns:
0 if everyting went ok. If someting went wrong, a negative number is retuned, and the errno variable is set.
See also:
PostMessage( Message* pcMsg ), DispatchMessage()
Author(s):
Kurt Skauen (kurt@atheos.cx)

status_t Looper::PostMessage ( uint32 nCode,
Handler * pcHandler,
Handler * pcReplyTo = NULL )
 

Deliver a message to the looper.

Description:
Construct a message with the given code, and posts it to a specific handler by calling PostMessage( Message *pcMsg, Handler *pcHandler, Handler* pcReplyHandler )
Parameters:
nCode   - The code that should be assigned to the sendt message
pcHandler   - Must point to a valid handler that will receive the message.
pcReplyTo   - If not NULL should point to the handler that should receive the reply sendt to the message.

Returns:
0 if everyting went ok. If someting went wrong, a negative number is retuned, and the errno variable is set.
See also:
PostMessage( Message *pcMsg, Handler *pcHandler, Handler* pcReplyHandler ) , DispatchMessage()
Author(s):
Kurt Skauen (kurt@atheos.cx)

status_t Looper::PostMessage ( Message * pcMsg )
 

Deliver a message to the looper.

Description:
The message is posted to the looper with no absolute destination. This means that it will be handled by the default handler, or the looper itself if there is no default handler.
Note:
The caller is responsible for deleting the message (It is not deleted or kept by the looper)
Parameters:
pcMsg   - The message to post.
Returns:
0 if everyting went ok. If someting went wrong, a negative number is retuned, and the errno variable is set.
See also:
DispatchMessage()
Author(s):
Kurt Skauen (kurt@atheos.cx)

status_t Looper::PostMessage ( uint32 nCode )
 

Deliver a message to the looper.

Description:
Construct a message with the given code, and posts it to the looper by calling PostMessage( Message* pcMsg )
Parameters:
nCode   - The code that should be assigned to the sendt message
Returns:
0 if everyting went ok. If someting went wrong, a negative number is retuned, and the errno variable is set.
See also:
PostMessage( Message* pcMsg ),DispatchMessage()
Author(s):
Kurt Skauen (kurt@atheos.cx)

void Looper::Quit ( ) [virtual]
 

Unconditionally terminate the looper.

Description:
Calling quit will unconditionally terminates the looper (As opposed to post an M_QUIT message that will politly call OkToQuit() before terminating the looper). If the call is made by the looper thread itself this member will delete the looper object, and call exit_thread(). If an external thread made the call, a M_TERMINATE message is sendt, and the caller thread is blocked until the looper thread is dead. In eighter way the looper object gets deleted, and the looper thread dies.
See also:
OkToQuit(), PostMessage()
Author(s):
Kurt Skauen (kurt@atheos.cx)

bool Looper::RemoveHandler ( Handler * pcHandler )
 

Remove a handler previously added by AddHandler().

Description:
Removes a handler from the looper. If the default handler is removed the default looper pointer as returned by GetDefaultHandler() will be set to NULL.
Parameters:
pcHandler   - The handler to remove
Returns:
True if the Handler in fact was a member of the looper, false otherwise.
See also:
AddHandler(), SetDefaultHandler(), GetDefaultHandler()
Author(s):
Kurt Skauen (kurt@atheos.cx)

bool Looper::RemoveTimer ( Handler * pcTarget,
int nID )
 

Delete a timer.

When creating a timer in repeate mode, you will propably at some time want to get rid of it. This is the way to go.

Parameters:
-   pcTarget - The handler for which a timer is to be removed.
-   nID - The ID of the timer to be removed.

Returns:
True if the timer was found, false otherwise.
See also:
Looper::AddTimer(), Handler::TimerTick()
Author(s):
Kurt Skauen (kurt@atheos.cx)

thread_id Looper::Run ( ) [virtual]
 

Start and unlock the looper.

Description:
As mention in the description of the constructor, no thread are spawned there and the looper is locked. Calling Run() will spawn a new thread to run the message loop, and unlock the looper.
Note:
Not all loopers will spawn a new thread. F.eks. the Application class will overload the Run() member and lead the calling thread into the message loop. This means that when calling Run() on an application object it will not return until the loop terminates.
Returns:
The thread ID of the looper thread.
See also:
Quit(), OkToQuit(), PostMessage(), Lock(), Unlock()
Author(s):
Kurt Skauen (kurt@atheos.cx)

Reimplemented in os::Application.

void Looper::SetDefaultHandler ( Handler * pcHandler )
 

Set the default target for incomming messages.

Description:
Call this method to assign a handler as the default handler for the looper. When a handler become the default handler it will receive all messages that is not target directly at another handler. You can remove the current default handler by passing in a NULL pointer.
Parameters:
pcHandler   - The handler to set as default, or NULL
See also:
GetDefaultHandler(), DispatchMessage(), Handler::HandleMessage()
Author(s):
Kurt Skauen (kurt@atheos.cx)

void Looper::SpoolMessages ( )
 

Drain the low-level message port.

Description:
SpoolMessage() will fetch all messages from the low-level message port deflatten the message objects, and add the os::Message objects to the internal message queue
See also:
GetMessageQueue(), PostMessage()
Author(s):
Kurt Skauen (kurt@atheos.cx)

For internal use only.

void Looper::Started ( ) [virtual]
 

Called by the looper thread before entering the message loop.

Description:
This hook can be overloaded to do one-shot initialization of the looper that can not be done in the contructor. Started() is called from the loopers thread just before it start processing messages.
See also:
Idle(), Run()
Author(s):
Kurt Skauen (kurt@atheos.cx)

status_t Looper::Unlock ( )
 

Unlock the looper.

Returns:
Return 0, unless someting realy bad happened.
See also:
Looper::Lock()
Author(s):
Kurt Skauen (kurt@atheos.cx)

int Looper::Wait ( ) const
 


Friends And Related Function Documentation

class Application [friend]
 

class Messenger [friend]
 

Reimplemented from os::Handler.

class NodeMonitor [friend]
 

Reimplemented from os::Handler.


The documentation for this class was generated from the following files:
Generated at Sat Apr 7 16:11:36 2001 for AtheOS higlevel API by doxygen1.2.5 written by Dimitri van Heesch, © 1997-2001