CXMessagePost

From cxwiki

CXMessagePost offers a mechanism for delaying CXMessage dispatch and for dispatching CXMessages to a CXMessageTarget which is owned by another thread. CXMessagePost is itself a baseclass, and application code will typically use a singleton (or near-singleton) object of a specific subclass based on which thread they wish to dispatch the message to.

Accessors

The most common usage is to call CXMessagePostTask::Get() to retrieve the main-thread singleton, which will dispatch any messages on the main thread.
 
Note: The CXMessagePost facility is typically used on the main thread to post messages to the native user interface. This usage is still the most common, however now that we support user interfaces on multiple threads, it is likely that the accessors will be rewritten to avoid possible unintentional misuse.
// Retrieves the system-provided CXMessagePost singleton for 
// the main thread. This will dispatch messages to main-thread
// recipients during CXTask idle time. If no singleton exists,
// it will be created on demand.
static CXMessagePost& CXMessagePostTask::Get(void);

// This deletes the system-provided CXMessagePost singleton
// for the main thread. This is called during final shutdown.
// This does not prevent a subsequent call to 
// CXMessagePost::Get() from recreating the singleton, although
// it is generally intended that CXMessagePost::Get() will not
// be called that late in shutdown.
static void CXMessagePostTask::KillSingleton(void);

 

Message Dispatch

Regardless of the specific dispatch implementation, the methods provided to trigger message dispatch are identical. All dispatch messages are delayed, even if the eventual dispatch is on the same thread as the caller.

If the 'source' object is deleted on the dispatch thread prior the method returning, the result is undefined. This can obviously only occur when the caller is not running on the dispatch thread.

If the 'source' object is deleted on the dispatch thead after the function returns but prior to message dispatch, the message dispatch will simply not occur.

If the 'source' message is deleted on another thread, the outcome is undefined (likely either the message dispatch will not occur, or the application will crash, depending on timing).

Note that these methods also allow a single reference-counted object to be passed. This isn't used by the method, but will be kept around to avoid the object in question being deleted before the message is processed.

// Equivalent to calling source->BroadcastMessage(*k_message) on 
// this object's dispatch thread at (or soon after) the specified
// timestamp.
void PostBroadcast(
    CXMessageTarget* __nonnull source
  , CXMessage* __nonnull k_message
  , Reference reference = Reference()
  , CXTimestamp deliveryTimestamp = CXTime::GetTimestamp()
  );

// Equivalent to calling source->Message(*k_message) on this 
// object's dispatch thread at (or soon after) the specified
// timestamp.
void PostMessage(
    CXMessageTarget* __nonnull source
  , CXMessage* __nonnull k_message
  , Reference reference = Reference()
  , CXTimestamp deliveryTimestamp = CXTime::GetTimestamp()
  );

// Cancels any queued messages for the specified source which
// match the specified message name. Note that this does not
// block against any (matching) queued messages which are in
// the process of being dispatched.
void CancelMessage(
    CXMessageTarget* __nonnull source
  , const CXString& messageName
  );

// Cancels any queued messages for the specified source. This
// will additionally block against any queued messages which
// are in the process of being dispatched, so is suitable for
// use when deleting a CXMessageTarget across threads. Note
// that it does not prevent additional messages from being 
// queued during or after this function returns, so the 
// application must ensure to avoid any problematic race
// conditions.
void CancelMessages(CXMessageTarget* __nonnull source);

Derived Implementations

Derived classes must use their own mechanisms to ensure that CXMessagePost::Update() is called regularly, and should ideally avoid calling it from within a Message handler to avoid complications.