All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
Public Member Functions | Protected Member Functions | List of all members
BLooper Class Reference

Receive and process messages in a separate thread. More...

Inherits BHandler.

Inherited by BApplication, BMediaRoster, and BWindow.

Public Member Functions

 BLooper (const char *name=NULL, int32 priority=B_NORMAL_PRIORITY, int32 portCapacity=B_LOOPER_PORT_DEFAULT_CAPACITY)
 Construct a new BLooper with a priority and an capacity.
 
virtual ~BLooper ()
 Destruct the looper.
 
virtual status_t Perform (perform_code d, void *arg)
 Internal method.
 
Message Mechanics
status_t PostMessage (uint32 command)
 Post a message with the command as what identifier to this looper.
 
status_t PostMessage (BMessage *message)
 Post a message to this looper.
 
status_t PostMessage (uint32 command, BHandler *handler, BHandler *replyTo=NULL)
 Sends a message with command what identifier to the handler associated with this looper. A response may be sent to the replyTo handler asynchronously.
 
status_t PostMessage (BMessage *message, BHandler *handler, BHandler *replyTo=NULL)
 Send a message to the handler associated with this looper. A response may be sent to the replyTo handler asynchronously.
 
Message Processing
virtual void DispatchMessage (BMessage *message, BHandler *handler)
 Dispatch a message to a handler. Override if there are messages that you want to catch before they are sent to the handlers.
 
virtual void MessageReceived (BMessage *message)
 Process a message received by the internal handler of this looper.
 
BMessageCurrentMessage () const
 Retrieve the current message.
 
BMessageDetachCurrentMessage ()
 Get ownership of the message currently being processed.
 
void DispatchExternalMessage (BMessage *message, BHandler *handler, bool &_detached)
 Internal method to support single-threaded GUI toolkits.
 
BMessageQueueMessageQueue () const
 Get a pointer to the internal message queue of this looper.
 
bool IsMessageWaiting () const
 Check if there is a message waiting.
 
Handler Management
void AddHandler (BHandler *handler)
 Associate a handler to this looper.
 
bool RemoveHandler (BHandler *handler)
 Disassociate a handler from this looper.
 
int32 CountHandlers () const
 Get the number of handlers associated with this looper.
 
BHandlerHandlerAt (int32 index) const
 Get the handler at an index of the list of associated handlers.
 
int32 IndexOf (BHandler *handler) const
 Get the index of the handler that is in the associated handler list.
 
BHandlerPreferredHandler () const
 Get the preferred handler.
 
void SetPreferredHandler (BHandler *handler)
 Set a preferred handler.
 
Loop Debugging

These methods may aid you in debugging problems when they occur, but do not use these in actual production code. These methods are unreliable because they are not thread-safe, and as such are only useful in specific debugging situations. Handle with care.

thread_id LockingThread () const
 Return the thread id of the thread that currently holds the lock.
 
int32 CountLocks () const
 Return the number of recursive locks that are currently being held on this looper.
 
int32 CountLockRequests () const
 Return the number of pending locks.
 
sem_id Sem () const
 Return the id of the semaphore that is used to lock this looper.
 
Scripting
virtual BHandlerResolveSpecifier (BMessage *message, int32 index, BMessage *specifier, int32 what, const char *property)
 Determine the proper handler for a scripting message.
 
virtual status_t GetSupportedSuites (BMessage *data)
 Reports the suites of messages and specifiers that derived classes understand.
 
Looper Message Filters

Note that filters added with these methods will be applied to all associated handlers. Have a look at the filtering methods of the BHandler class to see how filters can be applied to the inherited handler of this looper specifically.

virtual void AddCommonFilter (BMessageFilter *filter)
 Add a common filter to the list of filters that are applied to all incoming messages.
 
virtual bool RemoveCommonFilter (BMessageFilter *filter)
 Remove a filter from the common message filter list.
 
virtual void SetCommonFilterList (BList *filters)
 Set a new list of filters that need to be applied to all incoming messages.
 
BListCommonFilterList () const
 Return a list of filters applied to all incoming messages.
 
