API
 
Loading...
Searching...
No Matches
mzmqClient.hpp
Go to the documentation of this file.
1/** \file mzmqClient.hpp
2 * \brief The MagAO-X milkzmqClient wrapper
3 *
4 * \author Jared R. Males (jaredmales@gmail.com)
5 *
6 * \ingroup mzmqClient_files
7 */
8
9#ifndef mzmqClient_hpp
10#define mzmqClient_hpp
11
12
13//#include <ImageStreamIO/ImageStruct.h>
14//#include <ImageStreamIO/ImageStreamIO.h>
15
16#include <milkzmqClient.hpp>
17
18#include "../../libMagAOX/libMagAOX.hpp" //Note this is included on command line to trigger pch
19#include "../../magaox_git_version.h"
20
21namespace MagAOX
22{
23namespace app
24{
25
26/** \defgroup mzmqClient ImageStreamIO 0mq Stream Client
27 * \brief Reads the contents of an ImageStreamIO image stream over a zeroMQ channel
28 *
29 * <a href="../handbook/operating/software/apps/mzmqClient.html">Application Documentation</a>
30 *
31 * \ingroup apps
32 *
33 */
34
35/** \defgroup mzmqClient_files ImageStreamIO Stream Synchronization
36 * \ingroup mzmqClient
37 */
38
39/// MagAO-X application to control reading ImageStreamIO streams from a zeroMQ channel
40/** Contents are published to a local ImageStreamIO shmem buffer.
41 *
42 * \todo handle the alternate local name option as in the base milkzmqClient
43 * \todo md docs for this.
44 *
45 * \ingroup mzmqClient
46 *
47 */
48class mzmqClient : public MagAOXApp<>, public milkzmq::milkzmqClient
49{
50
51
52public:
53
54 ///Default c'tor
55 mzmqClient();
56
57 ///Destructor
58 ~mzmqClient() noexcept;
59
60 /// Setup the configuration system (called by MagAOXApp::setup())
61 virtual void setupConfig();
62
63 /// load the configuration system results (called by MagAOXApp::setup())
64 virtual void loadConfig();
65
66 /// Startup functions
67 /** Sets up the INDI vars.
68 *
69 */
70 virtual int appStartup();
71
72 /// Implementation of the FSM for the Siglent SDG
73 virtual int appLogic();
74
75
76 /// Do any needed shutdown tasks. Currently nothing in this app.
77 virtual int appShutdown();
78
79protected:
80
81 std::vector<std::string> m_shMemImNames;
82
83 /** \name SIGSEGV & SIGBUS signal handling
84 * These signals occur as a result of a ImageStreamIO source server resetting (e.g. changing frame sizes).
85 * When they occur a restart of the framegrabber and framewriter thread main loops is triggered.
86 *
87 * @{
88 */
89 bool m_restart {false};
90
91 static mzmqClient * m_selfClient; ///< 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//Set self pointer to null so app starts up uninitialized.
137
138inline
139mzmqClient::mzmqClient() : MagAOXApp(MAGAOX_CURRENT_SHA1, MAGAOX_REPO_MODIFIED)
140{
141 m_powerMgtEnabled = false;
142
143 return;
144}
145
146inline
148{
149 return;
150}
151
152inline
154{
155 config.add("server.address", "", "server.address", argType::Required, "server", "address", false, "string", "The server's remote address. Usually localhost if using a tunnel.");
156 config.add("server.imagePort", "", "server.imagePort", argType::Required, "server", "imagePort", false, "int", "The server's port. Usually the port on localhost forwarded to the host.");
157
158 config.add("server.shmimNames", "", "server.shmimNames", argType::Required, "server", "shmimNames", false, "string", "List of names of the remote shmim streams to get.");
159
160
161
162}
163
164
165
166inline
168{
170
171 config(m_address, "server.address");
172 config(m_imagePort, "server.imagePort");
173
174 config(m_shMemImNames, "server.shmimNames");
175
176 std::cerr << "m_imagePort = " << m_imagePort << "\n";
177
178}
179
180
181#include <sys/syscall.h>
182
183inline
185{
186 if(setSigSegvHandler() < 0)
187 {
189 return -1;
190 }
191
192 for(size_t n=0; n < m_shMemImNames.size(); ++n)
193 {
195 }
196
197 for(size_t n=0; n < m_imageThreads.size(); ++n)
198 {
199 if( imageThreadStart(n) > 0)
200 {
201 log<software_critical>({__FILE__, __LINE__, "Starting image thread " + m_imageThreads[n].m_imageName});
202 return -1;
203 }
204 }
205
206 return 0;
207
208}
209
210
211
212inline
214{
215 //first do a join check to see if other threads have exited.
216
217 for(size_t n=0; n < m_imageThreads.size(); ++n)
218 {
219 if(pthread_tryjoin_np(m_imageThreads[n].m_thread->native_handle(),0) == 0)
220 {
221 log<software_error>({__FILE__, __LINE__, "image thread " + m_imageThreads[n].m_imageName + " has exited"});
222
223 return -1;
224 }
225 }
226
227
228 return 0;
229
230}
231
232inline
234{
235 m_timeToDie = true;
236
237 for(size_t n=0; n < m_imageThreads.size(); ++n)
238 {
240 }
241
242 for(size_t n=0; n < m_imageThreads.size(); ++n)
243 {
244 if( m_imageThreads[n].m_thread->joinable())
245 {
246 m_imageThreads[n].m_thread->join();
247 }
248 }
249
250 return 0;
251}
252
253inline
255{
256 struct sigaction act;
257 sigset_t set;
258
259 act.sa_sigaction = &mzmqClient::_handlerSigSegv;
260 act.sa_flags = SA_SIGINFO;
261 sigemptyset(&set);
262 act.sa_mask = set;
263
264 errno = 0;
265 if( sigaction(SIGSEGV, &act, 0) < 0 )
266 {
267 std::string logss = "Setting handler for SIGSEGV failed. Errno says: ";
268 logss += strerror(errno);
269
271
272 return -1;
273 }
274
275 errno = 0;
276 if( sigaction(SIGBUS, &act, 0) < 0 )
277 {
278 std::string logss = "Setting handler for SIGBUS failed. Errno says: ";
279 logss += strerror(errno);
280
282
283 return -1;
284 }
285
286 log<text_log>("Installed SIGSEGV/SIGBUS signal handler.", logPrio::LOG_DEBUG);
287
288 return 0;
289}
290
291inline
293 siginfo_t *siginf,
294 void *ucont
295 )
296{
298}
299
300inline
302 siginfo_t *siginf,
303 void *ucont
304 )
305{
306 static_cast<void>(signum);
307 static_cast<void>(siginf);
308 static_cast<void>(ucont);
309
310 m_restart = true;
311
312 return;
313}
314
315inline
316void mzmqClient::reportInfo( const std::string & msg )
317{
319}
320
321inline
322void mzmqClient::reportNotice( const std::string & msg )
323{
325}
326
327inline
328void mzmqClient::reportWarning( const std::string & msg )
329{
331}
332
333inline
334void mzmqClient::reportError( const std::string & msg,
335 const std::string & file,
336 int line
337 )
338{
339 log<software_error>({file.c_str(), (uint32_t) line, msg});
340}
341
342
343
344}//namespace app
345} //namespace MagAOX
346#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 reading ImageStreamIO streams from a zeroMQ channel.
virtual int appLogic()
Implementation of the FSM for the Siglent SDG.
static mzmqClient * m_selfClient
Static pointer to this (set in constructor). Used for getting out of the static SIGSEGV handler.
virtual void reportNotice(const std::string &msg)
Log status (with LOG_NOTICE level of priority).
virtual int appShutdown()
Do any needed shutdown tasks. Currently nothing in this app.
mzmqClient()
Default c'tor.
virtual void reportWarning(const std::string &msg)
Log a warning.
void handlerSigSegv(int signum, siginfo_t *siginf, void *ucont)
Handles SIGSEGV and SIGBUS. Sets m_restart to true.
virtual void reportInfo(const std::string &msg)
Log status (with LOG_INFO level of priority).
int setSigSegvHandler()
Sets the handler for SIGSEGV and SIGBUS.
~mzmqClient() noexcept
Destructor.
virtual void setupConfig()
Setup the configuration system (called by MagAOXApp::setup())
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 int appStartup()
Startup functions.
virtual void loadConfig()
load the configuration system results (called by MagAOXApp::setup())
std::vector< std::string > m_shMemImNames
virtual void reportError(const std::string &msg, const std::string &file, int line)
Log an error.
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.