Line data Source code
1 : #pragma once 2 : 3 : #include <cstdint> 4 : #include <functional> 5 : #include <memory> 6 : 7 : #include "envoy/common/pure.h" 8 : 9 : namespace Envoy { 10 : namespace Event { 11 : 12 : struct FileReadyType { 13 : // File is ready for reading. 14 : static constexpr uint32_t Read = 0x1; 15 : // File is ready for writing. 16 : static constexpr uint32_t Write = 0x2; 17 : // File has been remote closed. 18 : static constexpr uint32_t Closed = 0x4; 19 : }; 20 : 21 : enum class FileTriggerType { 22 : // See @man 7 epoll(7) 23 : // They are used on all platforms for DNS and TCP listeners. 24 : Level, 25 : // See @man 7 epoll(7) 26 : // They are used on all platforms that support Edge triggering as the default trigger type. 27 : Edge, 28 : // These are synthetic edge events managed by Envoy. They are based on level events and when they 29 : // are activated they are immediately disabled. This makes them behave like Edge events. Then it 30 : // is is the responsibility of the consumer of the event to reactivate the event 31 : // when the socket operation would block. 32 : // 33 : // Their main application in Envoy is for Win32 which does not support edge-triggered events. They 34 : // should be used in Win32 instead of level events. They can only be used in platforms where 35 : // `PlatformDefaultTriggerType` is `FileTriggerType::EmulatedEdge`. 36 : EmulatedEdge 37 : }; 38 : 39 : // For POSIX developers to get the Windows behavior of file events 40 : // you need to add the following definition: 41 : // `FORCE_LEVEL_EVENTS` 42 : // You can do this with bazel if you add the following build/test options 43 : // `--copt="-DFORCE_LEVEL_EVENTS"` 44 0 : constexpr FileTriggerType determinePlatformPreferredEventType() { 45 0 : #if defined(WIN32) || defined(FORCE_LEVEL_EVENTS) 46 0 : return FileTriggerType::EmulatedEdge; 47 0 : #else 48 0 : return FileTriggerType::Edge; 49 0 : #endif 50 0 : } 51 : 52 : static constexpr FileTriggerType PlatformDefaultTriggerType = determinePlatformPreferredEventType(); 53 : 54 : /** 55 : * Callback invoked when a FileEvent is ready for reading or writing. 56 : */ 57 : using FileReadyCb = std::function<void(uint32_t events)>; 58 : 59 : /** 60 : * Wrapper for file based (read/write) event notifications. 61 : */ 62 : class FileEvent { 63 : public: 64 3411 : virtual ~FileEvent() = default; 65 : 66 : /** 67 : * Activate the file event explicitly for a set of events. Should be a logical OR of FileReadyType 68 : * events. This method "injects" the event (and fires callbacks) regardless of whether the event 69 : * is actually ready on the underlying file. 70 : */ 71 : virtual void activate(uint32_t events) PURE; 72 : 73 : /** 74 : * Enable the file event explicitly for a set of events. Should be a logical OR of FileReadyType 75 : * events. As opposed to activate(), this routine causes the file event to listen for the 76 : * registered events and fire callbacks when they are active. 77 : */ 78 : virtual void setEnabled(uint32_t events) PURE; 79 : 80 : /** 81 : * Add a single event from the event registration mark. 82 : */ 83 : virtual void registerEventIfEmulatedEdge(uint32_t event) PURE; 84 : 85 : /** 86 : * Remove a single event from the event registration mark. 87 : */ 88 : virtual void unregisterEventIfEmulatedEdge(uint32_t event) PURE; 89 : }; 90 : 91 : using FileEventPtr = std::unique_ptr<FileEvent>; 92 : 93 : } // namespace Event 94 : } // namespace Envoy