- Public Member Functions inherited from BHandler
 BHandler (const char *name=NULL)
 Construct a new handler with a name.
 
virtual ~BHandler ()
 Free the filters of this handler, as well as the list of observers.
 
virtual status_t Perform (perform_code d, void *arg)
 Perform some action (Internal method defined for binary compatibility purposes).
 
 BHandler (BMessage *data)
 Construct a handler from an archived message.
 
BLooperLooper () const
 Return a pointer to the looper that this handler is associated with.
 
void SetName (const char *name)
 Set or change the name of this handler.
 
const char * Name () const
 Return the name of this handler.
 
virtual void SetNextHandler (BHandler *handler)
 Set the next handler in the chain that the message is passed on to if this handler cannot process it.
 
BHandlerNextHandler () const
 Return the next hander in the chain to which the message is passed on.
 
virtual void AddFilter (BMessageFilter *filter)
 Add filter as a prerequisite to this handler.
 
virtual bool RemoveFilter (BMessageFilter *filter)
 Remove filter from the filter list.
 
virtual void SetFilterList (BList *filters)
 Set the internal list of filters to filters.
 
BListFilterList ()
 Return a pointer to the list of filters.
 
bool LockLooper ()
 Lock the looper associated with this handler.
 
status_t LockLooperWithTimeout (bigtime_t timeout)
 Lock the looper associated with this handler, with a time out value.
 
void UnlockLooper ()
 Unlock the looper.
 
status_t StartWatching (BMessenger target, uint32 what)
 Subscribe this handler to watch a specific state change of a target.
 
status_t StartWatchingAll (BMessenger target)
 Subscribe this handler to watch a target for all events.
 
status_t StopWatching (BMessenger target, uint32 what)
 Unsubscribe this handler from watching a specific state.
 
status_t StopWatchingAll (BMessenger target)
 Unsubscribe this handler from watching all states.
 
status_t StartWatching (BHandler *observer, uint32 what)
 Subscribe an observer for a specific state change of this handler.
 
status_t StartWatchingAll (BHandler *observer)
 Subscribe an observer for a all state changes.
 
status_t StopWatching (BHandler *observer, uint32 what)
 Unsubscribe an observer from watching a specific state.
 
status_t StopWatchingAll (BHandler *observer)
 Unsubscribe an observer from watching all states.
 
virtual void SendNotices (uint32 what, const BMessage *notice=NULL)
 Emit a state change to the observers.
 
bool IsWatched () const
 Check if there are any observers watching this handler.
 
- Public Member Functions inherited from BArchivable
 BArchivable ()
 Constructor. Does nothing.
 
 BArchivable (BMessage *from)
 Constructor. Does important behind-the-scenes work in the unarchiving process.
 
virtual ~BArchivable ()
 Destructor. Does nothing.
 
virtual status_t AllArchived (BMessage *archive) const
 Method relating to the use of BArchiver.
 
virtual status_t AllUnarchived (const BMessage *archive)
 Method relating to the use of BUnarchiver.
 
virtual status_t Archive (BMessage *into, bool deep=true) const
 Archive the object into a BMessage.
 
virtual status_t Perform (perform_code d, void *arg)
 Perform some action (Internal method defined for binary compatibility purposes).
 

Protected Member Functions

BMessageMessageFromPort (bigtime_t=B_INFINITE_TIMEOUT)
 Hook method to retrieve a message from the looper's port.
 

Archiving

 BLooper (BMessage *data)
 Construct a looper from an archived message.
 
virtual status_t Archive (BMessage *data, bool deep=true) const
 Archive a looper to a message.
 
static BArchivableInstantiate (BMessage *data)
 Static method to instantiate a looper from an archived message.
 

Loop Control

virtual thread_id Run ()
 Start the event loop.
 
void Loop ()
 Run the event loop in the current thread.
 
virtual void Quit ()
 Hook method that is called after a B_QUIT_REQUESTED message.
 
virtual bool QuitRequested ()
 Hook method that is called during a B_QUIT_REQUESTED message.
 
