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;
|