API
 
Loading...
Searching...
No Matches
mzmqServer.hpp
Go to the documentation of this file.
1/** \file mzmqServer.hpp
2 * \brief The MagAO-X milkzmqServer wrapper
3 *
4 * \author Jared R. Males (jaredmales@gmail.com)
5 *
6 * \ingroup mzmqServer_files
7 */
8
9#ifndef mzmqServer_hpp
10#define mzmqServer_hpp
11
12
13//#include <ImageStruct.h>
14//#include <ImageStreamIO.h>
15
16#include <milkzmqServer.hpp>
17
18//#include <mx/timeUtils.hpp>
19
20#include "../../libMagAOX/libMagAOX.hpp" //Note this is included on command line to trigger pch
21#include "../../magaox_git_version.h"
22
23
24
25namespace MagAOX
26{
27namespace app
28{
29
30/** \defgroup mzmqServer ImageStreamIO Stream Server
31 * \brief Writes the contents of an ImageStreamIO image stream over a zeroMQ channel
32 *
33 * <a href="../handbook/operating/software/apps/mzmqServer.html">Application Documentation</a>
34 *
35 * \ingroup apps
36 *
37 */
38
39/** \defgroup mzmqServer_files ImageStreamIO Stream Synchronization
40 * \ingroup mzmqServer
41 */
42
43/// MagAO-X application to control writing ImageStreamIO streams to a zeroMQ channel
44/** \todo document this better
45 * \todo implement thread-kills for shutdown. Maybe switch to USR1, with library wide empty handler, so it isn't logged.
46 * \ingroup mzmqServer
47 *
48 */
49class mzmqServer : public MagAOXApp<>, public milkzmq::milkzmqServer
50{
51
52
53public:
54
55 ///Default c'tor
56 mzmqServer();
57
58 ///Destructor
59 ~mzmqServer() noexcept;
60
61 /// Setup the configuration system (called by MagAOXApp::setup())
62 virtual void setupConfig();
63
64 /// load the configuration system results (called by MagAOXApp::setup())
65 virtual void loadConfig();
66
67 /// Startup functions
68 /** Sets up the INDI vars.
69 *
70 */
71 virtual int appStartup();
72
73 /// Implementation of the FSM for the Siglent SDG
74 virtual int appLogic();
75
76
77 /// Do any needed shutdown tasks. Currently nothing in this app.
78 virtual int appShutdown();
79
80protected:
81
82 bool m_compress {false};
83 std::vector<std::string> m_shMemImNames;
84
85 /** \name SIGSEGV & SIGBUS signal handling
86 * These signals occur as a result of a ImageStreamIO source server resetting (e.g. changing frame sizes).
87 * When they occur a restart of the framegrabber and framewriter thread main loops is triggered.
88 *
89 * @{
90 */
91 static mzmqServer * m_selfWriter; ///< Static pointer to this (set in constructor). Used for getting out of the static SIGSEGV handler.
92
93 ///Sets the handler for SIGSEGV and SIGBUS
94 /** These are caused by ImageStreamIO server resets.
95 */
97
98 ///The handler called when SIGSEGV or SIGBUS is received, which will be due to ImageStreamIO server resets. Just a wrapper for handlerSigSegv.
99 static void _handlerSigSegv( int signum,
101 void *ucont
102 );
103
104 ///Handles SIGSEGV and SIGBUS. Sets m_restart to true.
105 void handlerSigSegv( int signum,
107 void *ucont
108 );
109 ///@}
110
111
112 /** \name milkzmq Status and Error Handling
113 * Implementation of status updates, warnings, and errors from milkzmq using logs.
114 *
115 * @{
116 */
117
118 /// Log status (with LOG_INFO level of priority).
119 virtual void reportInfo( const std::string & msg /**< [in] the status message */);
120
121 /// Log status (with LOG_NOTICE level of priority).
122 virtual void reportNotice( const std::string & msg /**< [in] the status message */);
123
124 /// Log a warning.
125 virtual void reportWarning( const std::string & msg /**< [in] the warning message */);
126
127 /// Log an error.
128 virtual void reportError( const std::string & msg, ///< [in] the error message
129 const std::string & file, ///< [in] the name of the file where the error occurred
130 int line ///< [in] the line number of the error
131 );
132 ///@}
133
134};
135
136//Set self pointer to null so app starts up uninitialized.
138
139inline
140mzmqServer::mzmqServer() : MagAOXApp(MAGAOX_CURRENT_SHA1, MAGAOX_REPO_MODIFIED)
141{
142 m_powerMgtEnabled = false;
143
144 return;
145}
146
147inline
149{
150 return;
151}
152
153inline
155{
156 config.add("server.imagePort", "", "server.imagePort", argType::Required, "server", "imagePort", false, "int", "");
157
158 config.add("server.shmimNames", "", "server.shmimNames", argType::Required, "server", "shmimNames", false, "string", "");
159
160 config.add("server.usecSleep", "", "server.usecSleep", argType::Required, "server", "usecSleep", false, "int", "");
161
162 config.add("server.fpsTgt", "", "server.fpsTgt", argType::Required, "server", "fpsTgt", false, "float", "");
163
164 config.add("server.fpsGain", "", "server.fpsGain", argType::Required, "server", "fpsGain", false, "float", "");
165
166 config.add("server.compress", "", "server.compress", argType::Required, "server", "compress", false, "bool", "Flag to turn on compression for INT16 and UINT16.");
167
168}
169
170
171
172inline
174{
176
177 config(m_imagePort, "server.imagePort");
178
179 config(m_shMemImNames, "server.shmimNames");
180 config(m_usecSleep, "server.usecSleep");
181 config(m_fpsTgt, "server.fpsTgt");
182
183 config(m_fpsGain, "server.fpsGain");
184
185 config(m_compress, "server.compress");
186
187
188}
189
190
191#include <sys/syscall.h>
192
193inline
195{
196
197 //Now set up the framegrabber and writer threads.
198 // - need SIGSEGV and SIGBUS handling for ImageStreamIO restarts
199 // - initialize the semaphore
200 // - start the threads
201
202 if(setSigSegvHandler() < 0)
203 {
205 return -1;
206 }
207
209
210 for(size_t n=0; n < m_shMemImNames.size(); ++n)
211 {
213 }
214
215 if(serverThreadStart() < 0)
216 {
218 return -1;
219 }
220
221 for(size_t n=0; n < m_imageThreads.size(); ++n)
222 {
223 if( imageThreadStart(n) > 0)
224 {
225 log<software_critical>({__FILE__, __LINE__, "Starting image thread " + m_imageThreads[n].m_imageName});
226 return -1;
227 }
228 }
229
230
231 std::cerr << "Main Thread: " << syscall(SYS_gettid) << "\n";
232
233 return 0;
234
235}
236
237
238
239inline
241{
242 //first do a join check to see if other threads have exited.
243
244 if(pthread_tryjoin_np(m_serverThread.native_handle(),0) == 0)
245 {
246 log<software_error>({__FILE__, __LINE__, "server thread has exited"});
247
248 return -1;
249 }
250
251 for(size_t n=0; n < m_imageThreads.size(); ++n)
252 {
253 if(pthread_tryjoin_np(m_imageThreads[n].m_thread->native_handle(),0) == 0)
254 {
255 log<software_error>({__FILE__, __LINE__, "image thread " + m_imageThreads[n].m_imageName + " has exited"});
256
257 return -1;
258 }
259 }
260
261
262 return 0;
263
264}
265
266inline
268{
269 m_timeToDie = true;
270
271 for(size_t n=0; n < m_imageThreads.size(); ++n)
272 {
274 }
275
276 for(size_t n=0; n < m_imageThreads.size(); ++n)
277 {
278 if( m_imageThreads[n].m_thread->joinable())
279 {
280 m_imageThreads[n].m_thread->join();
281 }
282 }
283
284 return 0;
285}
286
287inline
289{
290 struct sigaction act;
291 sigset_t set;
292
293 act.sa_sigaction = &mzmqServer::_handlerSigSegv;
294 act.sa_flags = SA_SIGINFO;
295 sigemptyset(&set);
296 act.sa_mask = set;
297
298 errno = 0;
299 if( sigaction(SIGSEGV, &act, 0) < 0 )
300 {
301 std::string logss = "Setting handler for SIGSEGV failed. Errno says: ";
302 logss += strerror(errno);
303
305
306 return -1;
307 }
308
309 errno = 0;
310 if( sigaction(SIGBUS, &act, 0) < 0 )
311 {
312 std::string logss = "Setting handler for SIGBUS failed. Errno says: ";
313 logss += strerror(errno);
314
316
317 return -1;
318 }
319
320 log<text_log>("Installed SIGSEGV/SIGBUS signal handler.", logPrio::LOG_DEBUG);
321
322 return 0;
323}
324
325inline
327 siginfo_t *siginf,
328 void *ucont
329 )
330{
332}
333
334inline
336 siginfo_t *siginf,
337 void *ucont
338 )
339{
340 static_cast<void>(signum);
341 static_cast<void>(siginf);
342 static_cast<void>(ucont);
343
344 milkzmqServer::m_restart = true;
345
346 return;
347}
348
349inline
350void mzmqServer::reportInfo( const std::string & msg )
351{
353}
354
355inline
356void mzmqServer::reportNotice( const std::string & msg )
357{
359}
360
361inline
362void mzmqServer::reportWarning( const std::string & msg )
363{
365}
366
367inline
368void mzmqServer::reportError( const std::string & msg,
369 const std::string & file,
370 int line
371 )
372{
373 log<software_error>({file.c_str(), (uint32_t) line, msg});
374}
375
376
377
378}//namespace app
379} //namespace MagAOX
380#endif
The base-class for MagAO-X applications.
Definition MagAOXApp.hpp:73
std::string m_configName
The name of the configuration file (minus .conf).
Definition MagAOXApp.hpp:83
static int log(const typename logT::messageT &msg, logPrioT level=logPrio::LOG_DEFAULT)
Make a log entry.
MagAO-X application to control writing ImageStreamIO streams to a zeroMQ channel.
virtual void setupConfig()
Setup the configuration system (called by MagAOXApp::setup())
int setSigSegvHandler()
Sets the handler for SIGSEGV and SIGBUS.
virtual void loadConfig()
load the configuration system results (called by MagAOXApp::setup())
virtual int appShutdown()
Do any needed shutdown tasks. Currently nothing in this app.
virtual int appStartup()
Startup functions.
static void _handlerSigSegv(int signum, siginfo_t *siginf, void *ucont)
The handler called when SIGSEGV or SIGBUS is received, which will be due to ImageStreamIO server rese...
virtual void reportError(const std::string &msg, const std::string &file, int line)
Log an error.
virtual int appLogic()
Implementation of the FSM for the Siglent SDG.
void handlerSigSegv(int signum, siginfo_t *siginf, void *ucont)
Handles SIGSEGV and SIGBUS. Sets m_restart to true.
virtual void reportNotice(const std::string &msg)
Log status (with LOG_NOTICE level of priority).
mzmqServer()
Default c'tor.
virtual void reportInfo(const std::string &msg)
Log status (with LOG_INFO level of priority).
static mzmqServer * m_selfWriter
Static pointer to this (set in constructor). Used for getting out of the static SIGSEGV handler.
std::vector< std::string > m_shMemImNames
~mzmqServer() noexcept
Destructor.
virtual void reportWarning(const std::string &msg)
Log a warning.
std::stringstream msg
Definition dm.hpp:24
static constexpr logPrioT LOG_NOTICE
A normal but significant condition.
static constexpr logPrioT LOG_INFO
Informational. The info log level is the lowest level recorded during normal operations.
static constexpr logPrioT LOG_WARNING
A condition has occurred which may become an error, but the process continues.
static constexpr logPrioT LOG_DEBUG
Used for debugging.