bool Lock ()
 Lock the looper.
 
void Unlock ()
 Unlock a locked looper.
 
bool IsLocked () const
 Check if a looper is locked.
 
status_t LockWithTimeout (bigtime_t timeout)
 Lock a looper with a timeout.
 
thread_id Thread () const
 Return the thread id of the internal message looper thread.
 
team_id Team () const
 Return the team id in which this looper exists.
 
static BLooperLooperForThread (thread_id thread)
 Static method to retrieve a BLooper for a specified thread.
 

Additional Inherited Members

- Static Public Member Functions inherited from BHandler
static BArchivableInstantiate (BMessage *data)
 Static method to instantiate a handler from an archived message.
 
- Static Public Member Functions inherited from BArchivable
static BArchivableInstantiate (BMessage *archive)
 Static member to restore objects from messages.
 

Detailed Description

Receive and process messages in a separate thread.

When an object of this class is created, the message loop can be started with Run(). This spawns the thread that receives messages and processes messages. Messages are actually passed on to handlers that are associated with this looper. By default there is always one handler available: the looper itself. To 'quit' a looper, you should pass a B_QUIT_REQUESTED message using one of the message post functions. When a looper receives such a request, it will delete itself. As such, looper should always be created on the heap (with new), and never on the stack.

Posting messages can be done using the various PostMessage() methods. Whenever a message is posted, it will be added through to the message queue. It is possible to apply filters (see AddCommonFilter()) to filter out any messages that correspond with certain criteria. The method will copy the contents of the message and this copy is processed, so make sure you delete the original messages in case you create them on the heap. The handler for the message is chosen using the following criteria:

  1. If PostMessage() or the BMessenger is set to a specific handler, and this handler is associated with this looper, than the message is processed by that handler.
  2. Else, the preferred handler is used. You can set this using SetPreferredHandler().
  3. If there is no preferred handler, then the looper itself will process the message.

Because a looper usually is used in multiple threads, you should make sure you Lock() and Unlock() it during most operations. Locking calls can be recursive (so multiple locks can come from a single thread), but make sure you pair every Lock() with an Unlock() call. Failing to do so will inevitably cause a deadlock.

Because a looper provides a separate thread, and the inherited handler is usually a default handler, you will most often use this class by subclassing it. For example, you are likely to subclass BWindow (which is derived from BLooper) to customize your window and handle the messages sent to that window. You can override Run() in case you want to perform additional tasks before (or right after) starting the message loop. You can override QuitRequested() if you want to decline quitting in certain circumstances. You can override Quit() in case you want to perform additional procedures during closing time. You can also override DispatchMessage() if you want to do something with all incoming messages before they are dispatched to a handler.

BLooper is one of the major base classes of the Haiku application programmers interface. Closely related classes are BMessage, BHandler and BMessenger. It is used in the interface kit, for example by the BWindow class, which makes sure every window runs it its own thread.

BLooper is a part of the chain in the eloquent messaging structure. For a proper understanding of all its facets, have a look at the messaging overview.

Since
BeOS R3

Constructor & Destructor Documentation

◆ BLooper() [1/2]

BLooper::BLooper ( const char *  name = NULL,
int32  priority = B_NORMAL_PRIORITY,
int32  portCapacity = B_LOOPER_PORT_DEFAULT_CAPACITY 
)

Construct a new BLooper with a priority and an capacity.

The new looper is, by default, not running yet. If you have set up everything properly, you may call Run().

Attention
Remember that loopers should be created on the heap, because they will delete themselves in the Quit() method.
Parameters
nameThe name of the looper.
priorityThe priority of the message thread of this looper. The default priority should be good enough for most tasks. Also, some derived versions of BLooper will use a specialized priority. So it is advised to leave this setting at the default, unless you know why you would like another setting.
portCapacityLoopers use ports to send and receive messages (see the kernel kit). Ports have a maximum capacity; if there are so many messages queued that the port is full, all other incoming messages are dropped. There are situations where the size of the port should be different from the default. This might be when your looper receives a lot of messages, or if the message handling thread runs at a lower priority than normal, which would decrease the processing speed. Finding a suitable value for these custom scenarios would be done by testing.
See also
Run()
Since
BeOS R3

