Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ set(CXX_FLAGS
-D_FILE_OFFSET_BITS=64
-Wall
-Wextra
-Werror
# -Werror # Disabled for macOS compatibility with old Boost
-Wconversion
-Wno-unused-parameter
-Wold-style-cast
Expand All @@ -36,7 +36,7 @@ set(CXX_FLAGS
if(CMAKE_BUILD_BITS EQUAL 32)
list(APPEND CXX_FLAGS "-m32")
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
list(APPEND CXX_FLAGS "-Wno-null-dereference")
list(APPEND CXX_FLAGS "-Wno-sign-conversion")
list(APPEND CXX_FLAGS "-Wno-unused-local-typedef")
Expand Down
6 changes: 5 additions & 1 deletion muduo/base/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ set(base_SRCS
)

add_library(muduo_base ${base_SRCS})
target_link_libraries(muduo_base pthread rt)
if(UNIX AND NOT APPLE)
target_link_libraries(muduo_base pthread rt)
else()
target_link_libraries(muduo_base pthread)
endif()

#add_library(muduo_base_cpp11 ${base_SRCS})
#target_link_libraries(muduo_base_cpp11 pthread rt)
Expand Down
5 changes: 4 additions & 1 deletion muduo/base/FileUtil.cc
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,11 @@ void FileUtil::AppendFile::flush()

size_t FileUtil::AppendFile::write(const char* logline, size_t len)
{
// #undef fwrite_unlocked
#ifdef fwrite_unlocked
return ::fwrite_unlocked(logline, 1, len, fp_);
#else
return ::fwrite(logline, 1, len, fp_);
#endif
}

FileUtil::ReadSmallFile::ReadSmallFile(StringArg filename)
Expand Down
5 changes: 5 additions & 0 deletions muduo/base/Logging.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,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()
Expand Down
18 changes: 16 additions & 2 deletions muduo/base/Mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "muduo/base/CurrentThread.h"
#include "muduo/base/noncopyable.h"
#include <assert.h>
#include <stdio.h>
#include <pthread.h>

// Thread safety annotations {
Expand Down Expand Up @@ -84,18 +85,31 @@
#ifdef CHECK_PTHREAD_RETURN_VALUE

#ifdef NDEBUG
#ifdef __MACH__
#define MCHECK(ret) ({ __typeof__ (ret) errnum = (ret); \
if (__builtin_expect(errnum != 0, 0)) \
assert_perror_fail (errnum, __FILE__, __LINE__, __func__);})
static inline void assert_perror_fail(int errnum, const char* file, unsigned int line, const char* function) {
fprintf(stderr, "Pthread error %d at %s:%u, function %s\n", errnum, file, line, function);
abort();
}
#else
__BEGIN_DECLS
extern void __assert_perror_fail (int errnum,
const char *file,
unsigned int line,
const char *function)
noexcept __attribute__ ((__noreturn__));
__END_DECLS
#endif

#define MCHECK(ret) ({ __typeof__ (ret) errnum = (ret); \
if (__builtin_expect(errnum != 0, 0)) \
__assert_perror_fail (errnum, __FILE__, __LINE__, __func__);})
#endif

#else // NDEBUG
#define MCHECK(ret) ({ __typeof__ (ret) errnum = (ret); \
assert(errnum == 0); (void) errnum;})
#endif

#else // CHECK_PTHREAD_RETURN_VALUE

