Open Lighting Architecture  0.9.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
EPoller.h
1 /*
2  * This library is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU Lesser General Public
4  * License as published by the Free Software Foundation; either
5  * version 2.1 of the License, or (at your option) any later version.
6  *
7  * This library is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10  * Lesser General Public License for more details.
11  *
12  * You should have received a copy of the GNU Lesser General Public
13  * License along with this library; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15  *
16  * EPoller.h
17  * A Poller which uses epoll()
18  * Copyright (C) 2013 Simon Newton
19  */
20 
21 #ifndef COMMON_IO_EPOLLER_H_
22 #define COMMON_IO_EPOLLER_H_
23 
24 #include <ola/base/Macro.h>
25 #include <ola/Clock.h>
26 #include <ola/ExportMap.h>
27 #include <ola/io/Descriptor.h>
28 #include <sys/epoll.h>
29 
30 #include <map>
31 #include <set>
32 #include <string>
33 #include <utility>
34 #include <vector>
35 
36 #include "common/io/PollerInterface.h"
37 #include "common/io/TimeoutManager.h"
38 
39 namespace ola {
40 namespace io {
41 
42 class EPollData;
43 
51 class EPoller : public PollerInterface {
52  public :
58  EPoller(ExportMap *export_map, Clock *clock);
59 
60  ~EPoller();
61 
62  bool AddReadDescriptor(class ReadFileDescriptor *descriptor);
63  bool AddReadDescriptor(class ConnectedDescriptor *descriptor,
64  bool delete_on_close);
65  bool RemoveReadDescriptor(class ReadFileDescriptor *descriptor);
66  bool RemoveReadDescriptor(class ConnectedDescriptor *descriptor);
67 
68  bool AddWriteDescriptor(class WriteFileDescriptor *descriptor);
69  bool RemoveWriteDescriptor(class WriteFileDescriptor *descriptor);
70 
71  const TimeStamp *WakeUpTime() const { return &m_wake_up_time; }
72 
73  bool Poll(TimeoutManager *timeout_manager,
74  const TimeInterval &poll_interval);
75 
76  private:
77  typedef std::map<int, EPollData*> DescriptorMap;
78  typedef std::vector<EPollData*> DescriptorList;
79 
80  DescriptorMap m_descriptor_map;
81 
82  // EPoller is re-enterant. Remove may be called while we hold a pointer to an
83  // EPollData. To avoid deleting data out from underneath ourselves, we
84  // instead move the removed descriptors to this list and then clean them up
85  // outside the callback loop.
86  DescriptorList m_orphaned_descriptors;
87  // A list of pre-allocated descriptors we can use.
88  DescriptorList m_free_descriptors;
89  ExportMap *m_export_map;
90  CounterVariable *m_loop_iterations;
91  CounterVariable *m_loop_time;
92  int m_epoll_fd;
93  Clock *m_clock;
94  TimeStamp m_wake_up_time;
95 
96  std::pair<EPollData*, bool> LookupOrCreateDescriptor(int fd);
97 
98  bool RemoveDescriptor(int fd, int event, bool warn_on_missing);
99  void CheckDescriptor(struct epoll_event *event, EPollData *descriptor);
100 
101  static const int MAX_EVENTS;
102  static const int READ_FLAGS;
103  static const unsigned int MAX_FREE_DESCRIPTORS;
104 
105  DISALLOW_COPY_AND_ASSIGN(EPoller);
106 };
107 } // namespace io
108 } // namespace ola
109 #endif // COMMON_IO_EPOLLER_H_