source: trunk/FACT++/src/MessageDim.cc@ 10936

Last change on this file since 10936 was 10919, checked in by tbretz, 13 years ago
Added local mutices to protect Write calls from different threads - the current implementation is even overprotective
File size: 5.2 KB
Line 
1#include "MessageDim.h"
2
3#include <mutex>
4
5#include "tools.h"
6#include "Time.h"
7
8using namespace std;
9
10// **************************************************************************
11/** @class MessageDimTX
12
13@brief Based on MessageImp, redirects log-output to a Dim service MESSAGE
14
15This is a special DimService which offers SERVER/MESSAGE to the DimNetwork
16and redirects output issued via its base-class MessageImp to the Dim
17service. The severity of the message is send as qualiy of service of
18the service message.
19
20@section Examples
21
22 - A simple and usefull example can be found in \ref log.cc and \ref logtime.cc
23
24**/
25// **************************************************************************
26
27// --------------------------------------------------------------------------
28//
29//! Constructs a DimService with the name SERVER/MESSAGE. And passes the
30//! given ostream down to the MessageImp base.
31//!
32//! @param name
33//! Name of the message server to which we want to subscribe, e.g. DRIVE
34//!
35//! @param out
36//! ostream passed to MessageImp. It is used to redirect the output to.
37//
38MessageDimTX::MessageDimTX(const std::string &name, std::ostream &out)
39 : DimDescribedService((name + "/MESSAGE").c_str(), const_cast<char*>(""),
40 "A general logging service providing a quality of service (severity)"
41 "|Message[string]:The message"),
42MessageImp(out), fDebug(false)
43{
44 // This is a message which will never arrive because
45 // the time to establish a client-sever connection is
46 // too short.
47 Message("MessageDimTX started.");
48}
49
50// --------------------------------------------------------------------------
51//
52//!
53//
54MessageDimTX::~MessageDimTX()
55{
56 Message("MessageDimTX shutting down..");
57}
58
59// --------------------------------------------------------------------------
60//
61//! First calls MessageImp::Write to output the message tobe transmitted
62//! also to a local logging stream. Then the Dim service is updated.
63//! If sending of the message failed a message is written to the
64//! logging stream stored in MessageImp. It is intentionally not
65//! output through Update to make it look different than usual
66//! transmitted messages.
67//
68int MessageDimTX::Write(const Time &t, const string &txt, int qos)
69{
70 static mutex mtx;
71
72 mtx.lock();
73
74 MessageImp::Write(t, txt, qos);
75
76 // We have to use setData to make sure the DimService will
77 // hold a local copy of the data.
78 setQuality(qos);
79 setData(const_cast<char*>(txt.c_str()));
80 const int rc = updateService();
81
82 if (rc==0 && fDebug)
83 Out() << " !! " << t.GetAsStr() << " - Sending failed!" << endl;
84
85 mtx.unlock();
86
87 return rc;
88}
89
90// **************************************************************************
91/** @class MessageDimRX
92
93@brief Based on MessageImp, subscribes to a MESSAGE service in the Dim network
94
95This is a special DimInfoHandler. It subscribes to a service SERVER/MESSAGE
96on the DimNetwork and redirects all received output to its base class
97MessageImp view MessageImp::Write. the quality of service received with
98each service update is passed as severity.
99
100@section Examples
101
102 - A simple and usefull example can be found in \ref log.cc and \ref logtime.cc
103
104 @todo Maybe it is not a good idea that MessageImp is a base class,
105 maybe it should be a reference given in the constructor
106
107**/
108// **************************************************************************
109
110// --------------------------------------------------------------------------
111//
112//! Setup a DimStamedInfo service subscription for SERVER/MESSAGE
113//!
114//! @param name
115//! the name of the SERVER
116//!
117//! @param imp
118//! A reference to MessageImo to which messages will be redirected
119//
120MessageDimRX::MessageDimRX(const std::string &name, MessageImp &imp)
121: fMinLogLevel(0), fConnected(false), fMsg(imp),
122fDimMessage((name+"/MESSAGE").c_str(), const_cast<char*>(""), 0, this)
123{
124}
125
126// --------------------------------------------------------------------------
127//
128//! If the server has been disconnected write a simple log-message.
129//! Skip all received messages which have a severity smaller than
130//! fMinLogLevel. Write any other message with MessageImp::Write.
131//
132void MessageDimRX::infoHandler()
133{
134 if (getInfo()!=&fDimMessage)
135 return;
136
137 const string name = fDimMessage.getName();
138 const string server = name.substr(0, name.find_first_of('/'));
139
140 fConnected = fDimMessage.getSize()!=0;
141
142 // The server is diconnected. Do nothing
143 if (!fConnected)
144 {
145 // We cannot print this message because it is produced by
146 // every server which doesn't have the MESSAGE service, too.
147 //fMsg.Message(server+": Disconnected.");
148 return;
149 }
150
151 // skip all messages with a severity smaller than the minimum log level
152 if (fDimMessage.getQuality()<fMinLogLevel)
153 return;
154
155 stringstream msg;
156 msg << server << ": " << fDimMessage.getString();
157
158 // Make sure getTimestamp is called _before_ getTimestampMillisecs
159 // Must be in exactly this order!
160 const int tsec = fDimMessage.getTimestamp();
161 const int tms = fDimMessage.getTimestampMillisecs();
162
163 // Write the received message to the output
164 fMsg.Write(Time(tsec, tms*1000), msg.str().c_str(), fDimMessage.getQuality());
165}
Note: See TracBrowser for help on using the repository browser.