| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 #include "platform/globals.h" | |
| 6 #if defined(TARGET_OS_ANDROID) | |
| 7 | |
| 8 #include <errno.h> // NOLINT | |
| 9 #include <stdio.h> // NOLINT | |
| 10 #include <stdlib.h> // NOLINT | |
| 11 #include <sys/epoll.h> // NOLINT | |
| 12 | |
| 13 #include "bin/dbg_connection.h" | |
| 14 #include "bin/fdutils.h" | |
| 15 #include "bin/log.h" | |
| 16 #include "bin/socket.h" | |
| 17 | |
| 18 #include "platform/signal_blocker.h" | |
| 19 | |
| 20 | |
| 21 namespace dart { | |
| 22 namespace bin { | |
| 23 | |
| 24 intptr_t DebuggerConnectionImpl::epoll_fd_ = -1; | |
| 25 int DebuggerConnectionImpl::wakeup_fds_[2] = {-1, -1}; | |
| 26 | |
| 27 | |
| 28 void DebuggerConnectionImpl::HandleEvent(struct epoll_event* event) { | |
| 29 if (event->data.fd == DebuggerConnectionHandler::listener_fd_) { | |
| 30 if (DebuggerConnectionHandler::IsConnected()) { | |
| 31 FATAL("Cannot connect to more than one debugger.\n"); | |
| 32 } | |
| 33 intptr_t fd = ServerSocket::Accept(event->data.fd); | |
| 34 if (fd < 0) { | |
| 35 FATAL("Accepting new debugger connection failed.\n"); | |
| 36 } | |
| 37 FDUtils::SetBlocking(fd); | |
| 38 DebuggerConnectionHandler::AcceptDbgConnection(fd); | |
| 39 // TODO(hausner): add the debugger wire socket fd to the event poll queue | |
| 40 // once we poll the debugger connection. | |
| 41 } else if (event->data.fd == wakeup_fds_[0]) { | |
| 42 // Sync message. Not yet implemented. | |
| 43 UNIMPLEMENTED(); | |
| 44 } else { | |
| 45 Log::Print("unexpected: receiving debugger connection event.\n"); | |
| 46 UNIMPLEMENTED(); | |
| 47 } | |
| 48 } | |
| 49 | |
| 50 | |
| 51 void DebuggerConnectionImpl::Handler(uword args) { | |
| 52 static const int kMaxEvents = 4; | |
| 53 struct epoll_event events[kMaxEvents]; | |
| 54 while (1) { | |
| 55 const int no_timeout = -1; | |
| 56 intptr_t result = TEMP_FAILURE_RETRY( | |
| 57 epoll_wait(epoll_fd_, events, kMaxEvents, no_timeout)); | |
| 58 ASSERT(EAGAIN == EWOULDBLOCK); | |
| 59 if (result == -1) { | |
| 60 if (errno != EWOULDBLOCK) { | |
| 61 perror("epoll_wait failed"); | |
| 62 } | |
| 63 } else { | |
| 64 ASSERT(result <= kMaxEvents); | |
| 65 for (int i = 0; i < result; i++) { | |
| 66 HandleEvent(&events[i]); | |
| 67 } | |
| 68 } | |
| 69 } | |
| 70 } | |
| 71 | |
| 72 | |
| 73 void DebuggerConnectionImpl::SetupPollQueue() { | |
| 74 int result = NO_RETRY_EXPECTED(pipe(wakeup_fds_)); | |
| 75 if (result != 0) { | |
| 76 FATAL1("Pipe creation failed with error %d\n", result); | |
| 77 } | |
| 78 FDUtils::SetNonBlocking(wakeup_fds_[0]); | |
| 79 | |
| 80 static const int kEpollInitialSize = 16; | |
| 81 epoll_fd_ = NO_RETRY_EXPECTED(epoll_create(kEpollInitialSize)); | |
| 82 if (epoll_fd_ == -1) { | |
| 83 FATAL("Failed creating epoll file descriptor"); | |
| 84 } | |
| 85 | |
| 86 // Register the wakeup _fd with the epoll instance. | |
| 87 struct epoll_event event; | |
| 88 event.events = EPOLLIN; | |
| 89 event.data.fd = wakeup_fds_[0]; | |
| 90 int status = NO_RETRY_EXPECTED(epoll_ctl( | |
| 91 epoll_fd_, EPOLL_CTL_ADD, wakeup_fds_[0], &event)); | |
| 92 if (status == -1) { | |
| 93 FATAL("Failed adding wakeup fd to epoll instance"); | |
| 94 } | |
| 95 | |
| 96 // Register the listener_fd with the epoll instance. | |
| 97 event.events = EPOLLIN; | |
| 98 event.data.fd = DebuggerConnectionHandler::listener_fd_; | |
| 99 status = NO_RETRY_EXPECTED(epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, | |
| 100 DebuggerConnectionHandler::listener_fd_, &event)); | |
| 101 if (status == -1) { | |
| 102 FATAL("Failed adding listener fd to epoll instance"); | |
| 103 } | |
| 104 } | |
| 105 | |
| 106 | |
| 107 void DebuggerConnectionImpl::StartHandler(int port_number) { | |
| 108 ASSERT(DebuggerConnectionHandler::listener_fd_ != -1); | |
| 109 SetupPollQueue(); | |
| 110 int result = Thread::Start(&DebuggerConnectionImpl::Handler, 0); | |
| 111 if (result != 0) { | |
| 112 FATAL1("Failed to start debugger connection handler thread: %d\n", result); | |
| 113 } | |
| 114 } | |
| 115 | |
| 116 | |
| 117 intptr_t DebuggerConnectionImpl::Send(intptr_t socket, | |
| 118 const char* buf, | |
| 119 int len) { | |
| 120 return TEMP_FAILURE_RETRY(write(socket, buf, len)); | |
| 121 } | |
| 122 | |
| 123 | |
| 124 intptr_t DebuggerConnectionImpl::Receive(intptr_t socket, char* buf, int len) { | |
| 125 return TEMP_FAILURE_RETRY(read(socket, buf, len)); | |
| 126 } | |
| 127 | |
| 128 } // namespace bin | |
| 129 } // namespace dart | |
| 130 | |
| 131 #endif // defined(TARGET_OS_ANDROID) | |
| OLD | NEW |