Expand Down
10 changes: 9 additions & 1 deletion muduo/base/Thread.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,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
{
Expand All @@ -25,7 +27,11 @@ namespace detail

pid_t gettid()
{
#ifndef __MACH__
return static_cast<pid_t>(::syscall(SYS_gettid));
#else
return static_cast<pid_t>(pthread_mach_thread_np(pthread_self()));
#endif
}

void afterFork()
Expand Down Expand Up @@ -75,7 +81,9 @@ struct ThreadData
latch_ = NULL;

muduo::CurrentThread::t_threadName = name_.empty() ? "muduoThread" : name_.c_str();
#ifndef __MACH__
::prctl(PR_SET_NAME, muduo::CurrentThread::t_threadName);
#endif
try
{
func_();
Expand Down
8 changes: 4 additions & 4 deletions muduo/base/TimeZone.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "muduo/base/TimeZone.h"
#include "muduo/base/noncopyable.h"
#include "muduo/base/Date.h"
#include "muduo/net/Endian.h"

#include <algorithm>
#include <memory>
Expand All @@ -14,13 +15,12 @@
#include <vector>

#include <assert.h>
//#define _BSD_SOURCE
#include <endian.h>

#include <stdint.h>
#include <stdio.h>

using namespace muduo;
using namespace muduo::net;

struct TimeZone::Data
{
Expand Down Expand Up @@ -135,7 +135,7 @@ class File : noncopyable
ssize_t nr = ::fread(&x, 1, sizeof(int64_t), fp_);
if (nr != sizeof(int64_t))
throw std::logic_error("bad int64_t data");
return be64toh(x);
return sockets::networkToHost64(x);
}

int32_t readInt32()
Expand All @@ -144,7 +144,7 @@ class File : noncopyable
ssize_t nr = ::fread(&x, 1, sizeof(int32_t), fp_);
if (nr != sizeof(int32_t))
throw std::logic_error("bad int32_t data");
return be32toh(x);
return sockets::networkToHost32(x);
}

uint8_t readUInt8()
Expand Down
11 changes: 10 additions & 1 deletion muduo/net/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ if(NOT HAVE_ACCEPT4)
set_source_files_properties(SocketsOps.cc PROPERTIES COMPILE_FLAGS "-DNO_ACCEPT4")
endif()

# Select poller implementation based on platform
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(poller_implementation poller/EPollPoller.cc)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set(poller_implementation poller/KQueuePoller.cc)
else()
set(poller_implementation poller/PollPoller.cc)
endif()

set(net_SRCS
Acceptor.cc
Buffer.cc
Expand All @@ -16,7 +25,7 @@ set(net_SRCS
InetAddress.cc
Poller.cc
poller/DefaultPoller.cc
poller/EPollPoller.cc
${poller_implementation}
poller/PollPoller.cc
Socket.cc
SocketsOps.cc
Expand Down
4 changes: 4 additions & 0 deletions muduo/net/Channel.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@

#include <poll.h>

#ifndef POLLRDHUP
#define POLLRDHUP 0
#endif

using namespace muduo;
using namespace muduo::net;

Expand Down
21 changes: 20 additions & 1 deletion muduo/net/Endian.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,26 @@
#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
{
Expand Down Expand Up @@ -62,4 +81,4 @@ inline uint16_t networkToHost16(uint16_t net16)
} // namespace net
} // namespace muduo

#endif // MUDUO_NET_ENDIAN_H
#endif // MUDUO_NET_ENDIAN_H
39 changes: 37 additions & 2 deletions muduo/net/EventLoop.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@
#include <algorithm>

#include <signal.h>
#ifndef __MACH__
#include <sys/eventfd.h>
#else
#include <unistd.h>
#include <fcntl.h>
#endif
#include <unistd.h>

using namespace muduo;
Expand All @@ -30,15 +35,25 @@ __thread EventLoop* t_loopInThisThread = 0;

const int kPollTimeMs = 10000;

int createEventfd()
int createEventfd(int wakeupFdPair[2])
{
#ifndef __MACH__
int evtfd = ::eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
if (evtfd < 0)
{
LOG_SYSERR << "Failed in eventfd";
abort();
}
return evtfd;
#else
if (::socketpair(AF_UNIX, SOCK_STREAM, 0, wakeupFdPair) < 0)
{
LOG_SYSFATAL << "Failed in socketpair";
}
::fcntl(wakeupFdPair[0], F_SETFL, O_NONBLOCK | FD_CLOEXEC);
::fcntl(wakeupFdPair[1], F_SETFL, O_NONBLOCK | FD_CLOEXEC);
return wakeupFdPair[0];
#endif
}

#pragma GCC diagnostic ignored "-Wold-style-cast"
Expand Down Expand Up @@ -70,7 +85,8 @@ EventLoop::EventLoop()
threadId_(CurrentThread::tid()),
poller_(Poller::newDefaultPoller(this)),
timerQueue_(new TimerQueue(this)),
wakeupFd_(createEventfd()),
wakeupFdPair_{-1, -1},
wakeupFd_(createEventfd(wakeupFdPair_)),
wakeupChannel_(new Channel(this, wakeupFd_)),
currentActiveChannel_(NULL)
{
Expand All @@ -96,7 +112,12 @@ EventLoop::~EventLoop()
<< " destructs in thread " << CurrentThread::tid();
wakeupChannel_->disableAll();
wakeupChannel_->remove();
#ifndef __MACH__
::close(wakeupFd_);
#else
if (wakeupFdPair_[0] >= 0) ::close(wakeupFdPair_[0]);
if (wakeupFdPair_[1] >= 0) ::close(wakeupFdPair_[1]);
#endif
t_loopInThisThread = NULL;
}

Expand All @@ -111,7 +132,13 @@ void EventLoop::loop()
while (!quit_)
{
activeChannels_.clear();
#ifdef __MACH__
pollReturnTime_ = poller_->poll(timerQueue_->getTimeout(), &activeChannels_);
// Process timers on macOS since we don't have timerfd
timerQueue_->processTimers();
#else
pollReturnTime_ = poller_->poll(kPollTimeMs, &activeChannels_);
#endif
++iteration_;
if (Logger::logLevel() <= Logger::TRACE)
{
Expand Down Expand Up @@ -234,7 +261,11 @@ void EventLoop::abortNotInLoopThread()
void EventLoop::wakeup()
{
uint64_t one = 1;
#ifndef __MACH__
ssize_t n = sockets::write(wakeupFd_, &one, sizeof one);
#else
ssize_t n = sockets::write(wakeupFdPair_[1], &one, sizeof one);
#endif
if (n != sizeof one)
{
LOG_ERROR << "EventLoop::wakeup() writes " << n << " bytes instead of 8";
Expand All @@ -244,7 +275,11 @@ void EventLoop::wakeup()
void EventLoop::handleRead()
{
uint64_t one = 1;
#ifndef __MACH__
ssize_t n = sockets::read(wakeupFd_, &one, sizeof one);
#else
ssize_t n = sockets::read(wakeupFdPair_[0], &one, sizeof one);
#endif
if (n != sizeof one)
{
LOG_ERROR << "EventLoop::handleRead() reads " << n << " bytes instead of 8";
Expand Down
1 change: 1 addition & 0 deletions muduo/net/EventLoop.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ class EventLoop : noncopyable
Timestamp pollReturnTime_;
std::unique_ptr<Poller> poller_;
std::unique_ptr<TimerQueue> timerQueue_;
int wakeupFdPair_[2]; // for socketpair on macOS
int wakeupFd_;
// unlike in TimerQueue, which is an internal class,
// we don't expose Channel to client.
Expand Down
16 changes: 16 additions & 0 deletions muduo/net/InetAddress.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,12 @@ using namespace muduo::net;

static_assert(sizeof(InetAddress) == sizeof(struct sockaddr_in6),
"InetAddress is same size as sockaddr_in6");
#ifndef __MACH__
static_assert(offsetof(sockaddr_in, sin_family) == 0, "sin_family offset 0");
static_assert(offsetof(sockaddr_in6, sin6_family) == 0, "sin6_family offset 0");
static_assert(offsetof(sockaddr_in, sin_port) == 2, "sin_port offset 2");
static_assert(offsetof(sockaddr_in6, sin6_port) == 2, "sin6_port offset 2");
#endif

InetAddress::InetAddress(uint16_t portArg, bool loopbackOnly, bool ipv6)
{
Expand Down Expand Up @@ -118,6 +120,7 @@ static __thread char t_resolveBuffer[64 * 1024];
bool InetAddress::resolve(StringArg hostname, InetAddress* out)
{
assert(out != NULL);
#ifndef __MACH__
struct hostent hent;
struct hostent* he = NULL;
int herrno = 0;
Expand All @@ -138,6 +141,19 @@ bool InetAddress::resolve(StringArg hostname, InetAddress* out)
}
return false;
}
#else
struct hostent* he = gethostbyname(hostname.c_str());
if (he != NULL)
{
assert(he->h_addrtype == AF_INET && he->h_length == sizeof(uint32_t));
out->addr_.sin_addr = *reinterpret_cast<struct in_addr*>(he->h_addr);
return true;
}
else
{
return false;
}
#endif
}

void InetAddress::setScopeId(uint32_t scope_id)
Expand Down
Loading