◆ ~BLooper()

BLooper::~BLooper ( )
virtual

Destruct the looper.

You will never delete a looper yourself. You should pass a B_QUIT_REQUESTED message, or if you are destroying the looper from inside its own message handling thread, you should call Quit().

See also
Quit()
Since
BeOS R3

◆ BLooper() [2/2]

BLooper::BLooper ( BMessage data)

Construct a looper from an archived message.

The data message has to be constructed by a BLooper::Archive() call. Note that the data that is restored, is merely the port capacity and the name of the looper/handler. Other data, such as filters, is not archived by the default archiver.

Warning
This constructor does no type check whatsoever. Since you can pass any BMessage, you should - if you are not sure about the exact type - use the Instantiate() method, which does check the type.
See also
Instantiate()
Archive()
Since
BeOS R3

Member Function Documentation

◆ AddCommonFilter()

void BLooper::AddCommonFilter ( BMessageFilter filter)
virtual

Add a common filter to the list of filters that are applied to all incoming messages.

Filters can only be applied once, so they cannot be shared between loopers, a handler and a looper or between two handlers.

The filter is not copied; rather a pointer is stored. Keep the filter alive as long as it is used by a looper.

See also
RemoveCommonFilter()
SetCommonFilterList()
CommonFilterList()
Since
BeOS R3

◆ AddHandler()

void BLooper::AddHandler ( BHandler handler)

Associate a handler to this looper.

The handler will be associated to this looper. By default, the handler in this looper will be chained to the supplied handler.

Parameters
handlerThe handler to associate with this looper. If the handler is already associated to another looper, the operation will fail silently. Check beforehand if you cannot be sure that the handler is unassociated.
See also
RemoveHandler()
Since
BeOS R3

◆ Archive()

status_t BLooper::Archive ( BMessage data,
bool  deep = true 
) const
virtual

Archive a looper to a message.

Currently, only the name and the port capacity are archived. Any other data, such as the filters, is not stored.

Parameters
dataThe message to archive the object in.
deepThis parameter is ignored, as BLooper does not have children.
Return values
B_OKArchiving succeeded.
B_BAD_VALUEThe data parameter is not a valid message.
See also
BLooper::Instantiate(BMessage* data)
Since
BeOS R3

Reimplemented from BHandler.

Reimplemented in BWindow, BApplication, BDirectWindow, and BAlert.

◆ CommonFilterList()

BList * BLooper::CommonFilterList ( ) const

Return a list of filters applied to all incoming messages.

Returns
A pointer to the internal filter list, or NULL if such a list has not yet been created. Please note that you should use the internal list management functions to manipulate the internal filter list, in order to maintain internal consistency.
See also
AddCommonFilter()
RemoveCommonFilter()
SetCommonFilterList()
Since
BeOS R3

◆ CountHandlers()

int32 BLooper::CountHandlers ( ) const

Get the number of handlers associated with this looper.

See also
HandlerAt()
IndexOf()
Since
BeOS R3

◆ CountLockRequests()

int32 BLooper::CountLockRequests ( ) const

Return the number of pending locks.

Since
BeOS R3

◆ CountLocks()

int32 BLooper::CountLocks ( ) const

Return the number of recursive locks that are currently being held on this looper.

Since
BeOS R3

◆ CurrentMessage()

BMessage * BLooper::CurrentMessage ( ) const

Retrieve the current message.

Attention
Only call this method from within the thread that processes the messages. It contains a pointer to the message that is currently being handled. Due to the multithreaded nature of the operating system, this method will not safely let you read the message that is being processed by this handler from outside the context of the processing. If you do want to use a message outside of the processing thread, have a look at DetachCurrentMessage() to safely retrieve a message.
Returns
A pointer to the message that is currently being processed. Note that calling it from outside the thread that processes the message, could give you a NULL pointer or an invalid pointer.
Since
BeOS R5

