muduo是一个基于事件的轻量级c++网络库, 类似于libevent的事件模式, 使用了一些新的内核系统调用功能, 使用了eventfd作事件通知, 相比libevent的pipe或socketpir, 使用timerfd作作为定时事件, 相比libevent使用epoll的超时, 最小堆做定时事件, c++代码使用boost的一些特性, 如function, bind注册回调, 智能指针, 很少使用多态机制, 代码清晰, 容易理解.
有关muduo的详细介绍请参见作者 陈硕的Blog
因为muduo使用了最新的内核系统调用API, 在centos5上不能使用,(readhat 内核一直在2.6.18), 详细阅读了一下代码, 做一点修改, 能在centos运行, 另外还需安装boost-1.37, 网上有这个boost版本的rpm包, 可下载直接安装. 修改muduo向后兼容, 感觉没有必要, 就当是阅读代码的一种练习吧. 我的修改基于muduo-0.2.4版本, 主要是使用pipe代替eventfd, 使用时间线程代码timerfd, 以下是我的修改diff:
diff -Nur muduo-0.2.4/base/Atomic.h muduo-0.2.4_centos5/base/Atomic.h
--- muduo-0.2.4/base/Atomic.h 2011-06-02 20:37:56.000000000 +0800
+++ muduo-0.2.4_centos5/base/Atomic.h 2011-06-26 19:36:38.079282058 +0800
@@ -87,6 +87,8 @@
typedef detail::AtomicIntegerT<int32_t> AtomicInt32;
typedef detail::AtomicIntegerT<int64_t> AtomicInt64;
+typedef detail::AtomicIntegerT<uint32_t> AtomicUint32;
+typedef detail::AtomicIntegerT<uint64_t> AtomicUint64;
}
#endif // MUDUO_BASE_ATOMIC_H
diff -Nur muduo-0.2.4/base/CMakeLists.txt muduo-0.2.4_centos5/base/CMakeLists.txt
--- muduo-0.2.4/base/CMakeLists.txt 2011-06-02 20:37:56.000000000 +0800
+++ muduo-0.2.4_centos5/base/CMakeLists.txt 2011-06-26 19:36:38.079282058 +0800
@@ -1,3 +1,4 @@
+# Time-stamp: <2011-06-08 14:25:52 (zouzhy)>
set(base_SRCS
CountDownLatch.cc
Date.cc
@@ -16,4 +17,3 @@
file(GLOB HEADERS "*.h")
install(FILES ${HEADERS} DESTINATION include/muduo/base)
-add_subdirectory(tests)
diff -Nur muduo-0.2.4/base/Condition.h muduo-0.2.4_centos5/base/Condition.h
--- muduo-0.2.4/base/Condition.h 2011-06-02 20:37:56.000000000 +0800
+++ muduo-0.2.4_centos5/base/Condition.h 2011-06-26 19:36:38.079282058 +0800
@@ -2,16 +2,17 @@
// that can be found in the License file.
//
// Author: Shuo Chen (chenshuo at chenshuo dot com)
+// Modify: Add cond timewait
#ifndef MUDUO_BASE_CONDITION_H
#define MUDUO_BASE_CONDITION_H
#include <muduo/base/Mutex.h>
+#include <muduo/base/Timestamp.h>
#include <boost/noncopyable.hpp>
#include <pthread.h>
-
namespace muduo
{
@@ -33,6 +34,14 @@
pthread_cond_wait(&pcond_, mutex_.getPthreadMutex());
}
+ // rc == ETIMEOUT return false, other error ignore
+ bool timewait(Timestamp const & timeout)
+ {
+ struct timespec ts = timeout.timespceSinceEpoch();
+ int rc = pthread_cond_timedwait(&pcond_, mutex_.getPthreadMutex(), &ts);
+ return (rc == 0 ? true : false);
+ }
+
void notify()
{
pthread_cond_signal(&pcond_);
diff -Nur muduo-0.2.4/base/Timestamp.cc muduo-0.2.4_centos5/base/Timestamp.cc
--- muduo-0.2.4/base/Timestamp.cc 2011-06-02 20:37:56.000000000 +0800
+++ muduo-0.2.4_centos5/base/Timestamp.cc 2011-07-06 09:53:34.352372115 +0800
@@ -1,7 +1,15 @@
+// Use of this source code is governed by a BSD-style license
+// that can be found in the License file.
+//
+// Author: Shuo Chen (chenshuo at chenshuo dot com)
+
+// Modify: Add timespec convert function
+
#include <muduo/base/Timestamp.h>
#include <sys/time.h>
#include <stdio.h>
+
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#undef __STDC_FORMAT_MACROS
@@ -49,6 +57,15 @@
return Timestamp(seconds * kMicroSecondsPerSecond + tv.tv_usec);
}
+struct timespec Timestamp::timespceSinceEpoch() const {
+ struct timespec ts;
+ ts.tv_sec = static_cast<time_t>(
+ microSecondsSinceEpoch_ / Timestamp::kMicroSecondsPerSecond);
+ ts.tv_nsec = static_cast<long>(
+ (microSecondsSinceEpoch_ % Timestamp::kMicroSecondsPerSecond) * 1000);
+ return ts;
+}
+
Timestamp Timestamp::invalid()
{
return Timestamp();
diff -Nur muduo-0.2.4/base/Timestamp.h muduo-0.2.4_centos5/base/Timestamp.h
--- muduo-0.2.4/base/Timestamp.h 2011-06-02 20:37:56.000000000 +0800
+++ muduo-0.2.4_centos5/base/Timestamp.h 2011-06-26 19:36:38.083281589 +0800
@@ -1,3 +1,10 @@
+// Use of this source code is governed by a BSD-style license
+// that can be found in the License file.
+//
+// Author: Shuo Chen (chenshuo at chenshuo dot com)
+
+// Modify: Add timespec convert function
+
#ifndef MUDUO_BASE_TIMESTAMP_H
#define MUDUO_BASE_TIMESTAMP_H
@@ -48,6 +55,8 @@
// for internal usage.
int64_t microSecondsSinceEpoch() const { return microSecondsSinceEpoch_; }
+ struct timespec timespceSinceEpoch() const ;
+
///
/// Get time of now.
///
diff -Nur muduo-0.2.4/net/CMakeLists.txt muduo-0.2.4_centos5/net/CMakeLists.txt
--- muduo-0.2.4/net/CMakeLists.txt 2011-06-02 20:37:56.000000000 +0800
+++ muduo-0.2.4_centos5/net/CMakeLists.txt 2011-06-26 19:36:38.083281589 +0800
@@ -1,3 +1,4 @@
+# Time-stamp: <2011-06-08 14:26:36 (zouzhy)>
set(net_SRCS
Acceptor.cc
Buffer.cc
@@ -17,6 +18,7 @@
TcpConnection.cc
TcpServer.cc
Timer.cc
+ TimerT