855 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			855 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| diff --git a/CMakeLists.txt b/CMakeLists.txt
 | |
| index d18840f..8c9f075 100644
 | |
| --- a/CMakeLists.txt
 | |
| +++ b/CMakeLists.txt
 | |
| @@ -11,14 +11,15 @@ endif()
 | |
|  set(CXX_FLAGS
 | |
|   -g
 | |
|   # -DVALGRIND
 | |
| - # -DMUDUO_STD_STRING
 | |
| - -DCHECK_PTHREAD_RETURN_VALUE
 | |
| + # -DCHECK_PTHREAD_RETURN_VALUE
 | |
| + -DMUDUO_STD_STRING
 | |
|   -D_FILE_OFFSET_BITS=64
 | |
|   -Wall
 | |
|   -Wextra
 | |
| - -Werror
 | |
| + # -Werror
 | |
|   -Wconversion
 | |
|   -Wno-unused-parameter
 | |
| + -Wno-sign-conversion
 | |
|   -Wold-style-cast
 | |
|   -Woverloaded-virtual
 | |
|   -Wpointer-arith
 | |
| @@ -27,16 +28,15 @@ set(CXX_FLAGS
 | |
|   -march=native
 | |
|   # -MMD
 | |
|   # -std=c++0x
 | |
| - -rdynamic
 | |
|   )
 | |
|  if(CMAKE_BUILD_BITS EQUAL 32)
 | |
|    list(APPEND CXX_FLAGS "-m32")
 | |
|  endif()
 | |
|  string(REPLACE ";" " " CMAKE_CXX_FLAGS "${CXX_FLAGS}")
 | |
|  
 | |
| -set(CMAKE_CXX_COMPILER "g++")
 | |
| +set(CMAKE_CXX_COMPILER "clang++")
 | |
|  set(CMAKE_CXX_FLAGS_DEBUG "-O0")
 | |
| -set(CMAKE_CXX_FLAGS_RELEASE "-O2 -finline-limit=1000 -DNDEBUG")
 | |
| +set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
 | |
|  set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
 | |
|  set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
 | |
|  
 | |
| diff --git a/examples/roundtrip/roundtrip_udp.cc b/examples/roundtrip/roundtrip_udp.cc
 | |
| index 5f171b8..d612570 100644
 | |
| --- a/examples/roundtrip/roundtrip_udp.cc
 | |
| +++ b/examples/roundtrip/roundtrip_udp.cc
 | |
| @@ -17,7 +17,12 @@ const size_t frameLen = 2*sizeof(int64_t);
 | |
|  
 | |
|  int createNonblockingUDP()
 | |
|  {
 | |
| +#ifndef  __MACH__
 | |
|    int sockfd = ::socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK | SOCK_CLOEXEC, IPPROTO_UDP);
 | |
| +#else
 | |
| +  int sockfd = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
 | |
| +  sockets::setNonBlockAndCloseOnExec(sockfd);
 | |
| +#endif
 | |
|    if (sockfd < 0)
 | |
|    {
 | |
|      LOG_SYSFATAL << "::socket";
 | |
| diff --git a/examples/socks4a/tcprelay.cc b/examples/socks4a/tcprelay.cc
 | |
| index a4c6ec9..09a6a3a 100644
 | |
| --- a/examples/socks4a/tcprelay.cc
 | |
| +++ b/examples/socks4a/tcprelay.cc
 | |
| @@ -1,6 +1,5 @@
 | |
|  #include "tunnel.h"
 | |
|  
 | |
| -#include <malloc.h>
 | |
|  #include <stdio.h>
 | |
|  #include <sys/resource.h>
 | |
|  
 | |
| @@ -43,7 +42,6 @@ void onServerMessage(const TcpConnectionPtr& conn, Buffer* buf, Timestamp)
 | |
|  
 | |
|  void memstat()
 | |
|  {
 | |
| -  malloc_stats();
 | |
|  }
 | |
|  
 | |
|  int main(int argc, char* argv[])
 | |
| diff --git a/muduo/base/CMakeLists.txt b/muduo/base/CMakeLists.txt
 | |
| index 6e250d4..a76404f 100644
 | |
| --- a/muduo/base/CMakeLists.txt
 | |
| +++ b/muduo/base/CMakeLists.txt
 | |
| @@ -16,10 +16,10 @@ set(base_SRCS
 | |
|    )
 | |
|  
 | |
|  add_library(muduo_base ${base_SRCS})
 | |
| -target_link_libraries(muduo_base pthread rt)
 | |
| +target_link_libraries(muduo_base pthread)
 | |
|  
 | |
|  add_library(muduo_base_cpp11 ${base_SRCS})
 | |
| -target_link_libraries(muduo_base_cpp11 pthread rt)
 | |
| +target_link_libraries(muduo_base_cpp11 pthread)
 | |
|  set_target_properties(muduo_base_cpp11 PROPERTIES COMPILE_FLAGS "-std=c++0x")
 | |
|  
 | |
|  install(TARGETS muduo_base DESTINATION lib)
 | |
| diff --git a/muduo/base/Condition.cc b/muduo/base/Condition.cc
 | |
| index f10ace3..73a1715 100644
 | |
| --- a/muduo/base/Condition.cc
 | |
| +++ b/muduo/base/Condition.cc
 | |
| @@ -6,13 +6,21 @@
 | |
|  #include <muduo/base/Condition.h>
 | |
|  
 | |
|  #include <errno.h>
 | |
| +#include <sys/time.h>
 | |
|  
 | |
|  // returns true if time out, false otherwise.
 | |
|  bool muduo::Condition::waitForSeconds(int seconds)
 | |
|  {
 | |
|    struct timespec abstime;
 | |
| +#ifdef CLOCK_REALTIME
 | |
|    // FIXME: use CLOCK_MONOTONIC or CLOCK_MONOTONIC_RAW to prevent time rewind.
 | |
|    clock_gettime(CLOCK_REALTIME, &abstime);
 | |
| +#else  // Mac OS X
 | |
| +  struct timeval tv;
 | |
| +  gettimeofday(&tv, NULL);
 | |
| +  abstime.tv_sec = tv.tv_sec;
 | |
| +  abstime.tv_nsec = tv.tv_usec * 1000;
 | |
| +#endif
 | |
|    abstime.tv_sec += seconds;
 | |
|    MutexLock::UnassignGuard ug(mutex_);
 | |
|    return ETIMEDOUT == pthread_cond_timedwait(&pcond_, mutex_.getPthreadMutex(), &abstime);
 | |
| diff --git a/muduo/base/FileUtil.cc b/muduo/base/FileUtil.cc
 | |
| index 999b0e5..ad9da8a 100644
 | |
| --- a/muduo/base/FileUtil.cc
 | |
| +++ b/muduo/base/FileUtil.cc
 | |
| @@ -64,8 +64,12 @@ void FileUtil::AppendFile::flush()
 | |
|  
 | |
|  size_t FileUtil::AppendFile::write(const char* logline, size_t len)
 | |
|  {
 | |
| +#ifdef fwrite_unlocked
 | |
|    // #undef fwrite_unlocked
 | |
|    return ::fwrite_unlocked(logline, 1, len, fp_);
 | |
| +#else
 | |
| +  return ::fwrite(logline, 1, len, fp_);
 | |
| +#endif
 | |
|  }
 | |
|  
 | |
|  FileUtil::ReadSmallFile::ReadSmallFile(StringArg filename)
 | |
| diff --git a/muduo/base/Logging.cc b/muduo/base/Logging.cc
 | |
| index 341d627..9376007 100644
 | |
| --- a/muduo/base/Logging.cc
 | |
| +++ b/muduo/base/Logging.cc
 | |
| @@ -36,7 +36,12 @@ __thread time_t t_lastSecond;
 | |
|  
 | |
|  const char* strerror_tl(int savedErrno)
 | |
|  {
 | |
| +#ifndef __MACH__
 | |
|    return strerror_r(savedErrno, t_errnobuf, sizeof t_errnobuf);
 | |
| +#else
 | |
| +  strerror_r(savedErrno, t_errnobuf, sizeof t_errnobuf);
 | |
| +  return t_errnobuf;
 | |
| +#endif
 | |
|  }
 | |
|  
 | |
|  Logger::LogLevel initLogLevel()
 | |
| diff --git a/muduo/base/Thread.cc b/muduo/base/Thread.cc
 | |
| index 9d64780..cddcac1 100644
 | |
| --- a/muduo/base/Thread.cc
 | |
| +++ b/muduo/base/Thread.cc
 | |
| @@ -15,10 +15,12 @@
 | |
|  #include <errno.h>
 | |
|  #include <stdio.h>
 | |
|  #include <unistd.h>
 | |
| -#include <sys/prctl.h>
 | |
|  #include <sys/syscall.h>
 | |
|  #include <sys/types.h>
 | |
| +#ifndef __MACH__
 | |
| +#include <sys/prctl.h>
 | |
|  #include <linux/unistd.h>
 | |
| +#endif
 | |
|  
 | |
|  namespace muduo
 | |
|  {
 | |
| @@ -35,10 +37,17 @@ namespace CurrentThread
 | |
|  namespace detail
 | |
|  {
 | |
|  
 | |
| +#ifdef __MACH__
 | |
| +pid_t gettid()
 | |
| +{
 | |
| +  return pthread_mach_thread_np(pthread_self());
 | |
| +}
 | |
| +#else
 | |
|  pid_t gettid()
 | |
|  {
 | |
|    return static_cast<pid_t>(::syscall(SYS_gettid));
 | |
|  }
 | |
| +#endif
 | |
|  
 | |
|  void afterFork()
 | |
|  {
 | |
| @@ -88,7 +97,9 @@ struct ThreadData
 | |
|      }
 | |
|  
 | |
|      muduo::CurrentThread::t_threadName = name_.empty() ? "muduoThread" : name_.c_str();
 | |
| +#ifndef __MACH__
 | |
|      ::prctl(PR_SET_NAME, muduo::CurrentThread::t_threadName);
 | |
| +#endif
 | |
|      try
 | |
|      {
 | |
|        func_();
 | |
| diff --git a/muduo/base/TimeZone.cc b/muduo/base/TimeZone.cc
 | |
| index 37959d9..f95beb3 100644
 | |
| --- a/muduo/base/TimeZone.cc
 | |
| +++ b/muduo/base/TimeZone.cc
 | |
| @@ -8,7 +8,7 @@
 | |
|  #include <vector>
 | |
|  
 | |
|  //#define _BSD_SOURCE
 | |
| -#include <endian.h>
 | |
| +#include <muduo/net/Endian.h>
 | |
|  
 | |
|  #include <stdint.h>
 | |
|  #include <stdio.h>
 | |
| @@ -285,7 +285,7 @@ struct tm TimeZone::toLocalTime(time_t seconds) const
 | |
|      ::gmtime_r(&localSeconds, &localTime); // FIXME: fromUtcTime
 | |
|      localTime.tm_isdst = local->isDst;
 | |
|      localTime.tm_gmtoff = local->gmtOffset;
 | |
| -    localTime.tm_zone = &data.abbreviation[local->arrbIdx];
 | |
| +    localTime.tm_zone = const_cast<char*>(&data.abbreviation[local->arrbIdx]);
 | |
|    }
 | |
|  
 | |
|    return localTime;
 | |
| diff --git a/muduo/base/tests/AsyncLogging_test.cc b/muduo/base/tests/AsyncLogging_test.cc
 | |
| index bd9fe59..e510fd4 100644
 | |
| --- a/muduo/base/tests/AsyncLogging_test.cc
 | |
| +++ b/muduo/base/tests/AsyncLogging_test.cc
 | |
| @@ -4,6 +4,9 @@
 | |
|  
 | |
|  #include <stdio.h>
 | |
|  #include <sys/resource.h>
 | |
| +#ifdef __MACH__
 | |
| +#include <libgen.h>  // basename()
 | |
| +#endif
 | |
|  
 | |
|  int kRollSize = 500*1000*1000;
 | |
|  
 | |
| diff --git a/muduo/base/tests/BlockingQueue_test.cc b/muduo/base/tests/BlockingQueue_test.cc
 | |
| index c392773..6977578 100644
 | |
| --- a/muduo/base/tests/BlockingQueue_test.cc
 | |
| +++ b/muduo/base/tests/BlockingQueue_test.cc
 | |
| @@ -80,9 +80,6 @@ class Test
 | |
|  void testMove()
 | |
|  {
 | |
|  #ifdef __GXX_EXPERIMENTAL_CXX0X__
 | |
| -
 | |
| -// std::unique_ptr requires gcc 4.4 or later
 | |
| -#if __GNUC_PREREQ (4,4)
 | |
|    muduo::BlockingQueue<std::unique_ptr<int>> queue;
 | |
|    queue.put(std::unique_ptr<int>(new int(42)));
 | |
|    std::unique_ptr<int> x = queue.take();
 | |
| @@ -92,8 +89,6 @@ void testMove()
 | |
|    std::unique_ptr<int> y = queue.take();
 | |
|    printf("took %d\n", *y);
 | |
|  #endif
 | |
| -
 | |
| -#endif
 | |
|  }
 | |
|  
 | |
|  int main()
 | |
| diff --git a/muduo/base/tests/GzipFile_test.cc b/muduo/base/tests/GzipFile_test.cc
 | |
| index 6dc0d4d..b051ca8 100644
 | |
| --- a/muduo/base/tests/GzipFile_test.cc
 | |
| +++ b/muduo/base/tests/GzipFile_test.cc
 | |
| @@ -2,6 +2,8 @@
 | |
|  
 | |
|  #include <muduo/base/Logging.h>
 | |
|  
 | |
| +#include <errno.h>
 | |
| +
 | |
|  int main()
 | |
|  {
 | |
|    const char* filename = "/tmp/gzipfile_test.gz";
 | |
| diff --git a/muduo/base/tests/LogFile_test.cc b/muduo/base/tests/LogFile_test.cc
 | |
| index e77d68d..d27d65e 100644
 | |
| --- a/muduo/base/tests/LogFile_test.cc
 | |
| +++ b/muduo/base/tests/LogFile_test.cc
 | |
| @@ -1,5 +1,8 @@
 | |
|  #include <muduo/base/LogFile.h>
 | |
|  #include <muduo/base/Logging.h>
 | |
| +#ifdef __MACH__
 | |
| +#include <libgen.h>  // basename()
 | |
| +#endif
 | |
|  
 | |
|  boost::scoped_ptr<muduo::LogFile> g_logFile;
 | |
|  
 | |
| diff --git a/muduo/net/CMakeLists.txt b/muduo/net/CMakeLists.txt
 | |
| index 0127c48..9ea16ed 100644
 | |
| --- a/muduo/net/CMakeLists.txt
 | |
| +++ b/muduo/net/CMakeLists.txt
 | |
| @@ -16,7 +16,6 @@ set(net_SRCS
 | |
|    InetAddress.cc
 | |
|    Poller.cc
 | |
|    poller/DefaultPoller.cc
 | |
| -  poller/EPollPoller.cc
 | |
|    poller/PollPoller.cc
 | |
|    Socket.cc
 | |
|    SocketsOps.cc
 | |
| diff --git a/muduo/net/Channel.cc b/muduo/net/Channel.cc
 | |
| index f5e6624..62fbd6f 100644
 | |
| --- a/muduo/net/Channel.cc
 | |
| +++ b/muduo/net/Channel.cc
 | |
| @@ -102,6 +102,9 @@ void Channel::handleEventWithGuard(Timestamp receiveTime)
 | |
|    {
 | |
|      if (errorCallback_) errorCallback_();
 | |
|    }
 | |
| +#ifndef POLLRDHUP
 | |
| +  const int POLLRDHUP = 0;
 | |
| +#endif
 | |
|    if (revents_ & (POLLIN | POLLPRI | POLLRDHUP))
 | |
|    {
 | |
|      if (readCallback_) readCallback_(receiveTime);
 | |
| @@ -135,8 +138,10 @@ string Channel::eventsToString(int fd, int ev)
 | |
|      oss << "OUT ";
 | |
|    if (ev & POLLHUP)
 | |
|      oss << "HUP ";
 | |
| +#ifdef POLLRDHUP
 | |
|    if (ev & POLLRDHUP)
 | |
|      oss << "RDHUP ";
 | |
| +#endif
 | |
|    if (ev & POLLERR)
 | |
|      oss << "ERR ";
 | |
|    if (ev & POLLNVAL)
 | |
| diff --git a/muduo/net/Endian.h b/muduo/net/Endian.h
 | |
| index b277503..851e449 100644
 | |
| --- a/muduo/net/Endian.h
 | |
| +++ b/muduo/net/Endian.h
 | |
| @@ -12,7 +12,28 @@
 | |
|  #define MUDUO_NET_ENDIAN_H
 | |
|  
 | |
|  #include <stdint.h>
 | |
| +
 | |
| +#ifdef __MACH__
 | |
| +#include <libkern/OSByteOrder.h>
 | |
| + 
 | |
| +#define htobe16(x) OSSwapHostToBigInt16(x)
 | |
| +#define htole16(x) OSSwapHostToLittleInt16(x)
 | |
| +#define be16toh(x) OSSwapBigToHostInt16(x)
 | |
| +#define le16toh(x) OSSwapLittleToHostInt16(x)
 | |
| + 
 | |
| +#define htobe32(x) OSSwapHostToBigInt32(x)
 | |
| +#define htole32(x) OSSwapHostToLittleInt32(x)
 | |
| +#define be32toh(x) OSSwapBigToHostInt32(x)
 | |
| +#define le32toh(x) OSSwapLittleToHostInt32(x)
 | |
| + 
 | |
| +#define htobe64(x) OSSwapHostToBigInt64(x)
 | |
| +#define htole64(x) OSSwapHostToLittleInt64(x)
 | |
| +#define be64toh(x) OSSwapBigToHostInt64(x)
 | |
| +#define le64toh(x) OSSwapLittleToHostInt64(x)
 | |
| +#else
 | |
|  #include <endian.h>
 | |
| +#endif
 | |
| +
 | |
|  
 | |
|  namespace muduo
 | |
|  {
 | |
| @@ -60,8 +81,8 @@ inline uint16_t networkToHost16(uint16_t net16)
 | |
|  #if defined(__clang__) || __GNUC_MINOR__ >= 6
 | |
|  #pragma GCC diagnostic pop
 | |
|  #else
 | |
| -#pragma GCC diagnostic warning "-Wconversion"
 | |
| -#pragma GCC diagnostic warning "-Wold-style-cast"
 | |
| +//#pragma GCC diagnostic error "-Wconversion"
 | |
| +//#pragma GCC diagnostic error "-Wold-style-cast"
 | |
|  #endif
 | |
|  
 | |
|  
 | |
| diff --git a/muduo/net/EventLoop.cc b/muduo/net/EventLoop.cc
 | |
| index 7346838..19fde05 100644
 | |
| --- a/muduo/net/EventLoop.cc
 | |
| +++ b/muduo/net/EventLoop.cc
 | |
| @@ -18,7 +18,8 @@
 | |
|  #include <boost/bind.hpp>
 | |
|  
 | |
|  #include <signal.h>
 | |
| -#include <sys/eventfd.h>
 | |
| +#include <sys/types.h>
 | |
| +#include <sys/socket.h>
 | |
|  
 | |
|  using namespace muduo;
 | |
|  using namespace muduo::net;
 | |
| @@ -29,18 +30,6 @@ __thread EventLoop* t_loopInThisThread = 0;
 | |
|  
 | |
|  const int kPollTimeMs = 10000;
 | |
|  
 | |
| -int createEventfd()
 | |
| -{
 | |
| -  int evtfd = ::eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
 | |
| -  if (evtfd < 0)
 | |
| -  {
 | |
| -    LOG_SYSERR << "Failed in eventfd";
 | |
| -    abort();
 | |
| -  }
 | |
| -  return evtfd;
 | |
| -}
 | |
| -
 | |
| -#pragma GCC diagnostic ignored "-Wold-style-cast"
 | |
|  class IgnoreSigPipe
 | |
|  {
 | |
|   public:
 | |
| @@ -50,7 +39,6 @@ class IgnoreSigPipe
 | |
|      // LOG_TRACE << "Ignore SIGPIPE";
 | |
|    }
 | |
|  };
 | |
| -#pragma GCC diagnostic error "-Wold-style-cast"
 | |
|  
 | |
|  IgnoreSigPipe initObj;
 | |
|  }
 | |
| @@ -69,11 +57,15 @@ EventLoop::EventLoop()
 | |
|      threadId_(CurrentThread::tid()),
 | |
|      poller_(Poller::newDefaultPoller(this)),
 | |
|      timerQueue_(new TimerQueue(this)),
 | |
| -    wakeupFd_(createEventfd()),
 | |
| -    wakeupChannel_(new Channel(this, wakeupFd_)),
 | |
|      currentActiveChannel_(NULL)
 | |
|  {
 | |
|    LOG_DEBUG << "EventLoop created " << this << " in thread " << threadId_;
 | |
| +  if (::socketpair(AF_UNIX, SOCK_STREAM, 0, wakeupFd_) < 0)
 | |
| +  {
 | |
| +    LOG_SYSFATAL << "Failed in socketpair";
 | |
| +  }
 | |
| +  wakeupChannel_.reset(new Channel(this, wakeupFd_[0]));
 | |
| +
 | |
|    if (t_loopInThisThread)
 | |
|    {
 | |
|      LOG_FATAL << "Another EventLoop " << t_loopInThisThread
 | |
| @@ -95,7 +87,8 @@ EventLoop::~EventLoop()
 | |
|              << " destructs in thread " << CurrentThread::tid();
 | |
|    wakeupChannel_->disableAll();
 | |
|    wakeupChannel_->remove();
 | |
| -  ::close(wakeupFd_);
 | |
| +  ::close(wakeupFd_[0]);
 | |
| +  ::close(wakeupFd_[1]);
 | |
|    t_loopInThisThread = NULL;
 | |
|  }
 | |
|  
 | |
| @@ -110,12 +103,13 @@ void EventLoop::loop()
 | |
|    while (!quit_)
 | |
|    {
 | |
|      activeChannels_.clear();
 | |
| -    pollReturnTime_ = poller_->poll(kPollTimeMs, &activeChannels_);
 | |
| +    pollReturnTime_ = poller_->poll(timerQueue_->getTimeout(), &activeChannels_);
 | |
|      ++iteration_;
 | |
|      if (Logger::logLevel() <= Logger::TRACE)
 | |
|      {
 | |
|        printActiveChannels();
 | |
|      }
 | |
| +    timerQueue_->processTimers();
 | |
|      // TODO sort channel by priority
 | |
|      eventHandling_ = true;
 | |
|      for (ChannelList::iterator it = activeChannels_.begin();
 | |
| @@ -273,7 +267,7 @@ void EventLoop::abortNotInLoopThread()
 | |
|  void EventLoop::wakeup()
 | |
|  {
 | |
|    uint64_t one = 1;
 | |
| -  ssize_t n = sockets::write(wakeupFd_, &one, sizeof one);
 | |
| +  ssize_t n = sockets::write(wakeupFd_[1], &one, sizeof one);
 | |
|    if (n != sizeof one)
 | |
|    {
 | |
|      LOG_ERROR << "EventLoop::wakeup() writes " << n << " bytes instead of 8";
 | |
| @@ -283,7 +277,7 @@ void EventLoop::wakeup()
 | |
|  void EventLoop::handleRead()
 | |
|  {
 | |
|    uint64_t one = 1;
 | |
| -  ssize_t n = sockets::read(wakeupFd_, &one, sizeof one);
 | |
| +  ssize_t n = sockets::read(wakeupFd_[0], &one, sizeof one);
 | |
|    if (n != sizeof one)
 | |
|    {
 | |
|      LOG_ERROR << "EventLoop::handleRead() reads " << n << " bytes instead of 8";
 | |
| diff --git a/muduo/net/EventLoop.h b/muduo/net/EventLoop.h
 | |
| index 5741961..b03dd67 100644
 | |
| --- a/muduo/net/EventLoop.h
 | |
| +++ b/muduo/net/EventLoop.h
 | |
| @@ -156,7 +156,7 @@ class EventLoop : boost::noncopyable
 | |
|    Timestamp pollReturnTime_;
 | |
|    boost::scoped_ptr<Poller> poller_;
 | |
|    boost::scoped_ptr<TimerQueue> timerQueue_;
 | |
| -  int wakeupFd_;
 | |
| +  int wakeupFd_[2];
 | |
|    // unlike in TimerQueue, which is an internal class,
 | |
|    // we don't expose Channel to client.
 | |
|    boost::scoped_ptr<Channel> wakeupChannel_;
 | |
| diff --git a/muduo/net/InetAddress.cc b/muduo/net/InetAddress.cc
 | |
| index 394870a..05bb5de 100644
 | |
| --- a/muduo/net/InetAddress.cc
 | |
| +++ b/muduo/net/InetAddress.cc
 | |
| @@ -19,10 +19,10 @@
 | |
|  #include <boost/static_assert.hpp>
 | |
|  
 | |
|  // INADDR_ANY use (type)value casting.
 | |
| -#pragma GCC diagnostic ignored "-Wold-style-cast"
 | |
| +// #pragma GCC diagnostic ignored "-Wold-style-cast"
 | |
|  static const in_addr_t kInaddrAny = INADDR_ANY;
 | |
|  static const in_addr_t kInaddrLoopback = INADDR_LOOPBACK;
 | |
| -#pragma GCC diagnostic error "-Wold-style-cast"
 | |
| +// #pragma GCC diagnostic error "-Wold-style-cast"
 | |
|  
 | |
|  //     /* Structure describing an Internet socket address.  */
 | |
|  //     struct sockaddr_in {
 | |
| @@ -83,10 +83,15 @@ bool InetAddress::resolve(StringArg hostname, InetAddress* out)
 | |
|    assert(out != NULL);
 | |
|    struct hostent hent;
 | |
|    struct hostent* he = NULL;
 | |
| -  int herrno = 0;
 | |
|    bzero(&hent, sizeof(hent));
 | |
|  
 | |
| +#ifndef __MACH__
 | |
| +  int herrno = 0;
 | |
|    int ret = gethostbyname_r(hostname.c_str(), &hent, t_resolveBuffer, sizeof t_resolveBuffer, &he, &herrno);
 | |
| +#else
 | |
| +  he = gethostbyname(hostname.c_str());
 | |
| +  int ret = 0;
 | |
| +#endif
 | |
|    if (ret == 0 && he != NULL)
 | |
|    {
 | |
|      assert(he->h_addrtype == AF_INET && he->h_length == sizeof(uint32_t));
 | |
| diff --git a/muduo/net/Socket.cc b/muduo/net/Socket.cc
 | |
| index 111d87d..4e0efa7 100644
 | |
| --- a/muduo/net/Socket.cc
 | |
| +++ b/muduo/net/Socket.cc
 | |
| @@ -27,13 +27,18 @@ Socket::~Socket()
 | |
|  
 | |
|  bool Socket::getTcpInfo(struct tcp_info* tcpi) const
 | |
|  {
 | |
| +#ifndef __MACH__
 | |
|    socklen_t len = sizeof(*tcpi);
 | |
|    bzero(tcpi, len);
 | |
|    return ::getsockopt(sockfd_, SOL_TCP, TCP_INFO, tcpi, &len) == 0;
 | |
| +#else
 | |
| +  return false;
 | |
| +#endif
 | |
|  }
 | |
|  
 | |
|  bool Socket::getTcpInfoString(char* buf, int len) const
 | |
|  {
 | |
| +#ifndef __MACH__
 | |
|    struct tcp_info tcpi;
 | |
|    bool ok = getTcpInfo(&tcpi);
 | |
|    if (ok)
 | |
| @@ -56,6 +61,9 @@ bool Socket::getTcpInfoString(char* buf, int len) const
 | |
|               tcpi.tcpi_total_retrans);  // Total retransmits for entire connection
 | |
|    }
 | |
|    return ok;
 | |
| +#else
 | |
| +  return false;
 | |
| +#endif
 | |
|  }
 | |
|  
 | |
|  void Socket::bindAddress(const InetAddress& addr)
 | |
| diff --git a/muduo/net/SocketsOps.cc b/muduo/net/SocketsOps.cc
 | |
| index 188c3cb..1e5f268 100644
 | |
| --- a/muduo/net/SocketsOps.cc
 | |
| +++ b/muduo/net/SocketsOps.cc
 | |
| @@ -17,18 +17,26 @@
 | |
|  #include <stdio.h>  // snprintf
 | |
|  #include <strings.h>  // bzero
 | |
|  #include <sys/socket.h>
 | |
| +#ifdef __MACH__
 | |
| +#include <sys/uio.h>  // readv
 | |
| +#endif
 | |
|  #include <unistd.h>
 | |
|  
 | |
|  using namespace muduo;
 | |
|  using namespace muduo::net;
 | |
|  
 | |
| -namespace
 | |
| +namespace muduo
 | |
|  {
 | |
|  
 | |
|  typedef struct sockaddr SA;
 | |
|  
 | |
|  
 | |
|  #if VALGRIND || defined (NO_ACCEPT4)
 | |
| +namespace net
 | |
| +{
 | |
| +namespace sockets
 | |
| +{
 | |
| +
 | |
|  void setNonBlockAndCloseOnExec(int sockfd)
 | |
|  {
 | |
|    // non-block
 | |
| @@ -45,6 +53,9 @@ void setNonBlockAndCloseOnExec(int sockfd)
 | |
|  
 | |
|    (void)ret;
 | |
|  }
 | |
| +
 | |
| +}
 | |
| +}
 | |
|  #endif
 | |
|  
 | |
|  }
 | |
| @@ -71,7 +82,6 @@ struct sockaddr_in* sockets::sockaddr_in_cast(struct sockaddr* addr)
 | |
|  
 | |
|  int sockets::createNonblockingOrDie()
 | |
|  {
 | |
| -#if VALGRIND
 | |
|    int sockfd = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 | |
|    if (sockfd < 0)
 | |
|    {
 | |
| @@ -79,13 +89,6 @@ int sockets::createNonblockingOrDie()
 | |
|    }
 | |
|  
 | |
|    setNonBlockAndCloseOnExec(sockfd);
 | |
| -#else
 | |
| -  int sockfd = ::socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, IPPROTO_TCP);
 | |
| -  if (sockfd < 0)
 | |
| -  {
 | |
| -    LOG_SYSFATAL << "sockets::createNonblockingOrDie";
 | |
| -  }
 | |
| -#endif
 | |
|    return sockfd;
 | |
|  }
 | |
|  
 | |
| @@ -110,13 +113,8 @@ void sockets::listenOrDie(int sockfd)
 | |
|  int sockets::accept(int sockfd, struct sockaddr_in* addr)
 | |
|  {
 | |
|    socklen_t addrlen = static_cast<socklen_t>(sizeof *addr);
 | |
| -#if VALGRIND || defined (NO_ACCEPT4)
 | |
|    int connfd = ::accept(sockfd, sockaddr_cast(addr), &addrlen);
 | |
|    setNonBlockAndCloseOnExec(connfd);
 | |
| -#else
 | |
| -  int connfd = ::accept4(sockfd, sockaddr_cast(addr),
 | |
| -                         &addrlen, SOCK_NONBLOCK | SOCK_CLOEXEC);
 | |
| -#endif
 | |
|    if (connfd < 0)
 | |
|    {
 | |
|      int savedErrno = errno;
 | |
| diff --git a/muduo/net/SocketsOps.h b/muduo/net/SocketsOps.h
 | |
| index a07b1fe..efc779a 100644
 | |
| --- a/muduo/net/SocketsOps.h
 | |
| +++ b/muduo/net/SocketsOps.h
 | |
| @@ -24,6 +24,9 @@ namespace sockets
 | |
|  /// Creates a non-blocking socket file descriptor,
 | |
|  /// abort if any error.
 | |
|  int createNonblockingOrDie();
 | |
| +#ifdef __MACH__
 | |
| +void setNonBlockAndCloseOnExec(int sockfd);
 | |
| +#endif
 | |
|  
 | |
|  int  connect(int sockfd, const struct sockaddr_in& addr);
 | |
|  void bindOrDie(int sockfd, const struct sockaddr_in& addr);
 | |
| diff --git a/muduo/net/TimerQueue.cc b/muduo/net/TimerQueue.cc
 | |
| index 0f199e5..7f4813a 100644
 | |
| --- a/muduo/net/TimerQueue.cc
 | |
| +++ b/muduo/net/TimerQueue.cc
 | |
| @@ -19,8 +19,6 @@
 | |
|  
 | |
|  #include <boost/bind.hpp>
 | |
|  
 | |
| -#include <sys/timerfd.h>
 | |
| -
 | |
|  namespace muduo
 | |
|  {
 | |
|  namespace net
 | |
| @@ -28,57 +26,15 @@ namespace net
 | |
|  namespace detail
 | |
|  {
 | |
|  
 | |
| -int createTimerfd()
 | |
| -{
 | |
| -  int timerfd = ::timerfd_create(CLOCK_MONOTONIC,
 | |
| -                                 TFD_NONBLOCK | TFD_CLOEXEC);
 | |
| -  if (timerfd < 0)
 | |
| -  {
 | |
| -    LOG_SYSFATAL << "Failed in timerfd_create";
 | |
| -  }
 | |
| -  return timerfd;
 | |
| -}
 | |
| -
 | |
| -struct timespec howMuchTimeFromNow(Timestamp when)
 | |
| +int howMuchTimeFromNow(Timestamp when)
 | |
|  {
 | |
|    int64_t microseconds = when.microSecondsSinceEpoch()
 | |
|                           - Timestamp::now().microSecondsSinceEpoch();
 | |
| -  if (microseconds < 100)
 | |
| -  {
 | |
| -    microseconds = 100;
 | |
| -  }
 | |
| -  struct timespec ts;
 | |
| -  ts.tv_sec = static_cast<time_t>(
 | |
| -      microseconds / Timestamp::kMicroSecondsPerSecond);
 | |
| -  ts.tv_nsec = static_cast<long>(
 | |
| -      (microseconds % Timestamp::kMicroSecondsPerSecond) * 1000);
 | |
| -  return ts;
 | |
| -}
 | |
| -
 | |
| -void readTimerfd(int timerfd, Timestamp now)
 | |
| -{
 | |
| -  uint64_t howmany;
 | |
| -  ssize_t n = ::read(timerfd, &howmany, sizeof howmany);
 | |
| -  LOG_TRACE << "TimerQueue::handleRead() " << howmany << " at " << now.toString();
 | |
| -  if (n != sizeof howmany)
 | |
| -  {
 | |
| -    LOG_ERROR << "TimerQueue::handleRead() reads " << n << " bytes instead of 8";
 | |
| -  }
 | |
| -}
 | |
| -
 | |
| -void resetTimerfd(int timerfd, Timestamp expiration)
 | |
| -{
 | |
| -  // wake up loop by timerfd_settime()
 | |
| -  struct itimerspec newValue;
 | |
| -  struct itimerspec oldValue;
 | |
| -  bzero(&newValue, sizeof newValue);
 | |
| -  bzero(&oldValue, sizeof oldValue);
 | |
| -  newValue.it_value = howMuchTimeFromNow(expiration);
 | |
| -  int ret = ::timerfd_settime(timerfd, 0, &newValue, &oldValue);
 | |
| -  if (ret)
 | |
| +  if (microseconds < 1000)
 | |
|    {
 | |
| -    LOG_SYSERR << "timerfd_settime()";
 | |
| +    microseconds = 1000;
 | |
|    }
 | |
| +  return static_cast<int>(microseconds / 1000);
 | |
|  }
 | |
|  
 | |
|  }
 | |
| @@ -91,22 +47,13 @@ using namespace muduo::net::detail;
 | |
|  
 | |
|  TimerQueue::TimerQueue(EventLoop* loop)
 | |
|    : loop_(loop),
 | |
| -    timerfd_(createTimerfd()),
 | |
| -    timerfdChannel_(loop, timerfd_),
 | |
|      timers_(),
 | |
|      callingExpiredTimers_(false)
 | |
|  {
 | |
| -  timerfdChannel_.setReadCallback(
 | |
| -      boost::bind(&TimerQueue::handleRead, this));
 | |
| -  // we are always reading the timerfd, we disarm it with timerfd_settime.
 | |
| -  timerfdChannel_.enableReading();
 | |
|  }
 | |
|  
 | |
|  TimerQueue::~TimerQueue()
 | |
|  {
 | |
| -  timerfdChannel_.disableAll();
 | |
| -  timerfdChannel_.remove();
 | |
| -  ::close(timerfd_);
 | |
|    // do not remove channel, since we're in EventLoop::dtor();
 | |
|    for (TimerList::iterator it = timers_.begin();
 | |
|        it != timers_.end(); ++it)
 | |
| @@ -146,11 +93,19 @@ void TimerQueue::cancel(TimerId timerId)
 | |
|  void TimerQueue::addTimerInLoop(Timer* timer)
 | |
|  {
 | |
|    loop_->assertInLoopThread();
 | |
| -  bool earliestChanged = insert(timer);
 | |
| +  insert(timer);
 | |
| +}
 | |
|  
 | |
| -  if (earliestChanged)
 | |
| +int TimerQueue::getTimeout() const
 | |
| +{
 | |
| +  loop_->assertInLoopThread();
 | |
| +  if (timers_.empty())
 | |
| +  {
 | |
| +    return 10000;
 | |
| +  }
 | |
| +  else
 | |
|    {
 | |
| -    resetTimerfd(timerfd_, timer->expiration());
 | |
| +    return howMuchTimeFromNow(timers_.begin()->second->expiration());
 | |
|    }
 | |
|  }
 | |
|  
 | |
| @@ -174,11 +129,10 @@ void TimerQueue::cancelInLoop(TimerId timerId)
 | |
|    assert(timers_.size() == activeTimers_.size());
 | |
|  }
 | |
|  
 | |
| -void TimerQueue::handleRead()
 | |
| +void TimerQueue::processTimers()
 | |
|  {
 | |
|    loop_->assertInLoopThread();
 | |
|    Timestamp now(Timestamp::now());
 | |
| -  readTimerfd(timerfd_, now);
 | |
|  
 | |
|    std::vector<Entry> expired = getExpired(now);
 | |
|  
 | |
| @@ -242,11 +196,6 @@ void TimerQueue::reset(const std::vector<Entry>& expired, Timestamp now)
 | |
|    {
 | |
|      nextExpire = timers_.begin()->second->expiration();
 | |
|    }
 | |
| -
 | |
| -  if (nextExpire.valid())
 | |
| -  {
 | |
| -    resetTimerfd(timerfd_, nextExpire);
 | |
| -  }
 | |
|  }
 | |
|  
 | |
|  bool TimerQueue::insert(Timer* timer)
 | |
| diff --git a/muduo/net/TimerQueue.h b/muduo/net/TimerQueue.h
 | |
| index 0cfb02f..d882b71 100644
 | |
| --- a/muduo/net/TimerQueue.h
 | |
| +++ b/muduo/net/TimerQueue.h
 | |
| @@ -56,6 +56,9 @@ class TimerQueue : boost::noncopyable
 | |
|  
 | |
|    void cancel(TimerId timerId);
 | |
|  
 | |
| +  int getTimeout() const;
 | |
| +  void processTimers();
 | |
| +
 | |
|   private:
 | |
|  
 | |
|    // FIXME: use unique_ptr<Timer> instead of raw pointers.
 | |
| @@ -66,8 +69,6 @@ class TimerQueue : boost::noncopyable
 | |
|  
 | |
|    void addTimerInLoop(Timer* timer);
 | |
|    void cancelInLoop(TimerId timerId);
 | |
| -  // called when timerfd alarms
 | |
| -  void handleRead();
 | |
|    // move out all expired timers
 | |
|    std::vector<Entry> getExpired(Timestamp now);
 | |
|    void reset(const std::vector<Entry>& expired, Timestamp now);
 | |
| @@ -75,9 +76,6 @@ class TimerQueue : boost::noncopyable
 | |
|    bool insert(Timer* timer);
 | |
|  
 | |
|    EventLoop* loop_;
 | |
| -  const int timerfd_;
 | |
| -  Channel timerfdChannel_;
 | |
| -  // Timer list sorted by expiration
 | |
|    TimerList timers_;
 | |
|  
 | |
|    // for cancel()
 | |
| diff --git a/muduo/net/poller/DefaultPoller.cc b/muduo/net/poller/DefaultPoller.cc
 | |
| index f42f5a4..a6a3133 100644
 | |
| --- a/muduo/net/poller/DefaultPoller.cc
 | |
| +++ b/muduo/net/poller/DefaultPoller.cc
 | |
| @@ -16,6 +16,9 @@ using namespace muduo::net;
 | |
|  
 | |
|  Poller* Poller::newDefaultPoller(EventLoop* loop)
 | |
|  {
 | |
| +#ifdef __MACH__
 | |
| +  return new PollPoller(loop);
 | |
| +#else
 | |
|    if (::getenv("MUDUO_USE_POLL"))
 | |
|    {
 | |
|      return new PollPoller(loop);
 | |
| @@ -24,4 +27,5 @@ Poller* Poller::newDefaultPoller(EventLoop* loop)
 | |
|    {
 | |
|      return new EPollPoller(loop);
 | |
|    }
 | |
| +#endif
 | |
|  }
 | |
| 
 | |
| diff --git a/examples/protobuf/rpcbalancer/balancer_raw.cc b/examples/protobuf/rpcbalancer/balancer_raw.cc
 | |
| index 9c2e1db..c30b19d 100644
 | |
| --- a/examples/protobuf/rpcbalancer/balancer_raw.cc
 | |
| +++ b/examples/protobuf/rpcbalancer/balancer_raw.cc
 | |
| @@ -12,7 +12,7 @@
 | |
|  #include <boost/bind.hpp>
 | |
|  #include <boost/ptr_container/ptr_vector.hpp>
 | |
| 
 | |
| -#include <endian.h>
 | |
| +#include <machine/endian.h>
 | |
|  #include <stdio.h>
 | |
| 
 | |
|  using namespace muduo;
 |