this prevents interlacing of message information from different threads We call the thread running MessageLoggerScribe see How the Message Service Starts Up the server side All user programatic interaction is on the client but the configuration(driven by the.cfg file) is dealt with on the server side.The path looks like this(each step is detailed below) the constructor of LogInfo constructs a new MessageSender specifying that this is at severity level and that the category is myCategory When the<< x is encountered, that merely sends<< x to the MessageSender.In the line LogInfo("myCategory")<< x;one has created a **temporary **instance of LogInfo--this getsdestructed upon completion of the statement.The whole working of LogInfois in that destruction:Since LogInfo has an auto_ptr to the MessageSender, when LogInfo goes away, the auto_ptr goes away, and this causesa delete of the MessageSender.The destructor of MessageSender is whereall the action--at the client side--happens.The MessageSender instance owns an ErrorObj on the heap;this can be viewedas a receptacle for the severity and category information and a collectionof items sent in by operator<<.The ctor of MessageSender makes a newErrorObj--AND MessageSender NEVER DELETES THAT ErrorObj!!--Instead, the destructor of MessageSender[which, we will remember, isinvoked as soon as the LogInfo("myCategory")<< x;statement has beenexecuted] interacts with the servier side, placing in motion events thatwill lead to the pointer to this ErrorObj to be used and ultimatelydeleted by code on the server side.The ErrorObj is on the heap, so thispointer remains meaningful in the server side it will be used in.The interaction of MessageSender with the server side consists of two steps.First, it uses the MessageDrop instance to supply the module and run/event context.[There is a separate discussion below about the MessageDrop.] The module and context go into the ErrorObj.Second, it invokes the static LOG method of MessageLoggerQ, supplying the pointer to the ErrorObj.Now we leave the client side and go to the server side, which picks up theLOG_A_MESSAGE entry in the course of a consume(opcode, operand) call on theMessageLoggerQ.The run() method of MessageLoggerScribe has an eternaldo, which continually tries to consume from this queue(consume() sleeps onthe queue being empty).The method log() is passed the pointer to the ErrorObj.log() getsa reference to the ELcontextSupplier from the administrator, and setsthe context to that context remembered in the ErrorObj.(This is necessarysince the run/event of the message issuer is known to the client thread, having been provided by the before-module and before-event callbacks of themessage **service **running in the **client **thread, so this information hadneeded to cross the client/server boundary.) log() then parses the categories string and(if there are multiple categories) invokes the ErrorLog for this object for each category in the string.ErrorLog is in the ErrorLogger code;we are not documenting this code here.The effect is to shop the ErrorObj to every destination;in each case thecode for that destination(normally ELoutput) will apply the limits andthresholds, format the message, add header information, and output the message.Finally, the completion of the do in MessageLoggerScribe::run() deletes theErrorObj--completing the promise made when it was passed responsibility forthis heap-resident object.---------------The MessageDrop---------------The purpose of the message drop is to convey framework information to thepoint-of-invocation where a message is issued.The functions issuingmessages may not naturally have access to the ModuleDescription or theEventID(which contains the run and event numbers) or the list(preparedby configuration in MessageLoggerScrivbe) of debug-enabled modules.Theprocess of preparing a message requires this information.In discussing how the MessageDrop works, we will pay attention to the factsthat the MessageLoggerScript will be running in a distinct thread from thecode issuing the message, and that there may be several threads processingevents, each issuing messages independantly.MessageDrop is athread-specific singleton.The following files interact with MessageDrop:In the MessageLogger package:MessageDrop.h MessageDrop.cc MessageLogger.h MessageSender.cc In the MessageService package:MessageLogger.ccMessageDrop.h defines a singleton pattern.The(private) default ctor initializes the public data:ModuleName is""runEvent is"pre-events"debugEnabled is true There is a public instance() methodMessageDrop.cc refines that to be a thread-specific singleton pattern.This is accomplished by replacing the static bare pointer to MessageDrop which would have been present in an ordinary singleton, with a boost::thread_specific_ptr< MessageDrop > The latter is a object that may contain several but only one is accessible in this thread The if the pointer is it sets the pointer to a new MessageDrop Thus instance() will always return a pointer to the unique MessageDrop for this thread.Note that the server side has no way to influence or access the MessageDrop for a specific thread