◆ DetachCurrentMessage()

BMessage * BLooper::DetachCurrentMessage ( )

Get ownership of the message currently being processed.

Retrieve the current message and gain ownership of it. This means that the message will not be deleted as soon as the looper is done processing it. You can then use it for different purposes.

Attention
Only call this method from within the thread that processes the messages. Due to the multithreaded nature of the operating system, calling it from another thread is very likely to give you an invalid or a NULL pointer.
Since
BeOS R5

◆ DispatchExternalMessage()

void BLooper::DispatchExternalMessage ( BMessage message,
BHandler handler,
bool &  _detached 
)

Internal method to support single-threaded GUI toolkits.

Since
Haiku R1

◆ DispatchMessage()

void BLooper::DispatchMessage ( BMessage message,
BHandler handler 
)
virtual

Dispatch a message to a handler. Override if there are messages that you want to catch before they are sent to the handlers.

This method is called by the message looping thread to dispatch a message to handler. If you implement the BLooper class and your looper receives messages that absolutely have to be processed by the looper instead of any of the handlers, override this method. For example, the default implementation catches B_QUIT_REQUESTED messages before they are sent to the handlers, so that the looper will quit at those messages.

You are discouraged from using this method to filter out any messages you do not want to process. For this, there is a more generic method using the BMessageFilter class. If you want to skip messages with certain patterns, have a look at the AddCommonFilter() and SetCommonFilterList() methods.

If you do override this method, please remember to call the DispatchMessage() method of the parent class.

Since
BeOS R3

Reimplemented in BApplication, BDirectWindow, BAlert, and BWindow.

◆ GetSupportedSuites()

status_t BLooper::GetSupportedSuites ( BMessage data)
virtual

Reports the suites of messages and specifiers that derived classes understand.

Since
BeOS R3

Reimplemented from BHandler.

Reimplemented in BApplication, BDirectWindow, BAlert, and BWindow.

◆ HandlerAt()

BHandler * BLooper::HandlerAt ( int32  index) const

Get the handler at an index of the list of associated handlers.

Returns
A pointer to the handler at that index, or NULL if the index is out of range.
See also
CountHandlers()
IndexOf()
Since
BeOS R3

◆ IndexOf()

int32 BLooper::IndexOf ( BHandler handler) const

Get the index of the handler that is in the associated handler list.

Returns
The index of the handler in the list if the handler is in the list, else this method will return -1.
Since
BeOS R3

◆ Instantiate()

BArchivable * BLooper::Instantiate ( BMessage data)
static

Static method to instantiate a looper from an archived message.

Returns
A pointer to the instantiated looper, or NULL if the data is not a valid archived BLooper object.
See also
BLooper(BMessage* data)
Since
BeOS R3

◆ IsLocked()

bool BLooper::IsLocked ( ) const

Check if a looper is locked.

Returns
true if the looper is locked, false if the looper is not locked, or the looper has been deleted.
See also
Lock()
Unlock()
LockWithTimeout()
Since
BeOS R5

◆ IsMessageWaiting()

bool BLooper::IsMessageWaiting ( ) const

Check if there is a message waiting.

Returns
true if there are still messages to be processed, false if there is no message waiting.

◆ Lock()

bool BLooper::Lock ( )

Lock the looper.

For most operations involving the internal data of the looper, you need to hold the lock. Each looper implements a global lock, which you can use to perform operations on internal data in a thread-safe manner.

Do not forget to pair each Lock() request with an Unlock() request. Lock() requests can be stacked, which means that recursively locking a looper from a thread that actually holds the lock, will not cause a deadlock. See BLocker for more information on locking internals.

Returns
true if the locking request succeeded, false if the locking request could not be completed. There are a variety of reasons for this to happen, for example when the looper is destroyed.
See also
Unlock()
LockWithTimeout()
IsLocked()
Since
BeOS R5

Referenced by BAutolock::Lock().

◆ LockingThread()

thread_id BLooper::LockingThread ( ) const

Return the thread id of the thread that currently holds the lock.

Since
BeOS R3

◆ LockWithTimeout()

