DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
msghandler.hxx
Go to the documentation of this file.
1/************************************************************
2 * msghandler.hpp
3 *
4 * Created on: Dec 3, 2014
5 * Author: Leonidas Georgopoulos
6 *
7 * Copyright (C) 2014 Leonidas Georgopoulos
8 * Distributed under the Boost Software License, Version 1.0.
9 * (See accompanying file LICENSE_1_0.txt or
10 * copy at http://www.boost.org/LICENSE_1_0.txt)
11 *
12 ************************************************************/
13#ifndef LUTILS_MSGHANDLER_HPP_
14#define LUTILS_MSGHANDLER_HPP_
15
16#include <algorithm>
17
18#define LUTILS_MESSAGE_LEVEL_ZERO "lutils_nolevel"
19
20namespace lutils
21{
22namespace program
23{
24
28template<typename UI, typename M, typename T, typename B>
30{
31 m_running = false;
32 CONDITION_STD_SET(m_condition, m_cond_lock, m_have_messages, true);
33 if (m_handler != nullptr)
34 {
35 m_handler->join();
36 }
37 delete m_handler;
38}
39
43template<typename UI, typename M, typename T, typename B>
45 : m_handler(nullptr),
46 m_running(false),
47 m_have_messages(false)
48{
49 this->on();
50}
51
59template<typename UI, typename M, typename T, typename B>
60inline void msghandler<UI, M, T, B>::setlevel(t_str const & level, t_levels levels)
61{
62 t_lock l(m_loock);
63 m_level = level;
64 m_levels = levels;
65}
66
71template<typename UI, typename M, typename T, typename B>
72inline void msghandler<UI, M, T, B>::set(t_str const & logfile)
73{
74 reopen(logfile);
75}
76
80template<typename UI, typename M, typename T, typename B>
82{
83 if (m_handler == nullptr)
84 {
85 t_lock l(m_loock);
86 if (m_handler == nullptr)
87 {
88 m_running = true;
89 m_handler = new t_thread(& msghandler<UI>::handle, this);
90 }
91 }
92}
93
98template<typename UI, typename M, typename T, typename B>
100{
101 typename t_messages::value_type m;
102
103 while (m_running == true)
104 {
105 CONDITION_BOOL_WAIT_TRYFUN(m_condition, m_cond_lock, m_have_messages, [&m_running]()
106 {
107 m_running = false;
108 } );
109 {
110 t_lock l(m_loock);
111 while (!m_messages.empty())
112 {
113 m = m_messages.front();
114 m_messages.pop();
115 if (levelcheck(m.first))
116 {
117 if (m_logfile == nullptr)
118 {
119 post(m.second, m.first);
120 }
121 else
122 {
123 file(m.second);
124 }
125 }
126 }
127
128 m_have_messages = false;
129
130 }
131 }
132}
133
139template<typename UI, typename M, typename T, typename B>
141{
142 message(LUTILS_MESSAGE_LEVEL_ZERO, in);
143}
144
145template<typename UI, typename M, typename T, typename B>
146inline void msghandler<UI, M, T, B>::message(t_str const & level, t_str const & in)
147{
148 {
149 t_lock l(m_loock);
150 m_messages.push(std::make_pair(level, in));
151 }
152 CONDITION_STD_SET(m_condition, m_cond_lock, m_have_messages, true);
153}
154
160template<typename UI, typename M, typename T, typename B>
161template<typename TR >
162inline typename TR::default_post_ret_type msghandler<UI, M, T, B>::post(
163 t_str const & m, t_str const & l)
164{
165 std::cerr << "[" << l << "]:"<< m << std::endl;
166}
167
174template<typename UI, typename M, typename T, typename B>
175template<typename TR >
176inline typename TR::post_ret_type msghandler<UI, M, T, B>::post(
177 t_str const & m, t_str const & l)
178{
179 TR::post(m,l);
180}
181
189template<typename UI, typename M, typename T, typename B>
190inline bool msghandler<UI, M, T, B>::levelcheck(t_str const & level) const
191{
192 if (m_levels.empty())
193 {
194 return true;
195 }
196
197 typename t_levels::const_iterator minlevel = std::find(m_levels.begin(), m_levels.end(),
198 m_level);
199 typename t_levels::const_iterator reqlevel = std::find(m_levels.begin(), m_levels.end(),
200 level);
201
202 if (reqlevel == m_levels.end() || reqlevel < minlevel)
203 {
204 return false;
205 }
206 return true;
207}
208
216template<typename UI, typename M, typename T, typename B>
218{
219 *(m_file) << std::endl << m << std::endl;
220}
221
227template<typename UI, typename M, typename T, typename B>
228inline void msghandler<UI, M, T, B>::reopen(t_str const & logfile)
229{
230 t_lock l(m_loock);
231
232 m_logfile = t_str_ptr(new t_str(logfile));
233
234 if (m_file != nullptr)
235 {
236 while (m_file->is_open())
237 {
238 m_file->close();
239 }
240 }
241 m_file = t_file_ptr(new std::ofstream);
242
243 while (!m_file->is_open())
244 {
245 m_file->open(logfile);
246 }
247}
248
253template<typename UI, typename M, typename T, typename B>
255{
256 static msghandler<UI> This;
257 return This;
258}
259
260} /* namespace program */
261} /* namespace lutils */
262
263
264// Facility macro to inform at compile time msg handler that this class provides a post function
265#define HAS_POST typedef void post_ret_type;
266#define DEFAULT_POST typedef void default_post_ret_type;
267
268#endif /* LUTILS_MSGHANDLER_HPP_ */
bool levelcheck(t_str const &level) const
void message(t_str const &messagein)
std::vector< t_str > t_levels
TR::default_post_ret_type post(t_str const &m, t_str const &l)
std::lock_guard< t_mut > t_lock
static msghandler & ref()
std::unique_ptr< t_file > t_file_ptr
void reopen(t_str const &)
void file(t_str const &)
void set(t_str const &logfile)
std::shared_ptr< t_str > t_str_ptr
void setlevel(t_str const &level, t_levels levels)
#define CONDITION_BOOL_WAIT_TRYFUN(cond, lock, var, tryfun)
Definition macro.hpp:105
#define CONDITION_STD_SET(cond, lock, var, val)
Definition macro.hpp:73
#define LUTILS_MESSAGE_LEVEL_ZERO