Belle II Software  release-05-01-25
AbstractNSMCallback.cc
1 #include "daq/slc/nsm/AbstractNSMCallback.h"
2 
3 #include "daq/slc/system/Time.h"
4 
5 #include "daq/slc/base/TimeoutException.h"
6 #include "daq/slc/database/DBObject.h"
7 
8 #include "daq/slc/nsm/NSMCommunicator.h"
9 
10 #include <cstdlib>
11 
12 using namespace Belle2;
13 
14 AbstractNSMCallback::AbstractNSMCallback(int timeout)
15 {
16  m_timeout = timeout;
17 }
18 
19 int AbstractNSMCallback::addDB(const DBObject& obj)
20 {
21  DBObject::NameValueList list;
22  obj.search(list, "", true);
23  int id = 0;
24  for (DBObject::NameValueList::iterator it = list.begin();
25  it != list.end(); it++) {
26  const std::string& name(it->name);
27  if (name.size() == 0 || name.at(0) == '$') continue;
28  switch (it->type) {
29  case DBField::BOOL:
30  id = Callback::add(new NSMVHandlerInt(name, true, true, (int) * ((bool*)it->buf)));
31  set(name, (int) * ((bool*)it->buf));
32  break;
33  case DBField::CHAR:
34  id = Callback::add(new NSMVHandlerInt(name, true, true, (int) * ((char*)it->buf)));
35  set(name, (int) * ((char*)it->buf));
36  break;
37  case DBField::SHORT:
38  id = Callback::add(new NSMVHandlerInt(name, true, true, (int) * ((short*)it->buf)));
39  set(name, (int) * ((short*)it->buf));
40  break;
41  case DBField::INT:
42  id = Callback::add(new NSMVHandlerInt(name, true, true, *((int*)it->buf)));
43  set(name, (int) * ((int*)it->buf));
44  break;
45  case DBField::LONG:
46  id = Callback::add(new NSMVHandlerInt(name, true, true, (int) * ((long long*)it->buf)));
47  set(name, (int) * ((long long*)it->buf));
48  break;
49  case DBField::FLOAT:
50  id = Callback::add(new NSMVHandlerFloat(name, true, true, *((float*)it->buf)));
51  set(name, * ((float*)it->buf));
52  break;
53  case DBField::DOUBLE:
54  id = Callback::add(new NSMVHandlerFloat(name, true, true, (float) * ((double*)it->buf)));
55  set(name, (float) * ((double*)it->buf));
56  break;
57  case DBField::TEXT:
58  id = Callback::add(new NSMVHandlerText(name, true, true, *((std::string*)it->buf)));
59  set(name, *((std::string*)it->buf));
60  break;
61  default:
62  break;
63  }
64  }
65  return id;
66 }
67 
68 NSMCommunicator& AbstractNSMCallback::wait(const NSMNode& node,
69  const NSMCommand& cmd,
70  double timeout)
71 {
72  double t0 = Time().get();
73  double t = t0;
74  while (true) {
75  double t1 = (timeout - (t - t0) > 0 ? timeout - (t - t0) : 0);
76  NSMCommunicator& com(NSMCommunicator::select(t1));
77  NSMMessage msg = com.getMessage();
78  const std::string reqname = msg.getRequestName();
79  if ((cmd == NSMCommand::UNKNOWN || cmd == reqname) &&
80  (node.getName().size() == 0 || msg.getNodeName() == node.getName())) {
81  return com;
82  }
83  com.pushQueue(msg);
84  t = Time().get();
85  }
86 }
87 
88 int AbstractNSMCallback::wait(double timeout)
89 {
90  double t0 = Time().get();
91  double t = t0;
92  int count = 0;
93  try {
94  while (true) {
95  double t1 = (timeout - (t - t0) > 0 ? timeout - (t - t0) : 0);
96  if (t1 == 0) break;
97  NSMCommunicator& com(NSMCommunicator::select(t1));
98  NSMMessage msg = com.getMessage();
99  NSMCommand cmd(msg.getRequestName());
100  if (cmd == NSMCommand::VGET || cmd == NSMCommand::VLISTGET) {
101  perform(com);
102  } else {
103  com.pushQueue(msg);
104  }
105  t = Time().get();
106  }
107  } catch (const TimeoutException& e) {
108  }
109  return count;
110 }
111 
112 bool AbstractNSMCallback::try_wait()
113 {
114  try {
115  perform(wait(NSMNode(), NSMCommand::UNKNOWN, 0));
116  } catch (const std::exception& e) {
117  return false;
118  }
119  return true;
120 }
121 
122 void AbstractNSMCallback::readVar(const NSMMessage& msg, NSMVar& var)
123 {
124  const int* pars = msg.getParams();
125  const char* node = msg.getData();
126  const char* name = (msg.getData() + pars[2] + 1);
127  const char* value = (msg.getData() + pars[2] + 1 + pars[3] + 1);
128  var = NSMVar(name, (NSMVar::Type)pars[0], pars[1], value);
129  var.setNode(node);
130  var.setId(pars[4]);
131  var.setDate(pars[5]);
132 }
133 
134 bool AbstractNSMCallback::get(const NSMNode& node, NSMVHandler* handler,
135  int timeout)
136 {
137  if (handler && node.getName().size() > 0) {
138  NSMVar var(handler->get());
139  add(handler);
140  const std::string name = handler->getName();//var.getName();
141  NSMCommunicator::send(NSMMessage(node, NSMCommand::VGET, name));
142  if (timeout < 0) return true;
143  double t0 = Time().get();
144  double t = t0;
145  double tout = timeout;
146  while (true) {
147  double t1 = (tout - (t - t0) > 0 ? tout - (t - t0) : 0);
148  NSMCommunicator& com(wait(NSMNode(), NSMCommand::UNKNOWN, t1));
149  NSMMessage msg = com.getMessage();
150  NSMCommand cmd(msg.getRequestName());
151  if (cmd == NSMCommand::VSET) {
152  if (node.getName() == msg.getData() &&
153  var.getName() == (msg.getData() + msg.getParam(2) + 1)) {
154  readVar(msg, var);
155  return handler->handleSet(var);
156  }
157  } else if (cmd == NSMCommand::VGET || cmd == NSMCommand::VLISTGET ||
158  cmd == NSMCommand::OK || cmd == NSMCommand::ERROR || cmd == NSMCommand::FATAL) {
159  perform(com);
160  } else {
161  com.pushQueue(msg);
162  }
163  t = Time().get();
164  }
165  }
166  return false;
167 }
168 
169 bool AbstractNSMCallback::get(const NSMNode& node, NSMVar& var,
170  int timeout)
171 {
172  if (node.getName().size() > 0) {
173  const std::string name = var.getName();
174  NSMCommunicator::send(NSMMessage(node, NSMCommand::VGET, name));
175  if (timeout < 0) return true;
176  double t0 = Time().get();
177  double t = t0;
178  double tout = timeout;
179  while (true) {
180  double t1 = (tout - (t - t0) > 0 ? tout - (t - t0) : 0);
181  NSMCommunicator& com(wait(NSMNode(), NSMCommand::UNKNOWN, t1));
182  NSMMessage msg = com.getMessage();
183  NSMCommand cmd(msg.getRequestName());
184  if (cmd == NSMCommand::VSET) {
185  if (msg.getLength() > 0 && msg.getData() != NULL &&
186  node.getName() == msg.getData() &&
187  var.getName() == (msg.getData() + msg.getParam(2) + 1)) {
188  readVar(msg, var);
189  return true;
190  }
191  } else if (cmd == NSMCommand::VGET || cmd == NSMCommand::VLISTGET ||
192  cmd == NSMCommand::OK || cmd == NSMCommand::ERROR || cmd == NSMCommand::FATAL) {
193  perform(com);
194  } else {
195  com.pushQueue(msg);
196  }
197  t = Time().get();
198  }
199  }
200  return false;
201 }
202 
203 bool AbstractNSMCallback::set(const NSMNode& node, const NSMVar& var,
204  int timeout)
205 {
206  if (node.getName().size() > 0) {
207  NSMCommunicator::send(NSMMessage(node, var));
208  if (timeout < 0) return true;
209  double t0 = Time().get();
210  double t = t0;
211  double tout = timeout;
212  while (true) {
213  double t1 = (tout - (t - t0) > 0 ? tout - (t - t0) : 0);
214  NSMCommunicator& com(wait(node, NSMCommand::VREPLY, t1));
215  NSMMessage msg(com.getMessage());
216  NSMCommand cmd(msg.getRequestName());
217  if (cmd == NSMCommand::VREPLY && var.getName() == msg.getData()) {
218  bool ret = msg.getParam(0) > 0;
219  perform(com);
220  return ret;
221  } else if (cmd == NSMCommand::VGET || cmd == NSMCommand::VLISTGET ||
222  cmd == NSMCommand::OK || cmd == NSMCommand::ERROR || cmd == NSMCommand::FATAL) {
223  perform(com);
224  } else {
225  com.pushQueue(msg);
226  }
227  t = Time().get();
228  }
229  }
230  return false;
231 }
232 
233 bool AbstractNSMCallback::get(const NSMNode& node, const std::string& name,
234  int& val, int timeout)
235 {
236  return get_t(node, name, val, timeout, NSMVar::INT, 0);
237 }
238 
239 bool AbstractNSMCallback::get(const NSMNode& node, const std::string& name,
240  float& val, int timeout)
241 {
242  return get_t(node, name, val, timeout, NSMVar::FLOAT, 0);
243 }
244 
245 bool AbstractNSMCallback::get(const NSMNode& node, const std::string& name,
246  std::string& val, int timeout)
247 {
248  return get_t(node, name, val, timeout, NSMVar::TEXT, 1);
249 }
250 
251 bool AbstractNSMCallback::get(const NSMNode& node, const std::string& name,
252  std::vector<int>& val, int timeout)
253 {
254  return get_t(node, name, val, timeout, NSMVar::INT, 1);
255 }
256 
257 bool AbstractNSMCallback::get(const NSMNode& node, const std::string& name,
258  std::vector<float>& val, int timeout)
259 {
260  return get_t(node, name, val, timeout, NSMVar::FLOAT, 1);
261 }
262 
263 bool AbstractNSMCallback::set(const NSMNode& node, const std::string& name,
264  int val, int timeout)
265 {
266  return set(node, NSMVar(name, val), timeout);
267 }
268 
269 bool AbstractNSMCallback::set(const NSMNode& node, const std::string& name,
270  float val, int timeout)
271 {
272  return set(node, NSMVar(name, val), timeout);
273 }
274 
275 bool AbstractNSMCallback::set(const NSMNode& node, const std::string& name,
276  const std::string& val, int timeout)
277 {
278  return set(node, NSMVar(name, val), timeout);
279 }
280 
281 bool AbstractNSMCallback::set(const NSMNode& node, const std::string& name,
282  const std::vector<int>& val, int timeout)
283 {
284  return set(node, NSMVar(name, val), timeout);
285 }
286 
287 bool AbstractNSMCallback::set(const NSMNode& node, const std::string& name,
288  const std::vector<float>& val, int timeout)
289 {
290  return set(node, NSMVar(name, val), timeout);
291 }
292 
293 bool AbstractNSMCallback::get(DBObject& obj)
294 {
295  DBObject::NameValueList list;
296  obj.search(list);
297  for (DBObject::NameValueList::iterator it = list.begin();
298  it != list.end(); it++) {
299  const std::string& name(it->name);
300  if (name.size() == 0 || name.at(0) == '$') continue;
301  int vi = 0;
302  float vf = 0;
303  std::string vs;
304  switch (it->type) {
305  case DBField::BOOL:
306  if (get(name, vi)) *((bool*)it->buf) = (bool)vi;
307  break;
308  case DBField::CHAR:
309  if (get(name, vi)) *((char*)it->buf) = (char)vi;
310  break;
311  case DBField::SHORT:
312  if (get(name, vi)) *((short*)it->buf) = (short)vi;
313  break;
314  case DBField::INT:
315  if (get(name, vi)) *((int*)it->buf) = (int)vi;
316  break;
317  case DBField::LONG:
318  if (get(name, vi)) *((long long*)it->buf) = vi;
319  break;
320  case DBField::FLOAT:
321  if (get(name, vf)) *((float*)it->buf) = vf;
322  break;
323  case DBField::DOUBLE:
324  if (get(name, vf)) *((double*)it->buf) = vf;
325  break;
326  case DBField::TEXT:
327  if (get(name, vs)) *((std::string*)it->buf) = vs;
328  break;
329  default:
330  break;
331  }
332  }
333  return true;
334 }
335 
Belle2::NSMVHandler
Definition: NSMVHandler.h:15
Belle2::NSMNode
Definition: NSMNode.h:14
Belle2::NSMVHandlerInt
Definition: NSMVHandler.h:81
Belle2::DBObject
Definition: DBObject.h:14
Belle2::NSMCommunicator
Definition: NSMCommunicator.h:25
Belle2::NSMMessage
Definition: NSMMessage.h:29
Belle2::NSMVHandlerFloat
Definition: NSMVHandler.h:116
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::Time
Definition: Time.h:14
Belle2::NSMCommand
Definition: NSMCommand.h:12
Belle2::TimeoutException
Definition: TimeoutException.h:12
Belle2::NSMVHandlerText
Definition: NSMVHandler.h:151
Belle2::NSMVar
Definition: NSMVar.h:16