status_t BLooper::LockWithTimeout ( bigtime_t  timeout)

Lock a looper with a timeout.

This method locks the looper like Lock(), but if the locking request does not succeed within the provided timeout, the method will return.

Parameters
timeoutThe maximum time to wait for the lock request to succeed.
Returns
A status code.
Return values
B_OKThe lock is acquired.
B_BAD_VALUEThe looper has been destroyed.
other errorsThere was an error acquiring the lock.
See also
Lock()
Unlock()
IsLocked()
Since
BeOS R5

◆ Loop()

thread_id BLooper::Loop ( )

Run the event loop in the current thread.

This method runs the event loop in an already existing thread. It blocks until the looper stops looping. This can be used to turn an existing thread into a BLooper.

Make sure the looper is not yet running before you call this method.

Since
Haiku R1

◆ LooperForThread()

BLooper * BLooper::LooperForThread ( thread_id  thread)
static

Static method to retrieve a BLooper for a specified thread.

Since
BeOS R3

◆ MessageFromPort()

BMessage * BLooper::MessageFromPort ( bigtime_t  timeout = B_INFINITE_TIMEOUT)
protected

Hook method to retrieve a message from the looper's port.

The default implementation is called by the internal message looping thread and retrieves the next message from the port that belongs to this looper.

If you use a looper in a context where it might receive messages from other sources, you can override this method in order to insert these methods into the message processing. Note that any messages that are returned by this method will be deleted by this looper, so make sure you have ownership of the message. If you override this method, remember to call the base implementation every now and then, in order to retrieve the messages arriving at the default port.

Since
Haiku R1

◆ MessageQueue()

BMessageQueue * BLooper::MessageQueue ( ) const

Get a pointer to the internal message queue of this looper.

You can use this pointer to manipulate the message queue. Note that the message that is being processed is already detached from this queue.

Returns
A pointer to the internal message queue.
Since
BeOS R5

◆ MessageReceived()

void BLooper::MessageReceived ( BMessage message)
virtual

Process a message received by the internal handler of this looper.

Reimplemented from BHandler::MessageReceived();

Since
BeOS R5

Reimplemented from BHandler.

Reimplemented in BApplication, BDirectWindow, BAlert, and BWindow.

◆ Perform()

status_t BLooper::Perform ( perform_code  d,
void *  arg 
)
virtual

Internal method.

Since
Haiku R1

Reimplemented from BHandler.

Reimplemented in BDirectWindow, BWindow, BApplication, and BAlert.

◆ PostMessage() [1/4]

status_t BLooper::PostMessage ( BMessage message)

Post a message to this looper.

Posting a message puts it in the message queue. The message passes through the default handler chain.

The message is copied, and as such, you should make sure you will not leak it. The best way to send messages is like this:

BMessage message;
message.what = B_DO_SOMETHING;
message.AddString("some_data", "This is data")
aLooper->PostMessage(&message);
A container that can be send and received using the Haiku messaging subsystem.
Definition: Message.h:56
status_t AddString(const char *name, const char *string)
Convenience method to add a C-string to the label name.
uint32 what
A 4-byte constant that determines the type of message.
Definition: Message.h:58
Parameters
messageThe message you would like to pass to this method.
Returns
A status code.
Return values
B_OKThe operation succeeded, and the message is sent to the port.
B_ERRORThere was a general operation error.
B_BAD_VALUEThis looper is not yet running and therefore cannot receive messages.
See also
PostMessage(uint32) if you want to send a message without data members.
PostMessage(uint32, BHandler *, BHandler *) if you want to send a message to a specific handler, and request a reply.
PostMessage(BMessage *, BHandler *, BHandler *) for the same thing, but with a complete message.
Since
BeOS R5

◆ PostMessage() [2/4]

status_t BLooper::PostMessage ( BMessage message,
BHandler handler,
BHandler replyTo = NULL 
)

Send a message to the handler associated with this looper. A response may be sent to the replyTo handler asynchronously.

The target handler should be associated with this looper. This method bypasses the default message queue.

