From eb5bc5f9243f6ae838ad2a535c916198f99227a4 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Mon, 31 Jan 2005 00:26:30 +0000 Subject: [PATCH] Added a bit of documentation. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@11166 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/registrar/MessageDeliverer.cpp | 146 +++++++++++++++++++++ src/servers/registrar/MessagingService.cpp | 39 ++++++ 2 files changed, 185 insertions(+) diff --git a/src/servers/registrar/MessageDeliverer.cpp b/src/servers/registrar/MessageDeliverer.cpp index 0b23597ac2..58745a93d8 100644 --- a/src/servers/registrar/MessageDeliverer.cpp +++ b/src/servers/registrar/MessageDeliverer.cpp @@ -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 { 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 { // #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) diff --git a/src/servers/registrar/MessagingService.cpp b/src/servers/registrar/MessagingService.cpp index bf4981db68..256dffbbe7 100644 --- a/src/servers/registrar/MessagingService.cpp +++ b/src/servers/registrar/MessagingService.cpp @@ -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 { }; + +/*! \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"),