Android-cuttlefish cvd tool
fdevent.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef __FDEVENT_H
18#define __FDEVENT_H
19
20#include <stddef.h>
21#include <stdint.h>
22
23#include <atomic>
24#include <chrono>
25#include <deque>
26#include <functional>
27#include <map>
28#include <mutex>
29#include <optional>
30#include <set>
31#include <variant>
32
34
35#include "adb_unique_fd.h"
36
37// Events that may be observed
38#define FDE_READ 0x0001
39#define FDE_WRITE 0x0002
40#define FDE_ERROR 0x0004
41#define FDE_TIMEOUT 0x0008
42
43struct fdevent;
44
45typedef void (*fd_func)(int fd, unsigned events, void *userdata);
46typedef void (*fd_func2)(struct fdevent* fde, unsigned events, void* userdata);
47
48void invoke_fde(struct fdevent* fde, unsigned events);
49std::string dump_fde(const fdevent* fde);
50
53 unsigned events;
54 fdevent_event(fdevent* pfde, unsigned ev) : fde(pfde), events(ev) {}
55};
56
57struct fdevent final {
58 uint64_t id;
59
61
62 uint16_t state = 0;
63 std::optional<std::chrono::milliseconds> timeout;
64 std::chrono::steady_clock::time_point last_active;
65
66 std::variant<fd_func, fd_func2> func;
67 void* arg = nullptr;
68};
69
71 public:
72 virtual ~fdevent_context() = default;
73
74 // Allocate and initialize a new fdevent object.
75 fdevent* Create(unique_fd fd, std::variant<fd_func, fd_func2> func, void* arg);
76
77 // Deallocate an fdevent object, returning the file descriptor that was owned by it.
78 // Note that this calls Set, which is a virtual method, so destructors that call this must be
79 // final.
81
82 protected:
83 virtual void Register(fdevent*) = 0;
84 virtual void Unregister(fdevent*) = 0;
85
86 public:
87 // Change which events should cause notifications.
88 virtual void Set(fdevent* fde, unsigned events) = 0;
89 void Add(fdevent* fde, unsigned events);
90 void Del(fdevent* fde, unsigned events);
91
92 // Set a timeout on an fdevent.
93 // If no events are triggered by the timeout, an FDE_TIMEOUT will be generated.
94 // Note timeouts are not defused automatically; if a timeout is set on an fdevent, it will
95 // trigger repeatedly every |timeout| ms.
96 void SetTimeout(fdevent* fde, std::optional<std::chrono::milliseconds> timeout);
97
98 protected:
99 std::optional<std::chrono::milliseconds> CalculatePollDuration();
100 void HandleEvents(const std::vector<fdevent_event>& events);
101
102 private:
103 // Run all pending functions enqueued via Run().
105
106 public:
107 // Loop until TerminateLoop is called, handling events.
108 // Implementations should call FlushRunQueue on every iteration, and check the value of
109 // terminate_loop_ to determine whether to stop.
110 virtual void Loop() = 0;
111
112 // Assert that the caller is executing in the context of the execution
113 // thread that invoked Loop().
114 void CheckLooperThread() const;
115
116 // Assert that the caller is NOT executing in the context of the execution
117 // thread that invoked Loop().
118 void CheckNotLooperThread() const;
119
120 // Queue an operation to be run on the looper thread.
121 void Run(std::function<void()> fn);
122
123 // Test-only functionality:
124 void TerminateLoop();
125 virtual size_t InstalledCount() = 0;
126
127 protected:
128 // Interrupt the run loop.
129 virtual void Interrupt() = 0;
130
131 std::optional<uint64_t> looper_thread_id_ = std::nullopt;
132 std::atomic<bool> terminate_loop_ = false;
133
135
136 private:
137 uint64_t fdevent_id_ = 0;
139 std::deque<std::function<void()>> run_queue_ GUARDED_BY(run_queue_mutex_);
140
142};
143
144// Backwards compatibility shims that forward to the global fdevent_context.
145fdevent* fdevent_create(int fd, fd_func func, void* arg);
146fdevent* fdevent_create(int fd, fd_func2 func, void* arg);
147
149void fdevent_destroy(fdevent* fde);
150
151void fdevent_set(fdevent *fde, unsigned events);
152void fdevent_add(fdevent *fde, unsigned events);
153void fdevent_del(fdevent *fde, unsigned events);
154void fdevent_set_timeout(fdevent* fde, std::optional<std::chrono::milliseconds> timeout);
155void fdevent_loop();
156
157// Delegates to the member function that checks for the initialization
158// of Loop() so that fdevent_context requests can be serially processed
159// by the global instance robustly.
162
163// Queue an operation to run on the looper event thread.
164void fdevent_run_on_looper(std::function<void()> fn);
165
166// The following functions are used only for tests.
169void fdevent_reset();
170
171#endif
Definition: unique_fd.h:61
unique_fd fdevent_release(fdevent *fde)
Definition: fdevent.cpp:236
void invoke_fde(struct fdevent *fde, unsigned events)
Definition: fdevent.cpp:38
void fdevent_destroy(fdevent *fde)
Definition: fdevent.cpp:240
void fdevent_run_on_looper(std::function< void()> fn)
Definition: fdevent.cpp:260
void fdevent_terminate_loop()
Definition: fdevent.cpp:276
fdevent * fdevent_create(int fd, fd_func func, void *arg)
Definition: fdevent.cpp:226
size_t fdevent_installed_count()
Definition: fdevent.cpp:280
void fdevent_check_not_looper()
Definition: fdevent.cpp:272
std::string dump_fde(const fdevent *fde)
Definition: fdevent.cpp:48
void fdevent_add(fdevent *fde, unsigned events)
Definition: fdevent.cpp:248
void(* fd_func2)(struct fdevent *fde, unsigned events, void *userdata)
Definition: fdevent.h:46
void fdevent_set(fdevent *fde, unsigned events)
Definition: fdevent.cpp:244
void fdevent_loop()
Definition: fdevent.cpp:264
void(* fd_func)(int fd, unsigned events, void *userdata)
Definition: fdevent.h:45
void fdevent_del(fdevent *fde, unsigned events)
Definition: fdevent.cpp:252
void fdevent_reset()
Definition: fdevent.cpp:284
void fdevent_check_looper()
Definition: fdevent.cpp:268
void fdevent_set_timeout(fdevent *fde, std::optional< std::chrono::milliseconds > timeout)
Definition: fdevent.cpp:256
Definition: logging.h:464
__u32 set
Definition: nl80211.h:1
Definition: fdevent.h:70
virtual void Loop()=0
std::atomic< bool > terminate_loop_
Definition: fdevent.h:132
virtual void Register(fdevent *)=0
virtual void Unregister(fdevent *)=0
virtual size_t InstalledCount()=0
std::mutex run_queue_mutex_
Definition: fdevent.h:138
unique_fd Destroy(fdevent *fde)
Definition: fdevent.cpp:91
void Del(fdevent *fde, unsigned events)
Definition: fdevent.cpp:115
uint64_t fdevent_id_
Definition: fdevent.h:137
std::set< fdevent * > fdevent_set_
Definition: fdevent.h:141
void FlushRunQueue() EXCLUDES(run_queue_mutex_)
Definition: fdevent.cpp:166
void CheckNotLooperThread() const
Definition: fdevent.cpp:189
virtual ~fdevent_context()=default
std::optional< std::chrono::milliseconds > CalculatePollDuration()
Definition: fdevent.cpp:127
void CheckLooperThread() const
Definition: fdevent.cpp:183
virtual void Set(fdevent *fde, unsigned events)=0
void SetTimeout(fdevent *fde, std::optional< std::chrono::milliseconds > timeout)
Definition: fdevent.cpp:120
std::map< int, fdevent > installed_fdevents_
Definition: fdevent.h:134
void TerminateLoop()
Definition: fdevent.cpp:204
fdevent * Create(unique_fd fd, std::variant< fd_func, fd_func2 > func, void *arg)
Definition: fdevent.cpp:63
std::optional< uint64_t > looper_thread_id_
Definition: fdevent.h:131
void HandleEvents(const std::vector< fdevent_event > &events)
Definition: fdevent.cpp:154
void Add(fdevent *fde, unsigned events)
Definition: fdevent.cpp:110
void Run(std::function< void()> fn)
Definition: fdevent.cpp:195
virtual void Interrupt()=0
std::deque< std::function< void()> > run_queue_ GUARDED_BY(run_queue_mutex_)
Definition: fdevent.h:51
fdevent_event(fdevent *pfde, unsigned ev)
Definition: fdevent.h:54
fdevent * fde
Definition: fdevent.h:52
unsigned events
Definition: fdevent.h:53
Definition: fdevent.h:57
std::optional< std::chrono::milliseconds > timeout
Definition: fdevent.h:63
std::variant< fd_func, fd_func2 > func
Definition: fdevent.h:66
uint16_t state
Definition: fdevent.h:62
uint64_t id
Definition: fdevent.h:58
void * arg
Definition: fdevent.h:67
unique_fd fd
Definition: fdevent.h:60
std::chrono::steady_clock::time_point last_active
Definition: fdevent.h:64
#define EXCLUDES(...)
Definition: thread_annotations.h:74