1 /* http://frotznet.googlecode.com/svn/trunk/utils/fdevent.c 2 ** 3 ** Copyright 2006, Brian Swetland <swetland (at) frotz.net> 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 #define TRACE_TAG FDEVENT 19 20 #include "sysdeps.h" 21 #include "fdevent.h" 22 23 #include <fcntl.h> 24 #include <stdlib.h> 25 #include <string.h> 26 #include <unistd.h> 27 28 #include <atomic> 29 #include <list> 30 #include <unordered_map> 31 #include <vector> 32 33 #include <android-base/logging.h> 34 #include <android-base/stringprintf.h> 35 36 #include "adb_io.h" 37 #include "adb_trace.h" 38 #include "adb_utils.h" 39 40 #if !ADB_HOST 41 // This socket is used when a subproc shell service exists. 42 // It wakes up the fdevent_loop() and cause the correct handling 43 // of the shell's pseudo-tty master. I.e. force close it. 44 int SHELL_EXIT_NOTIFY_FD = -1; 45 #endif // !ADB_HOST 46 47 #define FDE_EVENTMASK 0x00ff 48 #define FDE_STATEMASK 0xff00 49 50 #define FDE_ACTIVE 0x0100 51 #define FDE_PENDING 0x0200 52 #define FDE_CREATED 0x0400 53 54 struct PollNode { 55 fdevent* fde; 56 adb_pollfd pollfd; 57 58 explicit PollNode(fdevent* fde) : fde(fde) { 59 memset(&pollfd, 0, sizeof(pollfd)); 60 pollfd.fd = fde->fd; 61 62 #if defined(__linux__) 63 // Always enable POLLRDHUP, so the host server can take action when some clients disconnect. 64 // Then we can avoid leaving many sockets in CLOSE_WAIT state. See http://b/23314034. 65 pollfd.events = POLLRDHUP; 66 #endif 67 } 68 }; 69 70 // All operations to fdevent should happen only in the main thread. 71 // That's why we don't need a lock for fdevent. 72 static auto& g_poll_node_map = *new std::unordered_map<int, PollNode>(); 73 static auto& g_pending_list = *new std::list<fdevent*>(); 74 static std::atomic<bool> terminate_loop(false); 75 static bool main_thread_valid; 76 static unsigned long main_thread_id; 77 78 static void check_main_thread() { 79 if (main_thread_valid) { 80 CHECK_EQ(main_thread_id, adb_thread_id()); 81 } 82 } 83 84 static void set_main_thread() { 85 main_thread_valid = true; 86 main_thread_id = adb_thread_id(); 87 } 88 89 static std::string dump_fde(const fdevent* fde) { 90 std::string state; 91 if (fde->state & FDE_ACTIVE) { 92 state += "A"; 93 } 94 if (fde->state & FDE_PENDING) { 95 state += "P"; 96 } 97 if (fde->state & FDE_CREATED) { 98 state += "C"; 99 } 100 if (fde->state & FDE_READ) { 101 state += "R"; 102 } 103 if (fde->state & FDE_WRITE) { 104 state += "W"; 105 } 106 if (fde->state & FDE_ERROR) { 107 state += "E"; 108 } 109 if (fde->state & FDE_DONT_CLOSE) { 110 state += "D"; 111 } 112 return android::base::StringPrintf("(fdevent %d %s)", fde->fd, state.c_str()); 113 } 114 115 fdevent *fdevent_create(int fd, fd_func func, void *arg) 116 { 117 check_main_thread(); 118 fdevent *fde = (fdevent*) malloc(sizeof(fdevent)); 119 if(fde == 0) return 0; 120 fdevent_install(fde, fd, func, arg); 121 fde->state |= FDE_CREATED; 122 return fde; 123 } 124 125 void fdevent_destroy(fdevent *fde) 126 { 127 check_main_thread(); 128 if(fde == 0) return; 129 if(!(fde->state & FDE_CREATED)) { 130 LOG(FATAL) << "destroying fde not created by fdevent_create(): " << dump_fde(fde); 131 } 132 fdevent_remove(fde); 133 free(fde); 134 } 135 136 void fdevent_install(fdevent* fde, int fd, fd_func func, void* arg) { 137 check_main_thread(); 138 CHECK_GE(fd, 0); 139 memset(fde, 0, sizeof(fdevent)); 140 fde->state = FDE_ACTIVE; 141 fde->fd = fd; 142 fde->func = func; 143 fde->arg = arg; 144 if (!set_file_block_mode(fd, false)) { 145 // Here is not proper to handle the error. If it fails here, some error is 146 // likely to be detected by poll(), then we can let the callback function 147 // to handle it. 148 LOG(ERROR) << "failed to set non-blocking mode for fd " << fd; 149 } 150 auto pair = g_poll_node_map.emplace(fde->fd, PollNode(fde)); 151 CHECK(pair.second) << "install existing fd " << fd; 152 D("fdevent_install %s", dump_fde(fde).c_str()); 153 } 154 155 void fdevent_remove(fdevent* fde) { 156 check_main_thread(); 157 D("fdevent_remove %s", dump_fde(fde).c_str()); 158 if (fde->state & FDE_ACTIVE) { 159 g_poll_node_map.erase(fde->fd); 160 if (fde->state & FDE_PENDING) { 161 g_pending_list.remove(fde); 162 } 163 if (!(fde->state & FDE_DONT_CLOSE)) { 164 adb_close(fde->fd); 165 fde->fd = -1; 166 } 167 fde->state = 0; 168 fde->events = 0; 169 } 170 } 171 172 static void fdevent_update(fdevent* fde, unsigned events) { 173 auto it = g_poll_node_map.find(fde->fd); 174 CHECK(it != g_poll_node_map.end()); 175 PollNode& node = it->second; 176 if (events & FDE_READ) { 177 node.pollfd.events |= POLLIN; 178 } else { 179 node.pollfd.events &= ~POLLIN; 180 } 181 182 if (events & FDE_WRITE) { 183 node.pollfd.events |= POLLOUT; 184 } else { 185 node.pollfd.events &= ~POLLOUT; 186 } 187 fde->state = (fde->state & FDE_STATEMASK) | events; 188 } 189 190 void fdevent_set(fdevent* fde, unsigned events) { 191 check_main_thread(); 192 events &= FDE_EVENTMASK; 193 if ((fde->state & FDE_EVENTMASK) == events) { 194 return; 195 } 196 CHECK(fde->state & FDE_ACTIVE); 197 fdevent_update(fde, events); 198 D("fdevent_set: %s, events = %u", dump_fde(fde).c_str(), events); 199 200 if (fde->state & FDE_PENDING) { 201 // If we are pending, make sure we don't signal an event that is no longer wanted. 202 fde->events &= events; 203 if (fde->events == 0) { 204 g_pending_list.remove(fde); 205 fde->state &= ~FDE_PENDING; 206 } 207 } 208 } 209 210 void fdevent_add(fdevent* fde, unsigned events) { 211 check_main_thread(); 212 fdevent_set(fde, (fde->state & FDE_EVENTMASK) | events); 213 } 214 215 void fdevent_del(fdevent* fde, unsigned events) { 216 check_main_thread(); 217 fdevent_set(fde, (fde->state & FDE_EVENTMASK) & ~events); 218 } 219 220 static std::string dump_pollfds(const std::vector<adb_pollfd>& pollfds) { 221 std::string result; 222 for (const auto& pollfd : pollfds) { 223 std::string op; 224 if (pollfd.events & POLLIN) { 225 op += "R"; 226 } 227 if (pollfd.events & POLLOUT) { 228 op += "W"; 229 } 230 android::base::StringAppendF(&result, " %d(%s)", pollfd.fd, op.c_str()); 231 } 232 return result; 233 } 234 235 static void fdevent_process() { 236 std::vector<adb_pollfd> pollfds; 237 for (const auto& pair : g_poll_node_map) { 238 pollfds.push_back(pair.second.pollfd); 239 } 240 CHECK_GT(pollfds.size(), 0u); 241 D("poll(), pollfds = %s", dump_pollfds(pollfds).c_str()); 242 int ret = adb_poll(&pollfds[0], pollfds.size(), -1); 243 if (ret == -1) { 244 PLOG(ERROR) << "poll(), ret = " << ret; 245 return; 246 } 247 for (const auto& pollfd : pollfds) { 248 if (pollfd.revents != 0) { 249 D("for fd %d, revents = %x", pollfd.fd, pollfd.revents); 250 } 251 unsigned events = 0; 252 if (pollfd.revents & POLLIN) { 253 events |= FDE_READ; 254 } 255 if (pollfd.revents & POLLOUT) { 256 events |= FDE_WRITE; 257 } 258 if (pollfd.revents & (POLLERR | POLLHUP | POLLNVAL)) { 259 // We fake a read, as the rest of the code assumes that errors will 260 // be detected at that point. 261 events |= FDE_READ | FDE_ERROR; 262 } 263 #if defined(__linux__) 264 if (pollfd.revents & POLLRDHUP) { 265 events |= FDE_READ | FDE_ERROR; 266 } 267 #endif 268 if (events != 0) { 269 auto it = g_poll_node_map.find(pollfd.fd); 270 CHECK(it != g_poll_node_map.end()); 271 fdevent* fde = it->second.fde; 272 CHECK_EQ(fde->fd, pollfd.fd); 273 fde->events |= events; 274 D("%s got events %x", dump_fde(fde).c_str(), events); 275 fde->state |= FDE_PENDING; 276 g_pending_list.push_back(fde); 277 } 278 } 279 } 280 281 static void fdevent_call_fdfunc(fdevent* fde) 282 { 283 unsigned events = fde->events; 284 fde->events = 0; 285 CHECK(fde->state & FDE_PENDING); 286 fde->state &= (~FDE_PENDING); 287 D("fdevent_call_fdfunc %s", dump_fde(fde).c_str()); 288 fde->func(fde->fd, events, fde->arg); 289 } 290 291 #if !ADB_HOST 292 293 #include <sys/ioctl.h> 294 295 static void fdevent_subproc_event_func(int fd, unsigned ev, 296 void* /* userdata */) 297 { 298 299 D("subproc handling on fd = %d, ev = %x", fd, ev); 300 301 CHECK_GE(fd, 0); 302 303 if (ev & FDE_READ) { 304 int subproc_fd; 305 306 if(!ReadFdExactly(fd, &subproc_fd, sizeof(subproc_fd))) { 307 LOG(FATAL) << "Failed to read the subproc's fd from " << fd; 308 } 309 auto it = g_poll_node_map.find(subproc_fd); 310 if (it == g_poll_node_map.end()) { 311 D("subproc_fd %d cleared from fd_table", subproc_fd); 312 adb_close(subproc_fd); 313 return; 314 } 315 fdevent* subproc_fde = it->second.fde; 316 if(subproc_fde->fd != subproc_fd) { 317 // Already reallocated? 318 LOG(FATAL) << "subproc_fd(" << subproc_fd << ") != subproc_fde->fd(" << subproc_fde->fd 319 << ")"; 320 return; 321 } 322 323 subproc_fde->force_eof = 1; 324 325 int rcount = 0; 326 ioctl(subproc_fd, FIONREAD, &rcount); 327 D("subproc with fd %d has rcount=%d, err=%d", subproc_fd, rcount, errno); 328 if (rcount != 0) { 329 // If there is data left, it will show up in the select(). 330 // This works because there is no other thread reading that 331 // data when in this fd_func(). 332 return; 333 } 334 335 D("subproc_fde %s", dump_fde(subproc_fde).c_str()); 336 subproc_fde->events |= FDE_READ; 337 if(subproc_fde->state & FDE_PENDING) { 338 return; 339 } 340 subproc_fde->state |= FDE_PENDING; 341 fdevent_call_fdfunc(subproc_fde); 342 } 343 } 344 345 void fdevent_subproc_setup() 346 { 347 int s[2]; 348 349 if(adb_socketpair(s)) { 350 PLOG(FATAL) << "cannot create shell-exit socket-pair"; 351 } 352 D("fdevent_subproc: socket pair (%d, %d)", s[0], s[1]); 353 354 SHELL_EXIT_NOTIFY_FD = s[0]; 355 fdevent *fde = fdevent_create(s[1], fdevent_subproc_event_func, NULL); 356 CHECK(fde != nullptr) << "cannot create fdevent for shell-exit handler"; 357 fdevent_add(fde, FDE_READ); 358 } 359 #endif // !ADB_HOST 360 361 void fdevent_loop() 362 { 363 set_main_thread(); 364 #if !ADB_HOST 365 fdevent_subproc_setup(); 366 #endif // !ADB_HOST 367 368 while (true) { 369 if (terminate_loop) { 370 return; 371 } 372 373 D("--- --- waiting for events"); 374 375 fdevent_process(); 376 377 while (!g_pending_list.empty()) { 378 fdevent* fde = g_pending_list.front(); 379 g_pending_list.pop_front(); 380 fdevent_call_fdfunc(fde); 381 } 382 } 383 } 384 385 void fdevent_terminate_loop() { 386 terminate_loop = true; 387 } 388 389 size_t fdevent_installed_count() { 390 return g_poll_node_map.size(); 391 } 392 393 void fdevent_reset() { 394 g_poll_node_map.clear(); 395 g_pending_list.clear(); 396 main_thread_valid = false; 397 terminate_loop = false; 398 } 399