16c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen/* 26c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * Copyright (C) 2011 The Android Open Source Project 36c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * 46c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * Licensed under the Apache License, Version 2.0 (the "License"); 56c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * you may not use this file except in compliance with the License. 66c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * You may obtain a copy of the License at 76c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * 86c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * http://www.apache.org/licenses/LICENSE-2.0 96c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * 106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * Unless required by applicable law or agreed to in writing, software 116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * distributed under the License is distributed on an "AS IS" BASIS, 126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * See the License for the specific language governing permissions and 146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen * limitations under the License. 156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen */ 166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#define LOG_TAG "common_time" 186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <utils/Log.h> 196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <fcntl.h> 216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <linux/in.h> 226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <linux/tcp.h> 236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <poll.h> 246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <sys/socket.h> 256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <sys/types.h> 266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <unistd.h> 276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <utils/Errors.h> 286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <utils/misc.h> 296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include <common_time/local_clock.h> 316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include "common_clock.h" 336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#include "diag_thread.h" 346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#define kMaxEvents 16 366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen#define kListenPort 9876 376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenstatic bool setNonblocking(int fd) { 396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen int flags = fcntl(fd, F_GETFL); 406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) { 416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen ALOGE("Failed to set socket (%d) to non-blocking mode (errno %d)", 426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen fd, errno); 436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen return false; 446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen } 456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen return true; 476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen} 486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenstatic bool setNodelay(int fd) { 506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen int tmp = 1; 516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &tmp, sizeof(tmp)) < 0) { 526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen ALOGE("Failed to set socket (%d) to no-delay mode (errno %d)", 536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen fd, errno); 546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen return false; 556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen } 566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen return true; 586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen} 596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chennamespace android { 616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 626c929510474caa14dc9d56826b2c65552861d6b3Mike J. ChenDiagThread::DiagThread(CommonClock* common_clock, LocalClock* local_clock) { 636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen common_clock_ = common_clock; 646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen local_clock_ = local_clock; 656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen listen_fd_ = -1; 666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen data_fd_ = -1; 676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen kernel_logID_basis_known_ = false; 686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen discipline_log_ID_ = 0; 696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen} 706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 716c929510474caa14dc9d56826b2c65552861d6b3Mike J. ChenDiagThread::~DiagThread() { 726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen} 736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenstatus_t DiagThread::startWorkThread() { 756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen status_t res; 766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen stopWorkThread(); 776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen res = run("Diag"); 786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen if (res != OK) 806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen ALOGE("Failed to start work thread (res = %d)", res); 816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen return res; 836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen} 846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid DiagThread::stopWorkThread() { 866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen status_t res; 876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen res = requestExitAndWait(); // block until thread exit. 886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen if (res != OK) 896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen ALOGE("Failed to stop work thread (res = %d)", res); 906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen} 916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool DiagThread::openListenSocket() { 936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen bool ret = false; 946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen int flags; 956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen cleanupListenSocket(); 966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen if ((listen_fd_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { 986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen ALOGE("Socket failed."); 996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen goto bailout; 1006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen } 1016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 1026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen // Set non-blocking operation 1036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen if (!setNonblocking(listen_fd_)) 1046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen goto bailout; 1056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 1066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen struct sockaddr_in addr; 1076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen memset(&addr, 0, sizeof(addr)); 1086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen addr.sin_family = AF_INET; 1096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen addr.sin_addr.s_addr = INADDR_ANY; 1106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen addr.sin_port = htons(kListenPort); 1116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 1126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen if (bind(listen_fd_, (struct sockaddr*)&addr, sizeof(addr)) < 0) { 1136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen ALOGE("Bind failed."); 1146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen goto bailout; 1156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen } 1166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 1176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen if (listen(listen_fd_, 1) < 0) { 1186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen ALOGE("Listen failed."); 1196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen goto bailout; 1206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen } 1216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 1226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen ret = true; 1236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbailout: 1246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen if (!ret) 1256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen cleanupListenSocket(); 1266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 1276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen return ret; 1286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen} 1296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 1306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid DiagThread::cleanupListenSocket() { 1316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen if (listen_fd_ >= 0) { 1326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen int res; 1336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 1346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen struct linger l; 1356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen l.l_onoff = 1; 1366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen l.l_linger = 0; 1376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 1386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen setsockopt(listen_fd_, SOL_SOCKET, SO_LINGER, &l, sizeof(l)); 1396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen shutdown(listen_fd_, SHUT_RDWR); 1406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen close(listen_fd_); 1416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen listen_fd_ = -1; 1426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen } 1436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen} 1446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 1456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid DiagThread::cleanupDataSocket() { 1466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen if (data_fd_ >= 0) { 1476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen int res; 1486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 1496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen struct linger l; 1506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen l.l_onoff = 1; 1516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen l.l_linger = 0; 1526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 1536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen setsockopt(data_fd_, SOL_SOCKET, SO_LINGER, &l, sizeof(l)); 1546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen shutdown(data_fd_, SHUT_RDWR); 1556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen close(data_fd_); 1566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen data_fd_ = -1; 1576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen } 1586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen} 1596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 1606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid DiagThread::resetLogIDs() { 1616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen // Drain and discard all of the events from the kernel 1626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen struct local_time_debug_event events[kMaxEvents]; 1636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen while(local_clock_->getDebugLog(events, kMaxEvents) > 0) 1646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen ; 1656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 1666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen { 1676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen Mutex::Autolock lock(&discipline_log_lock_); 1686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen discipline_log_.clear(); 1696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen discipline_log_ID_ = 0; 1706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen } 1716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 1726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen kernel_logID_basis_known_ = false; 1736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen} 1746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 1756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenvoid DiagThread::pushDisciplineEvent(int64_t observed_local_time, 1766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen int64_t observed_common_time, 1776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen int64_t nominal_common_time, 1786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen int32_t total_correction, 17911bc45fcba96cf7ccc5f67b3c47088c2c89c8e7aKent Ryhorchuk int32_t rtt) { 1806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen Mutex::Autolock lock(&discipline_log_lock_); 1816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 1826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen DisciplineEventRecord evt; 1836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 1846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen evt.event_id = discipline_log_ID_++; 1856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 1866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen evt.action_local_time = local_clock_->getLocalTime(); 1876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen common_clock_->localToCommon(evt.action_local_time, 1886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen &evt.action_common_time); 1896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 1906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen evt.observed_local_time = observed_local_time; 1916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen evt.observed_common_time = observed_common_time; 1926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen evt.nominal_common_time = nominal_common_time; 1936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen evt.total_correction = total_correction; 19411bc45fcba96cf7ccc5f67b3c47088c2c89c8e7aKent Ryhorchuk evt.rtt = rtt; 1956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 1966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen discipline_log_.push_back(evt); 1976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen while (discipline_log_.size() > kMaxDisciplineLogSize) 1986c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen discipline_log_.erase(discipline_log_.begin()); 1996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen} 2006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 2016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbool DiagThread::threadLoop() { 2026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen struct pollfd poll_fds[1]; 2036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 2046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen if (!openListenSocket()) { 2056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen ALOGE("Failed to open listen socket"); 2066c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen goto bailout; 2076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen } 2086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 2096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen while (!exitPending()) { 2106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen memset(&poll_fds, 0, sizeof(poll_fds)); 2116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 2126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen if (data_fd_ < 0) { 2136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen poll_fds[0].fd = listen_fd_; 2146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen poll_fds[0].events = POLLIN; 2156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen } else { 2166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen poll_fds[0].fd = data_fd_; 2176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen poll_fds[0].events = POLLRDHUP | POLLIN; 2186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen } 2196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 2206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen int poll_res = poll(poll_fds, NELEM(poll_fds), 50); 2216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen if (poll_res < 0) { 2226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen ALOGE("Fatal error (%d,%d) while waiting on events", 2236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen poll_res, errno); 2246c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen goto bailout; 2256c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen } 2266c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 2276c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen if (exitPending()) 2286c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen break; 2296c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 2306c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen if (poll_fds[0].revents) { 2316c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen if (poll_fds[0].fd == listen_fd_) { 2326c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen data_fd_ = accept(listen_fd_, NULL, NULL); 2336c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 2346c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen if (data_fd_ < 0) { 2356c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen ALOGW("Failed accept on socket %d with err %d", 2366c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen listen_fd_, errno); 2376c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen } else { 2386c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen if (!setNonblocking(data_fd_)) 2396c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen cleanupDataSocket(); 2406c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen if (!setNodelay(data_fd_)) 2416c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen cleanupDataSocket(); 2426c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen } 2436c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen } else 2446c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen if (poll_fds[0].fd == data_fd_) { 2456c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen if (poll_fds[0].revents & POLLRDHUP) { 2466c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen // Connection hung up; time to clean up. 2476c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen cleanupDataSocket(); 2486c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen } else 2496c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen if (poll_fds[0].revents & POLLIN) { 2506c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen uint8_t cmd; 2516c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen if (read(data_fd_, &cmd, sizeof(cmd)) > 0) { 2526c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen switch(cmd) { 2536c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen case 'r': 2546c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen case 'R': 2556c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen resetLogIDs(); 2566c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen break; 2576c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen } 2586c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen } 2596c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen } 2606c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen } 2616c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen } 2626c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 2636c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen struct local_time_debug_event events[kMaxEvents]; 2646c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen int amt = local_clock_->getDebugLog(events, kMaxEvents); 2656c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 2666c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen if (amt > 0) { 2676c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen for (int i = 0; i < amt; i++) { 2686c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen struct local_time_debug_event& e = events[i]; 2696c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 2706c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen if (!kernel_logID_basis_known_) { 2716c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen kernel_logID_basis_ = e.local_timesync_event_id; 2726c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen kernel_logID_basis_known_ = true; 2736c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen } 2746c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 2756c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen char buf[1024]; 2766c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen int64_t common_time; 2776c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen status_t res = common_clock_->localToCommon(e.local_time, 2786c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen &common_time); 2796c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen snprintf(buf, sizeof(buf), "E,%lld,%lld,%lld,%d\n", 2806c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen e.local_timesync_event_id - kernel_logID_basis_, 2816c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen e.local_time, 2826c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen common_time, 2836c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen (OK == res) ? 1 : 0); 2846c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen buf[sizeof(buf) - 1] = 0; 2856c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 2866c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen if (data_fd_ >= 0) 2876c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen write(data_fd_, buf, strlen(buf)); 2886c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen } 2896c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen } 2906c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 2916c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen { // scope for autolock pattern 2926c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen Mutex::Autolock lock(&discipline_log_lock_); 2936c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 2946c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen while (discipline_log_.size() > 0) { 2956c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen char buf[1024]; 2966c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen DisciplineEventRecord& e = *discipline_log_.begin(); 2976c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen snprintf(buf, sizeof(buf), 29811bc45fcba96cf7ccc5f67b3c47088c2c89c8e7aKent Ryhorchuk "D,%lld,%lld,%lld,%lld,%lld,%lld,%d,%d\n", 2996c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen e.event_id, 3006c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen e.action_local_time, 3016c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen e.action_common_time, 3026c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen e.observed_local_time, 3036c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen e.observed_common_time, 3046c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen e.nominal_common_time, 3056c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen e.total_correction, 30611bc45fcba96cf7ccc5f67b3c47088c2c89c8e7aKent Ryhorchuk e.rtt); 3076c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen buf[sizeof(buf) - 1] = 0; 3086c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 3096c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen if (data_fd_ >= 0) 3106c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen write(data_fd_, buf, strlen(buf)); 3116c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 3126c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen discipline_log_.erase(discipline_log_.begin()); 3136c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen } 3146c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen } 3156c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen } 3166c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 3176c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chenbailout: 3186c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen cleanupDataSocket(); 3196c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen cleanupListenSocket(); 3206c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen return false; 3216c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen} 3226c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen 3236c929510474caa14dc9d56826b2c65552861d6b3Mike J. Chen} // namespace android 324