Added a bit of documentation.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@11166 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2005-01-31 00:26:30 +00:00
parent 242ebd2030
commit eb5bc5f924
2 changed files with 185 additions and 0 deletions

View File

@ -32,6 +32,11 @@ static const int32 kMaxMessagesPerPort = 10000;
static const int32 kMaxDataPerPort = 50 * 1024 * 1024; // 50 MB
// Message
/*! \brief Encapsulates a message to be delivered.
Besides the flattened message it also stores the when the message was
created and when the delivery attempts shall time out.
*/
class MessageDeliverer::Message : public Referenceable {
public:
Message(void *data, int32 dataSize, bigtime_t timeout)
@ -98,6 +103,16 @@ private:
};
// TargetMessage
/*! \brief Encapsulates a Message to be sent to a specific handler.
A TargetMessage is always associated with (i.e. queued in) a TargetPort.
While a Message stores only the message data and some timing info, this
object adds the token of a the target BHandler.
A Message can be referred to by more than one TargetMessage (when
broadcasting), but a TargetMessage is referred to exactly once, by
the TargetPort.
*/
class MessageDeliverer::TargetMessage
: public DoublyLinkedListLinkImpl<MessageDeliverer::TargetMessage> {
public:
@ -131,6 +146,14 @@ private:
};
// TargetMessageHandle
/*! \brief A small wrapper for TargetMessage providing a complete order.
This class only exists to provide the comparison operators required to
put a TargetMessage into a set. The order implemented is by ascending by
timeout time (primary) and by TargetMessage pointer (secondary).
Hence TargetMessageHandles referring to the same TargetMessage are equal
(and only those).
*/
class MessageDeliverer::TargetMessageHandle {
public:
TargetMessageHandle(TargetMessage *message)
@ -180,6 +203,14 @@ private:
};
// TargetPort
/*! \brief Represents a full target port, queuing the not yet delivered
messages.
A TargetPort internally queues TargetMessages in the order the are to be
delivered. Furthermore the object maintains an ordered set of
TargetMessages that can timeout (in ascending order of timeout time), so
that timed out messages can be dropped easily.
*/
class MessageDeliverer::TargetPort {
public:
TargetPort(port_id portID)
@ -309,6 +340,20 @@ struct MessageDeliverer::TargetPortMap : public map<port_id, TargetPort*> {
// #pragma mark -
/*! \class MessageDeliverer
\brief Service for delivering messages, which retries the delivery as long
as the target port is full.
For the user of the service only the MessageDeliverer::DeliverMessage()
will be of interest. Some of them allow broadcasting a message to several
recepients.
The class maintains a TargetPort for each target port which was full at the
time a message was to be delivered to it. A TargetPort has a queue of
undelivered messages. A separate worker thread retries periodically to send
the yet undelivered messages to the respective target ports.
*/
// constructor
MessageDeliverer::MessageDeliverer()
: fLock("message deliverer"),
@ -393,6 +438,21 @@ MessageDeliverer::Default()
}
// DeliverMessage
/*! \brief Delivers a message to the supplied target.
The method tries to send the message right now (if there are not already
messages pending for the target port). If that fails due to a full target
port, the message is queued for later delivery.
\param message The message to be delivered.
\param target A BMessenger identifying the delivery target.
\param timeout If given, the message will be dropped, when it couldn't be
delivered after this amount of microseconds.
\return
- \c B_OK, if sending the message succeeded or if the target port was
full and the message has been queued,
- another error code otherwise.
*/
status_t
MessageDeliverer::DeliverMessage(BMessage *message, BMessenger target,
bigtime_t timeout)
@ -405,6 +465,22 @@ MessageDeliverer::DeliverMessage(BMessage *message, BMessenger target,
}
// DeliverMessage
/*! \brief Delivers a message to the supplied target.
The method tries to send the message right now (if there are not already
messages pending for the target port). If that fails due to a full target
port, the message is queued for later delivery.
\param message The message to be delivered.
\param port The port the message shall be sent to.
\param token The token identifying the target BHandler.
\param timeout If given, the message will be dropped, when it couldn't be
delivered after this amount of microseconds.
\return
- \c B_OK, if sending the message succeeded or if the target port was
full and the message has been queued,
- another error code otherwise.
*/
status_t
MessageDeliverer::DeliverMessage(BMessage *message, port_id port, int32 token,
bigtime_t timeout)
@ -429,6 +505,23 @@ MessageDeliverer::DeliverMessage(BMessage *message, port_id port, int32 token,
}
// DeliverMessage
/*! \brief Delivers a flattened message to the supplied target.
The method tries to send the message right now (if there are not already
messages pending for the target port). If that fails due to a full target
port, the message is queued for later delivery.
\param message The flattened message to be delivered. This may be a
flattened BMessage or KMessage.
\param messageSize The size of the flattened message buffer.
\param target A BMessenger identifying the delivery target.
\param timeout If given, the message will be dropped, when it couldn't be
delivered after this amount of microseconds.
\return
- \c B_OK, if sending the message succeeded or if the target port was
full and the message has been queued,
- another error code otherwise.
*/
status_t
MessageDeliverer::DeliverMessage(const void *message, int32 messageSize,
BMessenger target, bigtime_t timeout)
@ -441,6 +534,24 @@ MessageDeliverer::DeliverMessage(const void *message, int32 messageSize,
}
// DeliverMessage
/*! \brief Delivers a flattened message to the supplied target.
The method tries to send the message right now (if there are not already
messages pending for the target port). If that fails due to a full target
port, the message is queued for later delivery.
\param message The flattened message to be delivered. This may be a
flattened BMessage or KMessage.
\param messageSize The size of the flattened message buffer.
\param port The port the message shall be sent to.
\param token The token identifying the target BHandler.
\param timeout If given, the message will be dropped, when it couldn't be
delivered after this amount of microseconds.
\return
- \c B_OK, if sending the message succeeded or if the target port was
full and the message has been queued,
- another error code otherwise.
*/
status_t
MessageDeliverer::DeliverMessage(const void *message, int32 messageSize,
port_id port, int32 token, bigtime_t timeout)
@ -452,6 +563,22 @@ MessageDeliverer::DeliverMessage(const void *message, int32 messageSize,
}
// DeliverMessage
/*! \brief Delivers a message to the supplied targets.
The method tries to send the message right now to each of the given targets
(if there are not already messages pending for a target port). If that
fails due to a full target port, the message is queued for later delivery.
\param message The message to be delivered.
\param targets An array of BMessengers identifying the delivery targets.
\param targetCount The number of delivery targets.
\param timeout If given, the message will be dropped, when it couldn't be
delivered after this amount of microseconds.
\return
- \c B_OK, if for each of the given targets sending the message succeeded
or if the target port was full and the message has been queued,
- another error code otherwise.
*/
status_t
MessageDeliverer::DeliverMessage(BMessage *message, const BMessenger *targets,
int32 targetCount, bigtime_t timeout)
@ -492,6 +619,25 @@ MessageDeliverer::DeliverMessage(BMessage *message, const BMessenger *targets,
}
// DeliverMessage
/*! \brief Delivers a flattened message to the supplied targets.
The method tries to send the message right now to each of the given targets
(if there are not already messages pending for a target port). If that
fails due to a full target port, the message is queued for later delivery.
\param message The flattened message to be delivered. This may be a
flattened BMessage or KMessage.
\param messageSize The size of the flattened message buffer.
\param targets An array of messaging_targets identifying the delivery
targets.
\param targetCount The number of delivery targets.
\param timeout If given, the message will be dropped, when it couldn't be
delivered after this amount of microseconds.
\return
- \c B_OK, if for each of the given targets sending the message succeeded
or if the target port was full and the message has been queued,
- another error code otherwise.
*/
status_t
MessageDeliverer::DeliverMessage(const void *messageData, int32 messageSize,
const messaging_target *targets, int32 targetCount, bigtime_t timeout)

View File

@ -19,6 +19,14 @@
// sService -- the singleton instance
MessagingService *MessagingService::sService = NULL;
/*! \class MessagingArea
\brief Represents an area of the messaging service shared between kernel
and registrar.
The main purpose of the class is to retrieve (and remove) commands from
the area.
*/
// constructor
MessagingArea::MessagingArea()
{
@ -188,6 +196,37 @@ struct MessagingService::CommandHandlerMap
: map<uint32, MessagingCommandHandler*> {
};
/*! \class MessagingService
\brief Userland implementation of the kernel -> userland messaging service.
This service provides a way for the kernel to send BMessages (usually
notification (e.g. node monitoring) messages) to userland applications.
The kernel could write the messages directly to the respective target ports,
but this has the disadvantage, that a message needs to be dropped, if the
port is full at the moment of sending. By transferring the message to the
registrar, it is possible to use the MessageDeliverer which retries sending
messages on full ports.
The message transfer is implemented via areas shared between kernel
and registrar. By default one area is used as a ring buffer. The kernel
adds messages to it, the registrar removes them. If the area is full, the
kernel creates a new one and adds it to the area list.
While the service is called `messaging service' and we were speaking of
`messages' being passed through the areas, the service is actually more
general. In fact `commands' are passed through the areas. Currently the
only implemented command type is to send a message, but it is very easy
to add further command types (e.g. one for alerting the user in case of
errors).
The MessagingService maintains a mapping of command types to command
handlers (MessagingCommandHandler, which perform the actual processing
of the commands), that can be altered via
MessagingService::SetCommandHandler().
*/
// constructor
MessagingService::MessagingService()
: fLock("messaging service"),