The message is copied, and as such, you should make sure you will not leak it. The best way to send messages is like this:

BMessage message;
message.what = B_DO_SOMETHING;
message.AddString("some_data", "This is data")
aLooper->PostMessage(&message, aHandler);
Parameters
messageThe message you want to pass.
handlerThe handler you would like to pass this message to.
replyToIf you would like to request a reply, pass the handler to which this reply should be directed to. If you pass NULL, you will not receive a reply.
Returns
A status code.
Return values
B_OKThe operation succeeded, and the message is sent to the port.
B_ERRORThere was a general operation error.
B_BAD_VALUEThis looper is not yet running and therefore cannot receive messages.
B_MISMATCHED_VALUESThe handler is not associated with this looper.
See also
PostMessage(uint32) if you want to send a message without data members.
PostMessage(BMessage *) if you want to send a message with data members.
PostMessage(uint32, BHandler *, BHandler *) if you want to send a message without data to a specific handler, and request a reply.
Since
BeOS R5

◆ PostMessage() [3/4]

status_t BLooper::PostMessage ( uint32  command)

Post a message with the command as what identifier to this looper.

Posting a message puts it in the message queue. The message passes through the default handler chain.

Parameters
commandThe what identifier of the message to be sent.
Returns
A status code.
Return values
B_OKThe operation succeeded, and the message is sent to the port.
B_ERRORThere was a general operation error.
B_BAD_VALUEThis looper is not yet running and therefore cannot receive messages.
See also
PostMessage(BMessage *) if you want to send a message with data members.
PostMessage(uint32, BHandler *, BHandler *) if you want to send a message to a specific handler, and request a reply.
PostMessage(BMessage *, BHandler *, BHandler *) for the same thing, but with a complete message.
Since
BeOS R5

◆ PostMessage() [4/4]

status_t BLooper::PostMessage ( uint32  command,
BHandler handler,
BHandler replyTo = NULL 
)

Sends a message with command what identifier to the handler associated with this looper. A response may be sent to the replyTo handler asynchronously.

The target handler should be associated with this looper. This method bypasses the default message queue.

Parameters
commandThe value you want as the message's what identifier.
handlerThe handler you would like to pass this message to.
replyToIf you would like to request a reply, pass the handler to which this reply should be directed to. If you pass NULL, you will not receive a reply.
Returns
A status code.
Return values
B_OKThe operation succeeded, and the message is sent to the port.
B_ERRORThere was a general operation error.
B_BAD_VALUEThis looper is not yet running and therefore cannot receive messages.
B_MISMATCHED_VALUESThe handler is not associated with this looper.
See also
PostMessage(uint32) if you want to send a message without data members.
PostMessage(BMessage *) if you want to send a message with data members.
PostMessage(BMessage *, BHandler *, BHandler *) if you want to send a message to a specific handler, and request a reply.
Since
BeOS R5

◆ PreferredHandler()

BHandler * BLooper::PreferredHandler ( ) const

Get the preferred handler.

Returns
A pointer to the preferred handler, or NULL if none is set.
See also
SetPreferredHandler()
Since
BeOS R3

◆ Quit()

void BLooper::Quit ( )
virtual

Hook method that is called after a B_QUIT_REQUESTED message.

If you want to quit and delete the looper, you should post a B_QUIT_REQUESTED message. This will first call the hook method QuitRequested(), which can be overridden in child classes in case there are conditions that would prevent the looper to be quit. If you really know what you are doing, and you definitely want to quit this looper, you may call this method, but only after performing a Lock() operation.

Override this method if your subclass needs to perform specific clean-up tasks. Remember to call the base class implementation when you're done.

Attention
You will not have to delete the looper object, if a looper quits it will delete itself.
Since
BeOS R3

Reimplemented in BApplication, BDirectWindow, BAlert, and BWindow.

◆ QuitRequested()

bool BLooper::QuitRequested ( )
virtual

Hook method that is called during a B_QUIT_REQUESTED message.

