nidas  v1.2-1520
SensorHandler.h
Go to the documentation of this file.
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4; -*-
2 // vim: set shiftwidth=4 softtabstop=4 expandtab:
3 /*
4  ********************************************************************
5  ** NIDAS: NCAR In-situ Data Acquistion Software
6  **
7  ** 2004, Copyright University Corporation for Atmospheric Research
8  **
9  ** This program is free software; you can redistribute it and/or modify
10  ** it under the terms of the GNU General Public License as published by
11  ** the Free Software Foundation; either version 2 of the License, or
12  ** (at your option) any later version.
13  **
14  ** This program is distributed in the hope that it will be useful,
15  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  ** GNU General Public License for more details.
18  **
19  ** The LICENSE.txt file accompanying this software contains
20  ** a copy of the GNU General Public License. If it is not found,
21  ** write to the Free Software Foundation, Inc.,
22  ** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23  **
24  ********************************************************************
25 */
26 
27 #ifndef NIDAS_CORE_PORTSELECTOR_H
28 #define NIDAS_CORE_PORTSELECTOR_H
29 
30 #include <nidas/Config.h>
31 
32 #include "DSMSensor.h"
33 #include "Polled.h"
34 #include "SensorOpener.h"
35 #include "RemoteSerialListener.h"
36 #include <nidas/util/Thread.h>
38 #include <nidas/util/IOException.h>
39 
40 #include <sys/time.h>
41 
42 #include <vector>
43 #include <set>
44 
55 #if (((POLLING_METHOD == POLL_EPOLL_ET || POLLING_METHOD == POLL_EPOLL_LT) && !defined(HAVE_EPOLL_PWAIT)) || (POLLING_METHOD == POLL_POLL && !defined(HAVE_PPOLL)))
56 #define USE_NOTIFY_PIPE
57 #endif
58 
59 namespace nidas { namespace core {
60 
88 {
89 public:
90 
91  friend class RemoteSerialConnection;
92  friend class RemoteSerialListener;
93 
99  SensorHandler(unsigned short rserialPort = 0);
100 
101  ~SensorHandler();
102 
108  void signalHandler(int sig, siginfo_t*);
109 
114  void addSensor(DSMSensor * sensor);
115 
119  void closeSensor(DSMSensor * sensor);
120 
126  void sensorIsOpen(DSMSensor * sensor) throw();
127 
133  void checkSensors(dsm_time_t);
134 
142  {
144  }
150  {
152  }
153 
154  void handleRemoteSerial(int fd, DSMSensor * sensor)
156 
160  int run() throw(nidas::util::Exception);
161 
162  std::list<DSMSensor*> getAllSensors() const;
163 
164  std::list<DSMSensor*> getOpenedSensors() const;
165 
169  void interrupt();
170 
174  int join() throw(nidas::util::Exception);
175 
176 #if POLLING_METHOD == POLL_EPOLL_ET || POLLING_METHOD == POLL_EPOLL_LT
177  int getEpollFd() const { return _epollfd; }
178 #endif
179 
184  void incrementFullBufferReads(const DSMSensor* sensor);
185 
186 
191  {
192  _pollingChanged = true;
193  }
194 
195 private:
196 
197  class PolledDSMSensor : public Polled
198  {
199  public:
200  PolledDSMSensor(DSMSensor* sensor,SensorHandler* handler)
202 
207 
211  bool handlePollEvents(uint32_t events) throw();
212 
214 
215  int getFd() const { return _sensor->getReadFd(); }
216 
217  const std::string getName() const { return _sensor->getName(); }
218 
219  int getTimeoutMsecs() const { return _sensor->getTimeoutMsecs(); }
220 
233  void setupTimeouts(int checkIntervalMsecs);
234 
246  bool checkTimeout();
247 
252  void close() throw(nidas::util::IOException);
253 
254  private:
256 
258 
264 
269 
276 
277  // no copying
279 
280  // no assignment
281  PolledDSMSensor& operator = (const PolledDSMSensor&);
282 
283  };
284 
285 #ifdef USE_NOTIFY_PIPE
286  class NotifyPipe: public Polled
287  {
288  public:
290 
291  ~NotifyPipe();
292 
293  bool handlePollEvents(uint32_t events) throw();
294 
295  void close() throw(nidas::util::IOException);
296 
302  void notify() throw();
303 
304  int getFd() const { return _fds[0]; }
305 
306  private:
307  int _fds[2];
309 
310  // no copying
311  NotifyPipe(const NotifyPipe&);
312 
313  // no assignment
315  };
316 #endif
317 
323  void add(DSMSensor* sensor) throw();
324 
330  void remove(PolledDSMSensor* sensor) throw();
331 
336  void scheduleClose(PolledDSMSensor*) throw();
337 
341  void scheduleReopen(PolledDSMSensor*) throw();
342 
347  void add(RemoteSerialConnection *) throw();
348 
349  void remove(RemoteSerialConnection *) throw();
350 
355  void scheduleAdd(RemoteSerialConnection*) throw();
356 
357  void scheduleClose(RemoteSerialConnection*) throw();
358 
364  void handlePollingChange();
365 
367 
368  void setupTimeouts(int sensorCheckIntervalMsecs);
369 
370  void checkTimeouts(dsm_time_t);
371 
375  std::list<DSMSensor*> _allSensors;
376 
377  mutable nidas::util::Mutex _pollingMutex;
378 
384 
389 
393  std::list<PolledDSMSensor*> _polledSensors;
394 
400 
406  std::set<PolledDSMSensor*> _pendingSensorClosures;
407 
412  std::set<PolledDSMSensor*> _pendingSensorReopens;
413 
414  unsigned short _remoteSerialSocketPort;
415 
417 
423 
429 
431 
432 #if POLLING_METHOD == POLL_EPOLL_ET || POLLING_METHOD == POLL_EPOLL_LT
433 
436  int _epollfd;
437 
438  struct epoll_event* _events;
439 
440  int _nevents;
441 
442 #elif POLLING_METHOD == POLL_PSELECT
443 
444  fd_set _rfdset;
445 
446  fd_set _efdset;
447 
451  int _nselect;
452 
456  int* _fds;
457 
458 #elif POLLING_METHOD == POLL_POLL
459 
460  struct pollfd* _fds;
461 
462 #endif
463 
464 #if POLLING_METHOD == POLL_PSELECT || POLLING_METHOD == POLL_POLL
465 
468  Polled** _polled;
469 
470 #if POLLING_METHOD == POLL_POLL
471  nfds_t _nfds;
472 #else
473  unsigned int _nfds;
474 #endif
475 
476  unsigned int _nAllocFds;
477 
478  struct timespec _timeout;
479 
480 #endif
481 
482 #ifdef USE_NOTIFY_PIPE
484 #endif
485 
486  dsm_time_t _sensorCheckTime;
487 
488  dsm_time_t _sensorStatsTime;
489 
495 
500 
505  unsigned int _sensorStatsInterval;
506 
508 
514  std::map<const DSMSensor*,unsigned int> _fullBufferReads;
515 
517 
520 
523 };
524 
525 }} // namespace nidas namespace core
526 
527 #endif
Definition: RemoteSerialConnection.h:41
DSMSensor * _sensor
Definition: SensorHandler.h:255
SensorHandler * _handler
Definition: SensorHandler.h:308
unsigned int _sensorStatsInterval
Interval for calculcating through-put statistics on each sensor, in microseconds. ...
Definition: SensorHandler.h:505
int _nTimeoutChecksMax
How many timeout checks constitute an timeout on this sensor.
Definition: SensorHandler.h:268
bool checkTimeout()
The SensorHandler will call this method of each opened sensor at the interval specified previously in...
Definition: SensorHandler.cc:267
int getTimeoutMsecs() const
Definition: SensorHandler.h:219
std::list< DSMSensor * > getOpenedSensors() const
Definition: SensorHandler.cc:168
Definition: RemoteSerialListener.h:41
void scheduleReopen(PolledDSMSensor *)
Schedule this PolledDSMSensor to be closed and reopened.
Definition: SensorHandler.cc:796
int _epollfd
epoll file descriptor.
Definition: SensorHandler.h:436
SensorHandler implements a DSMSensor event loop.
Definition: SensorHandler.h:87
virtual std::string getName() const
Return a name that should fully identify this sensor.
Definition: DSMSensor.h:183
int getFd() const
Definition: SensorHandler.h:215
std::list< DSMSensor * > _openedSensors
Collection of DSMSensors which have been opened.
Definition: SensorHandler.h:388
unsigned int _sensorCheckIntervalUsecs
Same as _sensorCheckIntervalMsecs, but in microseconds.
Definition: SensorHandler.h:499
Interface for objects with a file descriptor, providing a virtual method to be called when system cal...
Definition: Polled.h:109
bool handlePollEvents(uint32_t events)
Definition: SensorHandler.cc:227
long long dsm_time_t
Posix time in microseconds, the number of non-leap microseconds since 1970 Jan 1 00:00 UTC...
Definition: Sample.h:61
unsigned short _remoteSerialSocketPort
Definition: SensorHandler.h:414
Definition: SensorHandler.h:197
std::set< RemoteSerialConnection * > _pendingRserialClosures
RemoteSerialConnections to be closed, probably because the socket connection closed.
Definition: SensorHandler.h:428
dsm_time_t _sensorCheckTime
Definition: SensorHandler.h:486
void addSensor(DSMSensor *sensor)
Add an unopened sensor to the SensorHandler.
Definition: SensorHandler.cc:738
dsm_time_t _sensorStatsTime
Definition: SensorHandler.h:488
void close()
Remove this DSMSensor from those being polled, then call its close() method.
Definition: SensorHandler.cc:205
void setSensorStatsInterval(int val)
Set the sensor statistics calculation period.
Definition: SensorHandler.h:141
void signalHandler(int sig, siginfo_t *)
Override default implementation of Thread::signalHandler().
Definition: SensorHandler.cc:123
void interrupt()
Interrupt polling.
Definition: SensorHandler.cc:714
void sensorIsOpen(DSMSensor *sensor)
After SensorOpener has opened the sensor, it will notify SensorHandler via this method that the senso...
Definition: SensorHandler.cc:750
SensorHandler * _handler
Definition: SensorHandler.h:257
int _sensorCheckIntervalMsecs
Interval for checking for timeouts on each sensor, in milliseconds.
Definition: SensorHandler.h:494
PolledDSMSensor & operator=(const PolledDSMSensor &)
RemoteSerialListener * _rserial
Definition: SensorHandler.h:416
void handlePollingChange()
Called when something has changed in our collection of sensors.
Definition: SensorHandler.cc:976
std::list< RemoteSerialConnection * > _activeRserialConns
Definition: SensorHandler.h:430
std::map< const DSMSensor *, unsigned int > _fullBufferReads
For each sensor, number of times that the input buffer was filled in a read, i.e. ...
Definition: SensorHandler.h:514
std::list< RemoteSerialConnection * > _newRserials
Newly opened RemoteSerialConnections, which are to be added to the list of file descriptors to be pol...
Definition: SensorHandler.h:422
int _lastCheckInterval
What the previous timeout check interval was.
Definition: SensorHandler.h:275
std::list< DSMSensor * > _newOpenedSensors
Newly opened DSMSensors, which are to be added to the list of file descriptors to be polled...
Definition: SensorHandler.h:399
~PolledDSMSensor()
Destructor does not close().
Definition: SensorHandler.h:206
virtual int getReadFd() const
Definition: DSMSensor.h:459
std::list< DSMSensor * > getAllSensors() const
Definition: SensorHandler.cc:161
int run()
Thread function.
Definition: SensorHandler.cc:418
void handleRemoteSerial(int fd, DSMSensor *sensor)
void remove(PolledDSMSensor *sensor)
Internal private method to close the PolledDSMSensor.
Definition: SensorHandler.cc:828
void checkSensors(dsm_time_t)
Check on each sensor.
struct epoll_event * _events
Definition: SensorHandler.h:438
Definition: Thread.h:80
void setupTimeouts(int checkIntervalMsecs)
SensorHandler implements a fairly crude way to detect timeouts on data read from sensors.
Definition: SensorHandler.cc:291
void updateTimeouts()
Tell the SensorHandler that one or more sensor timeouts have changed.
Definition: SensorHandler.h:190
~SensorHandler()
Close any remaining sensors.
Definition: SensorHandler.cc:88
void scheduleAdd(RemoteSerialConnection *)
Schedule this remote serial connection to be closed when convenient.
Definition: SensorHandler.cc:857
std::set< PolledDSMSensor * > _pendingSensorClosures
Sensors to be closed, probably due to a read error or a timeout.
Definition: SensorHandler.h:406
std::list< DSMSensor * > _allSensors
The collection of DSMSensors to be handled.
Definition: SensorHandler.h:375
nidas::util::Mutex _pollingMutex
Definition: SensorHandler.h:377
SensorOpener _opener
Definition: SensorHandler.h:507
void add(DSMSensor *sensor)
Internal private method to create a PolledDSMSensor from a DSMSensor and add it to the list of curren...
Definition: SensorHandler.cc:809
DSMSensor * getDSMSensor()
Definition: SensorHandler.h:213
int join()
Join this thread and join the SensorOpener.
Definition: SensorHandler.cc:727
void checkTimeouts(dsm_time_t)
Definition: SensorHandler.cc:144
int getFd() const
Definition: SensorHandler.h:304
NotifyPipe * _notifyPipe
Definition: SensorHandler.h:483
int getEpollFd() const
Definition: SensorHandler.h:177
DSMSensor provides the basic support for reading, processing and distributing samples from a sensor a...
Definition: DSMSensor.h:87
int fd
Definition: twod.c:56
void incrementFullBufferReads(const DSMSensor *sensor)
Called by a DSMSensor to indicate that a read did not consume all available data. ...
Definition: SensorHandler.cc:219
std::set< PolledDSMSensor * > _pendingSensorReopens
Sensors to be closed and then reopened.
Definition: SensorHandler.h:412
Definition: IOException.h:37
#define USECS_PER_MSEC
Definition: types.h:115
PolledDSMSensor(const PolledDSMSensor &)
Definition: SensorHandler.cc:174
virtual int getTimeoutMsecs() const
Definition: DSMSensor.h:529
SensorHandler(unsigned short rserialPort=0)
Constructor.
Definition: SensorHandler.cc:42
void closeSensor(DSMSensor *sensor)
Request that SensorHandler close the sensor.
int _nevents
Definition: SensorHandler.h:440
int getSensorStatsInterval() const
Get the sensor check period.
Definition: SensorHandler.h:149
void scheduleClose(PolledDSMSensor *)
Schedule this PolledDSMSensor to be closed when convenient.
Definition: SensorHandler.cc:780
int _nTimeoutChecks
How many times this sensor has been checked for timeouts since the last time data was reads...
Definition: SensorHandler.h:263
bool _pollingChanged
A change in the polling file descriptors needs to be handled.
Definition: SensorHandler.h:383
Thread which opens DSMSensors.
Definition: SensorOpener.h:42
const std::string getName() const
Definition: SensorHandler.h:217
std::list< PolledDSMSensor * > _polledSensors
Those DSMSensors currently being polled.
Definition: SensorHandler.h:393
Definition: SensorHandler.h:286
void calcStatistics(dsm_time_t)
Definition: SensorHandler.cc:128
bool _acceptingOpens
Definition: SensorHandler.h:516