Poller.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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. #include <unistd.h>
  19. #include "AP_HAL/utility/RingBuffer.h"
  20. #include "Semaphores.h"
  21. namespace Linux {
  22. class Poller;
  23. class Pollable {
  24. friend class Poller;
  25. public:
  26. Pollable(int fd) : _fd(fd) { }
  27. Pollable() { }
  28. virtual ~Pollable();
  29. int get_fd() const { return _fd; }
  30. /* Called whenever the underlying file descriptor has data to be read. */
  31. virtual void on_can_read() { }
  32. /*
  33. * Called whenever the underlying file descriptor is ready to receive new
  34. * data, i.e. its buffer is not full.
  35. */
  36. virtual void on_can_write() { }
  37. /*
  38. * Called when an error occurred and is signaled by the OS - its meaning
  39. * depends on the file descriptor being used.
  40. */
  41. virtual void on_error() { }
  42. /*
  43. * Called when the other side closes its end - the exact meaning
  44. * depends on the file descriptor being used.
  45. */
  46. virtual void on_hang_up() { }
  47. protected:
  48. int _fd = -1;
  49. };
  50. /*
  51. * Internal class to be used inside Poller in order to keep track of requests
  52. * to wake it up
  53. */
  54. class WakeupPollable : public Pollable {
  55. friend class Poller;
  56. public:
  57. void on_can_read() override;
  58. };
  59. class Poller {
  60. public:
  61. Poller();
  62. ~Poller() {
  63. unregister_pollable(&_wakeup);
  64. if (_epfd >= 0) {
  65. close(_epfd);
  66. }
  67. }
  68. /*
  69. * Check if this Poller is not initialized
  70. */
  71. bool operator!() const { return _epfd == -1; }
  72. /*
  73. * Check if this Poller is succesfully initialized
  74. */
  75. explicit operator bool() const { return _epfd != -1; }
  76. /*
  77. * Register @p in this poller so calls to poll() will wait for
  78. * events specified in @events argument.
  79. */
  80. bool register_pollable(Pollable *p, uint32_t events);
  81. /*
  82. * Unregister @p from this Poller so it doesn't generate any more
  83. * event. Note that this doesn't destroy @p.
  84. */
  85. void unregister_pollable(const Pollable *p);
  86. /*
  87. * Wait for events on all Pollable objects registered with
  88. * register_pollable(). New Pollable objects can be registered at any
  89. * time, including when a thread is sleeping on a poll() call.
  90. */
  91. int poll() const;
  92. /*
  93. * Wake up the thread sleeping on a poll() call if it is in fact
  94. * sleeping. Otherwise a nop event is generated and handled. This is
  95. * usually called from a thread different from the one calling poll().
  96. */
  97. void wakeup() const;
  98. private:
  99. int _epfd = -1;
  100. WakeupPollable _wakeup{};
  101. };
  102. }