This hook function is called by the looper thread when a B_QUIT_REQUESTED is received. The default implementation always accepts the message, but if your subclass needs a special condition to be met before actually accepting a quit message, you can test for that condition in this hook method. A good example is a window (which is a derivative of BLooper), which contains a modified document. The condition may be that a modal dialog requesting a path of action is closed.

Returns
true if the looper can be quit and destroyed, false if this method does not accept the quit message and continue processing messages.
Since
BeOS R3

Reimplemented in BApplication, BAlert, and BWindow.

◆ RemoveCommonFilter()

bool BLooper::RemoveCommonFilter ( BMessageFilter filter)
virtual

Remove a filter from the common message filter list.

Note that this will not free the memory used by the filter, so you should dispose of it yourself.

See also
AddCommonFilter()
SetCommonFilterList()
CommonFilterList()
Since
BeOS R3

◆ RemoveHandler()

bool BLooper::RemoveHandler ( BHandler handler)

Disassociate a handler from this looper.

If the handler is disassociated, it can be reassociated to another looper.

Returns
true if the handler has been removed from this looper, false The handler was invalid or the handler was not associated to this looper.
See also
AddHandler()
Since
BeOS R3

◆ ResolveSpecifier()

BHandler * BLooper::ResolveSpecifier ( BMessage message,
int32  index,
BMessage specifier,
int32  what,
const char *  property 
)
virtual

Determine the proper handler for a scripting message.

Parameters
messageThe scripting message to determine the handler.
indexThe index of the specifier.
specifierThe message which contains the specifier.
whatThe 'what' field of the specifier message.
propertyThe name of the target property.
Returns
A pointer to the proper BHandler for the given scripting message.
Since
BeOS R3

Reimplemented from BHandler.

Reimplemented in BApplication, BAlert, BDirectWindow, and BWindow.

◆ Run()

thread_id BLooper::Run ( )
virtual

Start the event loop.

After the looper has been constructed, it needs to be started using this method. A thread will be spawned, which will receive messages.

Make sure the looper is not yet running before you call this method.

Returns
A (positive) thread id if spawning the thread succeeded, or an error code.
Since
BeOS R3

Reimplemented in BApplication, and BWindow.

◆ Sem()

sem_id BLooper::Sem ( ) const

Return the id of the semaphore that is used to lock this looper.

Since
BeOS R3

◆ SetCommonFilterList()

void BLooper::SetCommonFilterList ( BList filters)
virtual

Set a new list of filters that need to be applied to all incoming messages.

You are responsible for validating that all the items in the list of filters are actual filters. The old list is discarded; all the filters are destroyed.

Note that filters can only be applied to one looper or handler. If any of the filters is already associated with another one, this call will fail.

See also
AddCommonFilter()
RemoveCommonFilter()
CommonFilterList()
Since
BeOS R3

◆ SetPreferredHandler()

void BLooper::SetPreferredHandler ( BHandler handler)

Set a preferred handler.

If messages are posted to this looper using one of the PostMessage() methods without a specific BHandler argument, the messages will be handled by the looper itself (since a looper is a subclass of BHandler, this is perfectly possible). If you want to override that behavior, you should set a preferred handler. This handler will be called if incoming messages do not ask to be directly passed on to a specific handler.

Parameters
handlerThe preferred handler you want undesignated messages to be handled by. If you want to unset the preferred handler, pass NULL. If the supplied handler is not associated with this looper, this call will fail silently and the current preferred handler will be unset.
See also
PreferredHandler()
Since
BeOS R3

◆ Team()

team_id BLooper::Team ( ) const

Return the team id in which this looper exists.

Since
BeOS R3

◆ Thread()

thread_id BLooper::Thread ( ) const

Return the thread id of the internal message looper thread.

If the looper is not yet running, this method will return 0.

See also
Run()
Since
BeOS R3

◆ Unlock()

void BLooper::Unlock ( )

Unlock a locked looper.

Use this method paired with Lock() calls, to release a lock. Make sure that this method is only called on a locked looper.

See also
Lock()
LockWithTimeout()
IsLocked()
Since
BeOS R5

Referenced by BAutolock::Unlock().