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