APM:Libraries
Poller.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2016 Intel Corporation. All rights reserved.
3  *
4  * This file is free software: you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the
6  * Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This file is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12  * See the GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 #pragma once
18 
19 #include <unistd.h>
20 
22 #include "Semaphores.h"
23 
24 namespace Linux {
25 
26 class Poller;
27 
28 class Pollable {
29  friend class Poller;
30 public:
31  Pollable(int fd) : _fd(fd) { }
32  Pollable() { }
33 
34  virtual ~Pollable();
35 
36  int get_fd() const { return _fd; }
37 
38  /* Called whenever the underlying file descriptor has data to be read. */
39  virtual void on_can_read() { }
40 
41  /*
42  * Called whenever the underlying file descriptor is ready to receive new
43  * data, i.e. its buffer is not full.
44  */
45  virtual void on_can_write() { }
46 
47  /*
48  * Called when an error occurred and is signaled by the OS - its meaning
49  * depends on the file descriptor being used.
50  */
51  virtual void on_error() { }
52 
53  /*
54  * Called when the other side closes its end - the exact meaning
55  * depends on the file descriptor being used.
56  */
57  virtual void on_hang_up() { }
58 
59 protected:
60  int _fd = -1;
61 };
62 
63 /*
64  * Internal class to be used inside Poller in order to keep track of requests
65  * to wake it up
66  */
67 class WakeupPollable : public Pollable {
68  friend class Poller;
69 public:
70  void on_can_read() override;
71 };
72 
73 class Poller {
74 public:
75  Poller();
76 
77  ~Poller() {
78  unregister_pollable(&_wakeup);
79 
80  if (_epfd >= 0) {
81  close(_epfd);
82  }
83  }
84 
85  /*
86  * Check if this Poller is not initialized
87  */
88  bool operator!() const { return _epfd == -1; }
89 
90  /*
91  * Check if this Poller is succesfully initialized
92  */
93  explicit operator bool() const { return _epfd != -1; }
94 
95  /*
96  * Register @p in this poller so calls to poll() will wait for
97  * events specified in @events argument.
98  */
99  bool register_pollable(Pollable *p, uint32_t events);
100 
101  /*
102  * Unregister @p from this Poller so it doesn't generate any more
103  * event. Note that this doesn't destroy @p.
104  */
105  void unregister_pollable(const Pollable *p);
106 
107  /*
108  * Wait for events on all Pollable objects registered with
109  * register_pollable(). New Pollable objects can be registered at any
110  * time, including when a thread is sleeping on a poll() call.
111  */
112  int poll() const;
113 
114  /*
115  * Wake up the thread sleeping on a poll() call if it is in fact
116  * sleeping. Otherwise a nop event is generated and handled. This is
117  * usually called from a thread different from the one calling poll().
118  */
119  void wakeup() const;
120 
121 private:
122 
123  int _epfd = -1;
124  WakeupPollable _wakeup{};
125 };
126 
127 }
virtual void on_can_write()
Definition: Poller.h:45
virtual ~Pollable()
Definition: Poller.cpp:148
friend class Poller
Definition: Poller.h:29
int get_fd() const
Definition: Poller.h:36
int close(int fileno)
POSIX Close a file with fileno handel.
Definition: posix.c:675
bool operator!() const
Definition: Poller.h:88
virtual void on_can_read()
Definition: Poller.h:39
Pollable(int fd)
Definition: Poller.h:31
virtual void on_error()
Definition: Poller.h:51
virtual void on_hang_up()
Definition: Poller.h:57