Line data Source code
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 : 21 : #include "AP_HAL/utility/RingBuffer.h" 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 1 : Pollable() { } 33 : 34 : virtual ~Pollable(); 35 : 36 4 : int get_fd() const { return _fd; } 37 : 38 : /* Called whenever the underlying file descriptor has data to be read. */ 39 0 : 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 0 : 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 0 : 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 0 : 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 1 : ~Poller() { 78 1 : unregister_pollable(&_wakeup); 79 : 80 1 : if (_epfd >= 0) { 81 1 : close(_epfd); 82 : } 83 1 : } 84 : 85 : /* 86 : * Check if this Poller is not initialized 87 : */ 88 2 : 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 : }