blob: d2f81e004c743c3449ef0008e519d0b2c0a32252 [file] [log] [blame]
Josh Gao95068bb2019-07-08 15:23:17 -07001/*
2 * Copyright 2006, Brian Swetland <swetland@frotz.net>
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 */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080016
Yabin Cuiaed3c612015-09-22 15:52:57 -070017#define TRACE_TAG FDEVENT
JP Abgrall408fa572011-03-16 15:57:42 -070018
Dan Albert33134262015-03-19 15:21:08 -070019#include "sysdeps.h"
Dan Albert33134262015-03-19 15:21:08 -070020
Josh Gaoded557f2018-06-18 14:55:27 -070021#include <inttypes.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080022
Josh Gao2c95bf72019-07-08 18:05:16 -070023#include <android-base/logging.h>
Elliott Hughes4f713192015-12-04 22:00:26 -080024#include <android-base/stringprintf.h>
Josh Gao2c95bf72019-07-08 18:05:16 -070025#include <android-base/threads.h>
Yabin Cuia1080162015-09-04 16:19:56 -070026
Josh Gao95068bb2019-07-08 15:23:17 -070027#include "fdevent.h"
28#include "fdevent_poll.h"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080029
Josh Gao95068bb2019-07-08 15:23:17 -070030std::string dump_fde(const fdevent* fde) {
Yabin Cuia1080162015-09-04 16:19:56 -070031 std::string state;
32 if (fde->state & FDE_ACTIVE) {
33 state += "A";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080034 }
Yabin Cuia1080162015-09-04 16:19:56 -070035 if (fde->state & FDE_PENDING) {
36 state += "P";
37 }
Yabin Cuia1080162015-09-04 16:19:56 -070038 if (fde->state & FDE_READ) {
39 state += "R";
40 }
41 if (fde->state & FDE_WRITE) {
42 state += "W";
43 }
44 if (fde->state & FDE_ERROR) {
45 state += "E";
46 }
Josh Gaoded557f2018-06-18 14:55:27 -070047 return android::base::StringPrintf("(fdevent %" PRIu64 ": fd %d %s)", fde->id, fde->fd.get(),
48 state.c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080049}
50
Josh Gao2c95bf72019-07-08 18:05:16 -070051void fdevent_context::CheckMainThread() {
52 if (main_thread_id_) {
53 CHECK_EQ(*main_thread_id_, android::base::GetThreadId());
54 }
55}
56
Josh Gao95eef6b2019-07-08 17:37:23 -070057void fdevent_context::Run(std::function<void()> fn) {
58 {
59 std::lock_guard<std::mutex> lock(run_queue_mutex_);
60 run_queue_.push_back(std::move(fn));
61 }
62
63 Interrupt();
64}
65
Josh Gaoebaa3482019-07-08 18:08:06 -070066void fdevent_context::TerminateLoop() {
67 terminate_loop_ = true;
68 Interrupt();
69}
70
Josh Gao95eef6b2019-07-08 17:37:23 -070071void fdevent_context::FlushRunQueue() {
72 // We need to be careful around reentrancy here, since a function we call can queue up another
73 // function.
74 while (true) {
75 std::function<void()> fn;
76 {
77 std::lock_guard<std::mutex> lock(this->run_queue_mutex_);
78 if (this->run_queue_.empty()) {
79 break;
80 }
81 fn = this->run_queue_.front();
82 this->run_queue_.pop_front();
83 }
84 fn();
85 }
86}
87
Josh Gao7adca932019-07-08 17:31:47 -070088static auto& g_ambient_fdevent_context =
89 *new std::unique_ptr<fdevent_context>(new fdevent_context_poll());
Josh Gaoc2cf1212019-06-28 16:34:36 -070090
91static fdevent_context* fdevent_get_ambient() {
Josh Gao7adca932019-07-08 17:31:47 -070092 return g_ambient_fdevent_context.get();
Josh Gaoc2cf1212019-06-28 16:34:36 -070093}
94
Josh Gaoc2cf1212019-06-28 16:34:36 -070095fdevent* fdevent_create(int fd, fd_func func, void* arg) {
96 unique_fd ufd(fd);
97 return fdevent_get_ambient()->Create(std::move(ufd), func, arg);
98}
99
100fdevent* fdevent_create(int fd, fd_func2 func, void* arg) {
101 unique_fd ufd(fd);
102 return fdevent_get_ambient()->Create(std::move(ufd), func, arg);
103}
104
105unique_fd fdevent_release(fdevent* fde) {
106 return fdevent_get_ambient()->Destroy(fde);
107}
108
109void fdevent_destroy(fdevent* fde) {
110 fdevent_get_ambient()->Destroy(fde);
111}
112
113void fdevent_set(fdevent* fde, unsigned events) {
114 fdevent_get_ambient()->Set(fde, events);
115}
116
117void fdevent_add(fdevent* fde, unsigned events) {
118 fdevent_get_ambient()->Add(fde, events);
119}
120
121void fdevent_del(fdevent* fde, unsigned events) {
122 fdevent_get_ambient()->Del(fde, events);
123}
124
125void fdevent_set_timeout(fdevent* fde, std::optional<std::chrono::milliseconds> timeout) {
126 fdevent_get_ambient()->SetTimeout(fde, timeout);
127}
128
129void fdevent_run_on_main_thread(std::function<void()> fn) {
130 fdevent_get_ambient()->Run(std::move(fn));
131}
132
133void fdevent_loop() {
134 fdevent_get_ambient()->Loop();
135}
136
137void check_main_thread() {
138 fdevent_get_ambient()->CheckMainThread();
139}
140
Josh Gao022d4472016-02-10 14:49:00 -0800141void fdevent_terminate_loop() {
Josh Gaoc2cf1212019-06-28 16:34:36 -0700142 fdevent_get_ambient()->TerminateLoop();
Josh Gao022d4472016-02-10 14:49:00 -0800143}
144
Yabin Cuic1b1f6f2015-09-15 16:27:09 -0700145size_t fdevent_installed_count() {
Josh Gaoc2cf1212019-06-28 16:34:36 -0700146 return fdevent_get_ambient()->InstalledCount();
Yabin Cuic1b1f6f2015-09-15 16:27:09 -0700147}
148
149void fdevent_reset() {
Josh Gao7adca932019-07-08 17:31:47 -0700150 g_ambient_fdevent_context.reset(new fdevent_context_poll());
Yabin Cuic1b1f6f2015-09-15 16:27:09 -0700151}