├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── README.md ├── core ├── CMakeLists.txt ├── UdpAcceptor.cpp ├── UdpAcceptor.h ├── UdpCallbacks.h ├── UdpClient.cpp ├── UdpClient.h ├── UdpConnection.cpp ├── UdpConnection.h ├── UdpConnector.cpp ├── UdpConnector.h ├── UdpServer.cpp ├── UdpServer.h ├── UdpSocketsOps.cpp ├── UdpSocketsOps.h └── any.h ├── test ├── CMakeLists.txt ├── tcp_chat_client.cpp ├── tcp_chat_server.cpp ├── tcp_codec.h ├── udp_chat_client.cpp ├── udp_chat_server.cpp └── udp_codec.h ├── third ├── muduo-win │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ └── src │ │ ├── alds │ │ └── min_heap.h │ │ ├── base │ │ ├── Mutex.h │ │ ├── async_logging.cc │ │ ├── async_logging.h │ │ ├── blocking_queue.h │ │ ├── bounded_blocking_queue.h │ │ ├── config_file_reader.cc │ │ ├── config_file_reader.h │ │ ├── copyable.h │ │ ├── count_down_latch.cc │ │ ├── count_down_latch.h │ │ ├── file_util.cc │ │ ├── file_util.h │ │ ├── log_file.cc │ │ ├── log_file.h │ │ ├── log_stream.cc │ │ ├── log_stream.h │ │ ├── logging.cc │ │ ├── logging.h │ │ ├── security │ │ │ ├── aes.h │ │ │ ├── aes_core.cpp │ │ │ ├── aes_locl.h │ │ │ ├── base64.cpp │ │ │ ├── base64.h │ │ │ ├── md5.cpp │ │ │ └── md5.h │ │ ├── stringpiece.h │ │ ├── thread.h │ │ ├── thread_pool.cc │ │ ├── thread_pool.h │ │ ├── timestamp.cc │ │ ├── timestamp.h │ │ ├── types.h │ │ ├── uncopyable.h │ │ ├── win_time.cc │ │ └── win_time.h │ │ ├── net │ │ ├── Acceptor.cc │ │ ├── Acceptor.h │ │ ├── Buffer.cc │ │ ├── Buffer.h │ │ ├── Callbacks.h │ │ ├── Channel.cc │ │ ├── Channel.h │ │ ├── Connector.cc │ │ ├── Connector.h │ │ ├── Endian.h │ │ ├── EventLoop.cc │ │ ├── EventLoop.h │ │ ├── EventLoopThread.cc │ │ ├── EventLoopThread.h │ │ ├── EventLoopThreadPool.cc │ │ ├── EventLoopThreadPool.h │ │ ├── InetAddress.cc │ │ ├── InetAddress.h │ │ ├── Poller.cc │ │ ├── Poller.h │ │ ├── Poller │ │ │ ├── DefaultPoller.cc │ │ │ ├── SelectPoller.cc │ │ │ └── SelectPoller.h │ │ ├── Socket.cc │ │ ├── Socket.h │ │ ├── SocketsOps.cc │ │ ├── SocketsOps.h │ │ ├── TcpClient.cc │ │ ├── TcpClient.h │ │ ├── TcpConnection.cc │ │ ├── TcpConnection.h │ │ ├── TcpServer.cc │ │ ├── TcpServer.h │ │ ├── TimeMinHeap.h │ │ ├── Timer.cc │ │ ├── Timer.h │ │ ├── TimerId.h │ │ ├── TimerQueue.cc │ │ ├── TimerQueue.h │ │ └── poll.h │ │ └── test │ │ ├── ThreadPool_test.cc │ │ ├── acceptor_test.cc │ │ ├── async_logging_test.cc │ │ ├── config_file_read_test.cc │ │ ├── connector_test.cc │ │ ├── echoclient_test.cc │ │ ├── echoserver_test.cc │ │ ├── eventloop_test.cc │ │ ├── eventloopthread_test.cc │ │ ├── eventloopthreadpool_test.cc │ │ ├── log_file_test.cc │ │ ├── log_stream_bench.cc │ │ ├── logging_test.cc │ │ ├── min_heap_test.cc │ │ ├── security_test.cc │ │ ├── socketsOps_test.cc │ │ ├── tcpclient_test.cc │ │ ├── time_min_heap_test.cc │ │ └── timerqueue_test.cc └── muduo │ ├── CMakeLists.txt │ ├── base │ ├── Atomic.h │ ├── Condition.cc │ ├── Condition.h │ ├── CountDownLatch.cc │ ├── CountDownLatch.h │ ├── CurrentThread.h │ ├── Date.cc │ ├── Date.h │ ├── Exception.cc │ ├── Exception.h │ ├── LogStream.cc │ ├── LogStream.h │ ├── Logging.cc │ ├── Logging.h │ ├── Mutex.h │ ├── StringPiece.h │ ├── Thread.cc │ ├── Thread.h │ ├── ThreadLocal.h │ ├── ThreadLocalSingleton.h │ ├── ThreadPool.cc │ ├── ThreadPool.h │ ├── TimeZone.cc │ ├── TimeZone.h │ ├── Timestamp.cc │ ├── Timestamp.h │ ├── Types.h │ ├── WeakCallback.h │ ├── copyable.h │ └── noncopyable.h │ └── net │ ├── Acceptor.cc │ ├── Acceptor.h │ ├── Buffer.cc │ ├── Buffer.h │ ├── Callbacks.h │ ├── Channel.cc │ ├── Channel.h │ ├── Connector.cc │ ├── Connector.h │ ├── Endian.h │ ├── EventLoop.cc │ ├── EventLoop.h │ ├── EventLoopThread.cc │ ├── EventLoopThread.h │ ├── EventLoopThreadPool.cc │ ├── EventLoopThreadPool.h │ ├── InetAddress.cc │ ├── InetAddress.h │ ├── Poller.cc │ ├── Poller.h │ ├── Socket.cc │ ├── Socket.h │ ├── SocketsOps.cc │ ├── SocketsOps.h │ ├── TcpClient.cc │ ├── TcpClient.h │ ├── TcpConnection.cc │ ├── TcpConnection.h │ ├── TcpServer.cc │ ├── TcpServer.h │ ├── Timer.cc │ ├── Timer.h │ ├── TimerId.h │ ├── TimerQueue.cc │ ├── TimerQueue.h │ └── poller │ ├── DefaultPoller.cc │ ├── EPollPoller.cc │ ├── EPollPoller.h │ ├── PollPoller.cc │ └── PollPoller.h └── vs2015 └── realtinet ├── .gitignore ├── realtinet.sln └── realtinet ├── realtinet.vcxproj └── realtinet.vcxproj.filters /.gitignore: -------------------------------------------------------------------------------- 1 | .history/ 2 | 3 | # Visual Studio 2015 user specific files 4 | .vs/ 5 | 6 | # VisualStudioCode 7 | .vscode 8 | 9 | build/ 10 | 11 | bin_rs 12 | 13 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "third/kcpp"] 2 | path = third/kcpp 3 | url = git@github.com:no5ix/kcpp.git 4 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | cmake_minimum_required (VERSION 2.8) 3 | 4 | # CMake disable -std=c++11 flag for C files 5 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y") 6 | 7 | project (realtinet) 8 | 9 | set_property(GLOBAL PROPERTY USE_FOLDERS On) 10 | 11 | set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) 12 | set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) 13 | 14 | 15 | if(UNIX) 16 | 17 | if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) 18 | # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic") 19 | # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w") # Inhibit all warning messages. 20 | set(CXX_FLAGS 21 | -g 22 | # -DVALGRIND 23 | # -DMUDUO_STD_STRING 24 | -DCHECK_PTHREAD_RETURN_VALUE 25 | -D_FILE_OFFSET_BITS=64 26 | -Wall 27 | -Wextra 28 | -Werror 29 | # -Wconversion 30 | -Wno-unused-parameter 31 | # -Wold-style-cast 32 | -Wno-multichar 33 | -Wno-unused-function 34 | -Wno-reorder 35 | -Woverloaded-virtual 36 | -Wpointer-arith 37 | # -Wshadow 38 | -Wwrite-strings 39 | -march=native 40 | # -MMD 41 | -std=c++0x 42 | -rdynamic 43 | ) 44 | string(REPLACE ";" " " CMAKE_CXX_FLAGS "${CXX_FLAGS}") 45 | endif() 46 | 47 | # For gdb 48 | set(CMAKE_BUILD_TYPE "Debug") 49 | set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb") 50 | set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall") 51 | 52 | 53 | include_directories(${PROJECT_SOURCE_DIR}) 54 | include_directories(${PROJECT_SOURCE_DIR}/core) 55 | include_directories(${PROJECT_SOURCE_DIR}/third) 56 | include_directories(${PROJECT_SOURCE_DIR}/third/muduo) 57 | 58 | add_subdirectory(core) 59 | add_subdirectory(test) 60 | add_subdirectory(third/muduo) 61 | add_subdirectory(third/kcpp) 62 | 63 | else() 64 | message(SEND_ERROR "You are on an unsupported platform! (Not Unix)") 65 | ENDIF() -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [muduo](https://github.com/chenshuo/muduo) + [kcp](https://github.com/skywind3000/kcp), a fast and two-channel (reliable & unreliable) udp lib. 4 | 5 | 一个快速的双通道(可靠与非可靠)udp网络库, 基于 muduo + kcp . 6 | 7 | # About This 8 | 9 | 10 | - realtinet = [kcp](https://github.com/skywind3000/kcp) + ([kcpp](https://github.com/no5ix/kcpp), a kcp session implementation) + [muduo](https://github.com/chenshuo/muduo) + (UDP support for muduo) 11 | - used in [realtime-server](https://github.com/no5ix/realtime-server) (A open source realtime dedicated game server for FPS / MOBA ), [Video Preview 视频演示](https://github.com/no5ix/realtime-server/blob/master/img/UE4DemoScreenshot.gif) 12 | 13 | 14 | # QQ群 15 | 16 | 496687140 -------------------------------------------------------------------------------- /core/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set (PROJ_NAME realtinet) 2 | set (MUDUO_LIB_NAME muduo) 3 | set (KCPSESS_LIB_NAME kcpp) 4 | 5 | IF(UNIX) 6 | 7 | set(realtinet_SRCS 8 | UdpAcceptor.cpp 9 | UdpClient.cpp 10 | UdpConnection.cpp 11 | UdpConnector.cpp 12 | UdpServer.cpp 13 | UdpSocketsOps.cpp 14 | ) 15 | 16 | add_library(${PROJ_NAME} ${realtinet_SRCS}) 17 | target_link_libraries(${PROJ_NAME} ${MUDUO_LIB_NAME} ${KCPSESS_LIB_NAME}) 18 | 19 | # elseif(WIN32) # Check if we are on Windows 20 | 21 | # create_win_proj(${PROJ_NAME}) 22 | 23 | else() 24 | message(SEND_ERROR "You are on an unsupported platform! (Not Win32 or Unix)") 25 | ENDIF() -------------------------------------------------------------------------------- /core/UdpAcceptor.cpp: -------------------------------------------------------------------------------- 1 | #include "UdpAcceptor.h" 2 | #include "UdpSocketsOps.h" 3 | #include "UdpConnector.h" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | //#include 13 | //#include 14 | 15 | #ifndef _WIN32 16 | #include 17 | #endif 18 | 19 | using namespace muduo; 20 | using namespace muduo::net; 21 | 22 | 23 | UdpAcceptor::UdpAcceptor(EventLoop* loop, const InetAddress& listenAddr, bool reuseport) 24 | : loop_(loop), 25 | acceptSocket_(sockets::createUdpNonblockingOrDie(listenAddr.family())), 26 | acceptChannel_(loop, acceptSocket_.fd()), 27 | listenning_(false), 28 | listenPort_(listenAddr.toPort()), 29 | listenAddr_(listenAddr) 30 | { 31 | acceptSocket_.setReuseAddr(true); 32 | acceptSocket_.setReusePort(reuseport); 33 | acceptSocket_.bindAddress(listenAddr); 34 | 35 | acceptChannel_.setReadCallback( 36 | std::bind(&UdpAcceptor::handleRead, this)); 37 | } 38 | 39 | UdpAcceptor::~UdpAcceptor() 40 | { 41 | acceptChannel_.disableAll(); 42 | acceptChannel_.remove(); 43 | 44 | peerAddrToUdpConnectors_.empty(); 45 | } 46 | 47 | void UdpAcceptor::listen() 48 | { 49 | loop_->assertInLoopThread(); 50 | listenning_ = true; 51 | 52 | //#ifdef _WIN32 53 | // acceptSocket_.listen(); 54 | //#endif 55 | 56 | acceptChannel_.enableReading(); 57 | } 58 | 59 | void UdpAcceptor::handleRead() 60 | { 61 | loop_->assertInLoopThread(); 62 | InetAddress peerAddr; 63 | 64 | struct sockaddr_in6 addr; 65 | //struct sockaddr_in addr; 66 | //bzero( &addr, sizeof addr ); 67 | memset(&addr, 0, sizeof(addr)); 68 | int readByteCount = sockets::recvfrom(acceptSocket_.fd(), &addr, recvfromBuf_, krecvfromBufSize); 69 | 70 | if (readByteCount >= 0) 71 | { 72 | peerAddr.setSockAddrInet6(addr); 73 | //peerAddr.setSockAddrIn(addr); 74 | 75 | if (peerAddrToUdpConnectors_.find(peerAddr) 76 | == peerAddrToUdpConnectors_.end()) // check whether is connecting 77 | { 78 | UdpConnectorPtr newUdpConnector(new UdpConnector(loop_, peerAddr, listenAddr_)); 79 | peerAddrToUdpConnectors_[peerAddr] = newUdpConnector; 80 | 81 | newUdpConnector->setNewConnectionCallback( 82 | std::bind(&UdpAcceptor::newConnection, this, _1, peerAddr)); 83 | newUdpConnector->start(); 84 | } 85 | } 86 | else 87 | { 88 | LOG_SYSERR << "in UdpAcceptor::handleRead"; 89 | } 90 | } 91 | 92 | void UdpAcceptor::newConnection(Socket* connectedSocket, 93 | const InetAddress& peerAddr) 94 | { 95 | loop_->assertInLoopThread(); 96 | if (newConnectionCallback_) 97 | { 98 | newConnectionCallback_(connectedSocket, peerAddr); 99 | } 100 | else 101 | { 102 | //sockets::close( connfd ); 103 | } 104 | } 105 | 106 | void UdpAcceptor::RemoveConnector(const InetAddress& peerAddr) 107 | { 108 | loop_->assertInLoopThread(); 109 | assert(peerAddrToUdpConnectors_[peerAddr]); 110 | (peerAddrToUdpConnectors_[peerAddr])->stop(); 111 | loop_->runAfter(1, std::bind(&UdpAcceptor::EraseConnector, this, peerAddr)); 112 | } 113 | 114 | void UdpAcceptor::EraseConnector(const InetAddress& peerAddr) 115 | { 116 | loop_->assertInLoopThread(); 117 | peerAddrToUdpConnectors_.erase(peerAddr); 118 | } -------------------------------------------------------------------------------- /core/UdpAcceptor.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef UDP_MUDUO_NET_ACCEPTOR_H 3 | #define UDP_MUDUO_NET_ACCEPTOR_H 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | namespace muduo 14 | { 15 | namespace net 16 | { 17 | 18 | class EventLoop; 19 | class InetAddress; 20 | 21 | class UdpConnector; 22 | typedef std::shared_ptr UdpConnectorPtr; 23 | 24 | class UdpAcceptor : noncopyable 25 | { 26 | public: 27 | typedef std::function NewConnectionCallback; 29 | 30 | UdpAcceptor( EventLoop* loop, const InetAddress& listenAddr, bool reuseport ); 31 | ~UdpAcceptor(); 32 | 33 | void setNewConnectionCallback( const NewConnectionCallback& cb ) 34 | { newConnectionCallback_ = cb; } 35 | 36 | bool listenning() const { return listenning_; } 37 | void listen(); 38 | 39 | uint16_t GetListenPort() const { return listenPort_; } 40 | EventLoop* getLoop() const { return loop_; } 41 | void RemoveConnector( const InetAddress& peerAddr ); 42 | void EraseConnector( const InetAddress& peerAddr ); 43 | 44 | private: 45 | void handleRead(); 46 | void newConnection( Socket* connectedSocket, 47 | const InetAddress& peerAddr ); 48 | 49 | EventLoop* loop_; 50 | Socket acceptSocket_; 51 | Channel acceptChannel_; 52 | NewConnectionCallback newConnectionCallback_; 53 | bool listenning_; 54 | uint16_t listenPort_; 55 | InetAddress listenAddr_; 56 | 57 | typedef std::map InetAddressToUdpConnectorMap; 58 | InetAddressToUdpConnectorMap peerAddrToUdpConnectors_; 59 | 60 | static const size_t krecvfromBufSize = 1500; 61 | char recvfromBuf_[krecvfromBufSize]; 62 | }; 63 | 64 | } 65 | } 66 | 67 | #endif // MUDUO_NET_ACCEPTOR_H 68 | -------------------------------------------------------------------------------- /core/UdpCallbacks.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010, Shuo Chen. All rights reserved. 2 | // http://code.google.com/p/muduo/ 3 | // 4 | // Use of this source code is governed by a BSD-style license 5 | // that can be found in the License file. 6 | 7 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 8 | // 9 | // This is a public header file, it must only include public header files. 10 | 11 | #ifndef UDP_MUDUO_NET_CALLBACKS_H 12 | #define UDP_MUDUO_NET_CALLBACKS_H 13 | 14 | #include 15 | 16 | #include 17 | #include 18 | 19 | namespace muduo 20 | { 21 | namespace net 22 | { 23 | 24 | // All client visible callbacks go here. 25 | 26 | class Buffer; 27 | class UdpConnection; 28 | typedef std::shared_ptr UdpConnectionPtr; 29 | typedef std::function UdpTimerCallback; 30 | typedef std::function UdpConnectionCallback; 31 | typedef std::function UdpCloseCallback; 32 | typedef std::function UdpWriteCompleteCallback; 33 | typedef std::function UdpHighWaterMarkCallback; 34 | 35 | //// the data has been read to (buf, len) 36 | //typedef std::function UdpMessageCallback; 40 | 41 | //void UdpDefaultConnectionCallback(const UdpConnectionPtr& conn); 42 | //void UdpDefaultMessageCallback(const UdpConnectionPtr& conn, 43 | // char* buf, 44 | // size_t bufBytes, 45 | // Timestamp recvTime); 46 | 47 | // the data has been read to (buf, len) 48 | typedef std::function UdpMessageCallback; 51 | 52 | void UdpDefaultConnectionCallback(const UdpConnectionPtr& conn); 53 | void UdpDefaultMessageCallback(const UdpConnectionPtr& conn, 54 | Buffer* buffer, 55 | Timestamp recvTime); 56 | } 57 | } 58 | 59 | #endif // MUDUO_NET_CALLBACKS_H 60 | -------------------------------------------------------------------------------- /core/UdpClient.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef UDP_MUDUO_NET_CLIENT_H 3 | #define UDP_MUDUO_NET_CLIENT_H 4 | 5 | #include 6 | #include "UdpConnection.h" 7 | 8 | namespace muduo 9 | { 10 | namespace net 11 | { 12 | class UdpConnector; 13 | typedef std::shared_ptr UdpConnectorPtr; 14 | 15 | class UdpClient : noncopyable 16 | { 17 | public: 18 | // UdpClient(EventLoop* loop); 19 | // UdpClient(EventLoop* loop, const string& host, uint16_t port); 20 | UdpClient( EventLoop* loop, 21 | const InetAddress& serverAddr, 22 | const string& nameArg ); 23 | ~UdpClient(); // force out-line dtor, for std::unique_ptr members. 24 | 25 | void connect(); 26 | void disconnect(); 27 | void stop(); 28 | 29 | UdpConnectionPtr connection() const 30 | { 31 | MutexLockGuard lock( mutex_ ); 32 | return connection_; 33 | } 34 | 35 | EventLoop* getLoop() const { return loop_; } 36 | bool retry() const { return retry_; } 37 | void enableRetry() { retry_ = true; } 38 | 39 | const string& name() const 40 | { return name_; } 41 | 42 | /// Set connection callback. 43 | /// Not thread safe. 44 | void setConnectionCallback( UdpConnectionCallback cb ) 45 | { connectionCallback_ = std::move( cb ); } 46 | 47 | /// Set message callback. 48 | /// Not thread safe. 49 | void setMessageCallback( UdpMessageCallback cb ) 50 | { messageCallback_ = std::move( cb ); } 51 | 52 | /// Set write complete callback. 53 | /// Not thread safe. 54 | void setWriteCompleteCallback( UdpWriteCompleteCallback cb ) 55 | { writeCompleteCallback_ = std::move( cb ); } 56 | 57 | private: 58 | /// Not thread safe, but in loop 59 | void newConnection( Socket* connectedSocket ); 60 | /// Not thread safe, but in loop 61 | void removeConnection( const UdpConnectionPtr& conn ); 62 | 63 | EventLoop* loop_; 64 | UdpConnectorPtr connector_; // avoid revealing UdpConnector 65 | const string name_; 66 | UdpConnectionCallback connectionCallback_; 67 | UdpMessageCallback messageCallback_; 68 | UdpWriteCompleteCallback writeCompleteCallback_; 69 | bool retry_; // atomic 70 | bool connect_; // atomic 71 | // always in loop thread 72 | int nextConnId_; 73 | mutable MutexLock mutex_; 74 | UdpConnectionPtr connection_; // @GuardedBy mutex_ 75 | }; 76 | 77 | } 78 | } 79 | 80 | #endif // UDP_MUDUO_NET_CLIENT_H 81 | -------------------------------------------------------------------------------- /core/UdpConnector.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010, Shuo Chen. All rights reserved. 2 | // http://code.google.com/p/muduo/ 3 | // 4 | // Use of this source code is governed by a BSD-style license 5 | // that can be found in the License file. 6 | 7 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 8 | // 9 | // This is an internal header file, you should not include this. 10 | 11 | #ifndef UDP_MUDUO_NET_CONNECTOR_H 12 | #define UDP_MUDUO_NET_CONNECTOR_H 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | 20 | namespace muduo 21 | { 22 | namespace net 23 | { 24 | class Channel; 25 | class EventLoop; 26 | 27 | class UdpConnector : noncopyable, 28 | public std::enable_shared_from_this 29 | { 30 | public: 31 | typedef std::function NewConnectionCallback; 32 | 33 | //UdpConnector( EventLoop* loop, const InetAddress& serverAddr, const uint16_t localPort ); 34 | UdpConnector( EventLoop* loop, const InetAddress& serverAddr, const InetAddress& localAddr ); 35 | ~UdpConnector(); 36 | 37 | void setNewConnectionCallback( const NewConnectionCallback& cb ) 38 | { newConnectionCallback_ = cb; } 39 | 40 | void start(); // can be called in any thread 41 | void restart(); // must be called in loop thread 42 | void stop(); // can be called in any thread 43 | 44 | const InetAddress& serverAddress() const { return peerAddr_; } 45 | 46 | /////////// new : for UDP 47 | //const Socket& GetConnectSocket() const { return connectSocket_; } 48 | 49 | private: 50 | enum States { kDisconnected, kConnecting, kConnected }; 51 | static const int kMaxRetryDelayMs = 30 * 1000; 52 | static const int kInitRetryDelayMs = 500; 53 | 54 | void setState( States s ) { state_ = s; } 55 | void startInLoop(); 56 | void stopInLoop(); 57 | void connect(); 58 | void connecting( int sockfd ); 59 | void handleWrite(); 60 | void handleError(); 61 | void retry( int sockfd ); 62 | int removeAndResetChannel(); 63 | void resetChannel(); 64 | 65 | /////////// new : for UDP 66 | void connected( Socket* connectedSocket ); 67 | //Socket connectSocket_; 68 | 69 | 70 | EventLoop* loop_; 71 | InetAddress peerAddr_; 72 | uint16_t localPort_; 73 | InetAddress localAddr_; 74 | bool connect_; // atomic 75 | States state_; // FIXME: use atomic variable 76 | std::unique_ptr channel_; 77 | NewConnectionCallback newConnectionCallback_; 78 | int retryDelayMs_; 79 | 80 | }; 81 | 82 | } 83 | } 84 | 85 | #endif // MUDUO_NET_CONNECTOR_H 86 | -------------------------------------------------------------------------------- /core/UdpSocketsOps.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "UdpSocketsOps.h" 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include // snprintf 12 | 13 | #ifndef _WIN32 14 | 15 | #include // bzero 16 | #include 17 | #include // readv 18 | #include 19 | 20 | #else 21 | 22 | #include 23 | 24 | #pragma comment( lib, "ws2_32.lib" ) // for select 25 | #pragma comment(lib,"ws2_32") 26 | #include 27 | 28 | #endif 29 | 30 | 31 | #ifdef _MSC_VER 32 | #define snprintf sprintf_s 33 | #endif 34 | 35 | using namespace muduo; 36 | using namespace muduo::net; 37 | 38 | #ifndef _WIN32 39 | 40 | namespace 41 | { 42 | 43 | typedef struct sockaddr SA; 44 | 45 | 46 | 47 | #if VALGRIND || defined (NO_ACCEPT4) 48 | void setNonBlockAndCloseOnExec(int sockfd) 49 | { 50 | // non-block 51 | int flags = ::fcntl(sockfd, F_GETFL, 0); 52 | flags |= O_NONBLOCK; 53 | int ret = ::fcntl(sockfd, F_SETFL, flags); 54 | // FIXME check 55 | 56 | // close-on-exec 57 | flags = ::fcntl(sockfd, F_GETFD, 0); 58 | flags |= FD_CLOEXEC; 59 | ret = ::fcntl(sockfd, F_SETFD, flags); 60 | // FIXME check 61 | 62 | (void)ret; 63 | } 64 | #endif 65 | 66 | } 67 | 68 | int sockets::createUdpNonblockingOrDie(sa_family_t family) 69 | { 70 | #if VALGRIND 71 | int sockfd = ::socket(family, SOCK_DGRAM, IPPROTO_UDP); 72 | 73 | if (sockfd < 0) 74 | { 75 | LOG_SYSFATAL << "sockets::createUdpNonblockingOrDie"; 76 | } 77 | 78 | setNonBlockAndCloseOnExec(sockfd); 79 | #else 80 | int sockfd = ::socket(family, SOCK_DGRAM | SOCK_NONBLOCK | SOCK_CLOEXEC, IPPROTO_UDP); 81 | if (sockfd < 0) 82 | { 83 | LOG_SYSFATAL << "sockets::createUdpNonblockingOrDie"; 84 | } 85 | #endif 86 | return sockfd; 87 | } 88 | 89 | #else 90 | 91 | void setNonBlock(int sockfd) 92 | { 93 | #ifdef _MSC_VER 94 | u_long nonblock = 1; 95 | int ret = ioctlsocket(sockfd, FIONBIO, &nonblock); 96 | #else 97 | int ret = fcntl(fd, F_SETFL, O_NONBLOCK | fcntl(fd, F_GETFL)); 98 | #endif 99 | if (ret == SOCKET_ERROR) 100 | { 101 | LOG_ERROR << "set no block error"; 102 | } 103 | } 104 | 105 | int sockets::createUdpNonblockingOrDie(int family) 106 | { 107 | int sockfd = socket(family, SOCK_DGRAM, 0); 108 | int saveErrno = GetLastError(); 109 | if (sockfd < 0) 110 | { 111 | errno = saveErrno; 112 | LOG_SYSFATAL << "sockets::createUdpNonblockingOrDie"; 113 | } 114 | setNonBlock(sockfd); 115 | return sockfd; 116 | } 117 | 118 | #endif 119 | 120 | ////////// 121 | // for udp socket 122 | ///////// 123 | int sockets::recvfrom(int sockfd, struct sockaddr_in6* addr, char *packetMem, int packetSize) 124 | { 125 | //const uint16_t MAX_PACKET_BYTE_LENGTH = 1500; 126 | 127 | //char packetMem[MAX_PACKET_BYTE_LENGTH]; 128 | //int packetSize = sizeof(packetMem); 129 | socklen_t addrlen = static_cast(sizeof *addr); 130 | 131 | int readByteCount = static_cast(::recvfrom(sockfd, 132 | packetMem, 133 | packetSize, 134 | 0, 135 | sockaddr_cast(addr), 136 | &addrlen)); 137 | 138 | 139 | if (readByteCount < 0) 140 | { 141 | int savedErrno = errno; 142 | LOG_SYSERR << "Socket::recvfrom"; 143 | switch (savedErrno) 144 | { 145 | case EAGAIN: 146 | // expected errors 147 | errno = savedErrno; 148 | break; 149 | default: 150 | LOG_FATAL << "unknown error of ::recvfrom " << savedErrno; 151 | break; 152 | } 153 | } 154 | //recvfromBuf->append(packetMem, readByteCount); 155 | return readByteCount; 156 | } 157 | -------------------------------------------------------------------------------- /core/UdpSocketsOps.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef UDP_MUDUO_NET_SOCKETSOPS_H 4 | #define UDP_MUDUO_NET_SOCKETSOPS_H 5 | 6 | #ifndef _WIN32 7 | #include 8 | //#else 9 | //#include 10 | //#include 11 | //#include 12 | #endif 13 | 14 | 15 | namespace muduo 16 | { 17 | namespace net 18 | { 19 | class Buffer; 20 | namespace sockets 21 | { 22 | 23 | 24 | #ifndef _WIN32 25 | int createUdpNonblockingOrDie( sa_family_t family ); 26 | #else 27 | int createUdpNonblockingOrDie(int family); 28 | #endif 29 | 30 | int recvfrom(int sockfd, struct sockaddr_in6* addr, char *packetMem, int packetSize); 31 | } 32 | } 33 | } 34 | 35 | #endif // UDP_MUDUO_NET_SOCKETSOPS_H 36 | -------------------------------------------------------------------------------- /core/any.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/no5ix/realtinet/f940677ee7a563291b0071d31cdd952ab8b9566d/core/any.h -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set (LIB_NAME realtinet) 2 | 3 | IF(UNIX) 4 | 5 | add_executable(tcp_chat_client tcp_chat_client.cpp) 6 | target_link_libraries(tcp_chat_client ${LIB_NAME}) 7 | 8 | add_executable(tcp_chat_server tcp_chat_server.cpp) 9 | target_link_libraries(tcp_chat_server ${LIB_NAME}) 10 | 11 | add_executable(udp_chat_client udp_chat_client.cpp) 12 | target_link_libraries(udp_chat_client ${LIB_NAME}) 13 | 14 | add_executable(udp_chat_server udp_chat_server.cpp) 15 | target_link_libraries(udp_chat_server ${LIB_NAME}) 16 | 17 | else() 18 | message(SEND_ERROR "You are on an unsupported platform! (Not Win32 or Unix)") 19 | ENDIF() -------------------------------------------------------------------------------- /third/muduo-win/.gitignore: -------------------------------------------------------------------------------- 1 | *.bak 2 | ./src/build/* 3 | /src/build/ 4 | -------------------------------------------------------------------------------- /third/muduo-win/README.md: -------------------------------------------------------------------------------- 1 | # calm 2 | excerpts from muduo:https://github.com/chenshuo/muduo 3 | Change it to windows,use C++11. 4 | ## How to use 5 | ### Environment 6 | Use virtual studio 2017, which can support C++11 std::thread std::mutex and so on. 7 | ### Build 8 | Download from github
9 | `git clone git@github.com:kevin-gjm/calm.git`
10 | The sln file in src/build/calm/calm.sln 11 | build x86 Debug/Release
12 | 13 | The protobuf include and lib are in directory `src/3rdParty`.You may add it. 14 | 15 | ## PS 16 | Not separate the base and net library from the solution.You may do it by yourself. 17 | -------------------------------------------------------------------------------- /third/muduo-win/src/base/Mutex.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace muduo 6 | { 7 | 8 | // Use as data member of a class, eg. 9 | // 10 | // class Foo 11 | // { 12 | // public: 13 | // int size() const; 14 | // 15 | // private: 16 | // mutable MutexLock mutex_; 17 | // std::vector data_; // GUARDED BY mutex_ 18 | // }; 19 | #define MutexLock std::mutex 20 | 21 | // Use as a stack variable, eg. 22 | // int Foo::size() const 23 | // { 24 | // MutexLockGuard lock(mutex_); 25 | // return data_.size(); 26 | // } 27 | #define MutexLockGuard std::unique_lock 28 | } 29 | 30 | // Prevent misuse like: 31 | // MutexLockGuard(mutex_); 32 | // A tempory object doesn't hold the lock for long! 33 | //#define MutexLockGuard(x) error "Missing guard object name" -------------------------------------------------------------------------------- /third/muduo-win/src/base/async_logging.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | #ifdef _MSC_VER 8 | #define snprintf sprintf_s 9 | #endif 10 | 11 | using namespace muduo; 12 | 13 | AsyncLogging::AsyncLogging(const string& basename, 14 | size_t rollSize, 15 | int flushInterval /* = 3 */) 16 | :flushInterval_(flushInterval), 17 | running_(false), 18 | basename_(basename), 19 | rollSize_(rollSize), 20 | th_(), 21 | latch_(1), 22 | mutex_(), 23 | cond_(), 24 | currentBuffer_(new Buffer), 25 | nextBuffer_(new Buffer), 26 | buffers_() 27 | { 28 | currentBuffer_->bzero(); 29 | nextBuffer_->bzero(); 30 | buffers_.reserve(16); 31 | } 32 | 33 | void AsyncLogging::append(const char* logline, int len) 34 | { 35 | std::unique_lock lck(mutex_); 36 | if (currentBuffer_->avail() > len) 37 | { 38 | currentBuffer_->append(logline, len); 39 | } 40 | else 41 | { 42 | buffers_.push_back(currentBuffer_); 43 | if (nextBuffer_) 44 | { 45 | currentBuffer_ = nextBuffer_; 46 | } 47 | else 48 | { 49 | currentBuffer_.reset(new Buffer); 50 | } 51 | currentBuffer_->append(logline, len); 52 | cond_.notify_one(); 53 | }// end if (currentBuffer_->avail() > len) 54 | } 55 | 56 | void AsyncLogging::threadFunc() 57 | { 58 | assert(running_ == true); 59 | latch_.countDown(); 60 | LogFile output(basename_, rollSize_, false); 61 | BufferPtr newBuffer1(new Buffer); 62 | BufferPtr newBuffer2(new Buffer); 63 | newBuffer1->bzero(); 64 | newBuffer2->bzero(); 65 | BufferVector bufferToWrite; 66 | bufferToWrite.reserve(16); 67 | while (running_) 68 | { 69 | assert(newBuffer1 && newBuffer1->length() == 0); 70 | assert(newBuffer2 && newBuffer2->length() == 0); 71 | assert(bufferToWrite.empty()); 72 | { 73 | std::unique_lock lck(mutex_); 74 | if (buffers_.empty()) // unusual usage! 75 | { 76 | cond_.wait_for(lck, std::chrono::seconds(flushInterval_)); 77 | } 78 | buffers_.push_back(currentBuffer_); 79 | currentBuffer_ = std::move(newBuffer1); 80 | bufferToWrite.swap(buffers_); 81 | if (!nextBuffer_) 82 | { 83 | nextBuffer_ = std::move(newBuffer2); 84 | } 85 | }// end lck 86 | assert(!bufferToWrite.empty()); 87 | if (bufferToWrite.size() > 25) 88 | { 89 | char buf[256]; 90 | snprintf(buf, sizeof buf, "Dropped log messages at %s, %zd larger buffers\n", 91 | Timestamp::now().toFormattedString().c_str(), 92 | bufferToWrite.size() - 2); 93 | fputs(buf, stderr); 94 | output.append(buf, static_cast(strlen(buf))); 95 | bufferToWrite.erase(bufferToWrite.begin() + 2, bufferToWrite.end()); 96 | } 97 | for (size_t i = 0; i < bufferToWrite.size(); ++i) 98 | { 99 | output.append(bufferToWrite[i]->data(), bufferToWrite[i]->length()); 100 | } 101 | if (bufferToWrite.size() > 2) 102 | { 103 | bufferToWrite.resize(2); 104 | } 105 | if (!newBuffer1) 106 | { 107 | assert(!bufferToWrite.empty()); 108 | newBuffer1 = bufferToWrite.back(); 109 | bufferToWrite.pop_back(); 110 | newBuffer1->reset(); 111 | } 112 | 113 | if (!newBuffer2) 114 | { 115 | assert(!bufferToWrite.empty()); 116 | newBuffer2 = bufferToWrite.back(); 117 | bufferToWrite.pop_back(); 118 | newBuffer2->reset(); 119 | } 120 | bufferToWrite.clear(); 121 | output.flush(); 122 | }// end while (running_) 123 | output.flush(); 124 | } -------------------------------------------------------------------------------- /third/muduo-win/src/base/async_logging.h: -------------------------------------------------------------------------------- 1 | #ifndef CALM_BASE_ASYNCLOGGING_H_ 2 | #define CALM_BASE_ASYNCLOGGING_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace muduo 16 | { 17 | class AsyncLogging :muduo::uncopyable 18 | { 19 | public: 20 | AsyncLogging(const string& basename, 21 | size_t rollSize, 22 | int flushInterval = 3); 23 | ~AsyncLogging() 24 | { 25 | if (running_) 26 | { 27 | stop(); 28 | } 29 | } 30 | void append(const char* logline, int len); 31 | void start() 32 | { 33 | running_ = true; 34 | th_ = std::thread(std::bind(&AsyncLogging::threadFunc, this)); 35 | latch_.wait(); 36 | } 37 | void stop() 38 | { 39 | running_ = false; 40 | cond_.notify_one(); 41 | th_.join(); 42 | } 43 | private: 44 | void threadFunc(); 45 | 46 | typedef muduo::detail::FixedBuffer Buffer; 47 | typedef std::vector> BufferVector; 48 | typedef std::shared_ptr BufferPtr; 49 | 50 | const int flushInterval_; 51 | bool running_; 52 | string basename_; 53 | size_t rollSize_; 54 | std::thread th_; 55 | muduo::CountDownLatch latch_; 56 | std::mutex mutex_; 57 | std::condition_variable cond_; 58 | BufferPtr currentBuffer_; 59 | BufferPtr nextBuffer_; 60 | BufferVector buffers_; 61 | };// end class AsyncLogging 62 | }// end namespace muduo 63 | 64 | #endif //CALM_BASE_ASYNCLOGGING_H_ 65 | -------------------------------------------------------------------------------- /third/muduo-win/src/base/blocking_queue.h: -------------------------------------------------------------------------------- 1 | #ifndef CALM_BASE_BLOCKINGQUEUE_H_ 2 | #define CALM_BASE_BLOCKINGQUEUE_H_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | namespace muduo 11 | { 12 | template 13 | class BlockingQueue :muduo::uncopyable 14 | { 15 | public: 16 | BlockingQueue() 17 | :mutex_(), 18 | condition_(), 19 | queue_() 20 | {} 21 | void put(const T& x ) 22 | { 23 | std::unique_lock lck(mutex_); 24 | queue_.push_back(x); 25 | condition_.notify_one(); 26 | } 27 | T take() 28 | { 29 | std::unique_lock lck(mutex_); 30 | while(queue_.empty()) 31 | condition_.wait(lck); 32 | T font(queue_.front()); 33 | queue_.pop_front(); 34 | return x; 35 | } 36 | size_t size() const 37 | {} 38 | private: 39 | std::mutex mutex_; 40 | std::condition_variable condition_; 41 | std::deque queue_; 42 | }; 43 | }// end namespace muduo 44 | 45 | #endif //CALM_BASE_BLOCKINGQUEUE_H_ 46 | -------------------------------------------------------------------------------- /third/muduo-win/src/base/bounded_blocking_queue.h: -------------------------------------------------------------------------------- 1 | #ifndef CALM_BASE_BOUNDEDBLOCKINGQUEUE_H_ 2 | #define CALM_BASE_BOUNDEDBLOCKINGQUEUE_H_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | namespace muduo 11 | { 12 | template 13 | class BoundedBlockingQueue :muduo::uncopyable 14 | { 15 | public: 16 | BoundedBlockingQueue(int maxQueueSize) 17 | :mutex_(), 18 | notFull_(), 19 | notEmpty_(), 20 | maxQueueSize_(0) 21 | 22 | {} 23 | void setMaxQueueSize(int maxSize) { maxQueueSize_ = maxSize; } 24 | void put(T& x) 25 | { 26 | if (maxQueueSize_ == 0) 27 | return; 28 | std::unique_lock lck(mutex_); 29 | while (isFull()) 30 | { 31 | notFull_.wait(lck); 32 | } 33 | queue_.push_back(x); 34 | notEmpty_.notify_one(); 35 | } 36 | T take() 37 | { 38 | if (maxQueueSize_ == 0) 39 | return; 40 | std::unique_lock lck(mutex_); 41 | while (empty()) 42 | { 43 | notEmpty_.wait(lck); 44 | } 45 | T front(queue_.front()); 46 | queue_.pop_front(); 47 | notFull_.notify_one(); 48 | return front; 49 | } 50 | bool isFull() const 51 | { 52 | return maxQueueSize_ > 0 && queue_.size() > maxQueueSize_; 53 | } 54 | bool empty() const 55 | { 56 | std::unique_lock lck(mutex_); 57 | return queue_.empty(); 58 | } 59 | bool full() const 60 | { 61 | std::unique_lock lck(mutex_); 62 | return queue_.size() == maxQueueSize_; 63 | } 64 | size_t size() const 65 | { 66 | std::unique_lock lck(mutex_); 67 | return queue_.size(); 68 | } 69 | size_t capacity()const { return maxQueueSize_; } 70 | 71 | 72 | private: 73 | std::mutex mutex_; 74 | std::condition_variable notFull_; 75 | std::condition_variable notEmpty_; 76 | size_t maxQueueSize_; 77 | std::deque queue_; 78 | }; 79 | } //end namespace muduo 80 | 81 | #endif //CALM_BASE_BOUNDEDBLOCKINGQUEUE_H_ -------------------------------------------------------------------------------- /third/muduo-win/src/base/config_file_reader.h: -------------------------------------------------------------------------------- 1 | #ifndef CALM_BASE_CONFIGFILEREADER_H_ 2 | #define CALM_BASE_CONFIGFILEREADER_H_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | namespace muduo 9 | { 10 | class ConfigFileReader :muduo::uncopyable 11 | { 12 | public: 13 | ConfigFileReader(const char* filename); 14 | ~ConfigFileReader(); 15 | 16 | char* GetConfigName(const char* name); 17 | int SetConfigValue(const char* name, const char* value); 18 | private: 19 | void _LoadFile(const char* filename); 20 | int _WriteFile(const char*filename = NULL); 21 | void _ParseLine(char* line); 22 | char* _TrimSpace(char* name); 23 | 24 | bool m_load_ok; 25 | std::map m_config_map; 26 | std::string m_config_file; 27 | };//end class ConfigFileReader 28 | } //end namespace muduo 29 | 30 | #endif // !CALM_BASE_CONFIGFILEREADER_H_ 31 | -------------------------------------------------------------------------------- /third/muduo-win/src/base/copyable.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////// 2 | // 3 | // Copyright (c) 2016 gjm_kevin 4 | // gjm_kevin@163.com 5 | // 6 | ////////////////////////////////////////////////////////////////////// 7 | #ifndef CALM_BASE_COPYABLE_H_ 8 | #define CALM_BASE_COPYABLE_H_ 9 | namespace muduo 10 | { 11 | class copyable 12 | { 13 | }; 14 | }//end namespace muduo 15 | #endif //CALM_BASE_COPYABLE_H_ 16 | -------------------------------------------------------------------------------- /third/muduo-win/src/base/count_down_latch.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace muduo; 4 | CountDownLatch::CountDownLatch(int count) 5 | :mutex_(), 6 | condition_(), 7 | count_(count) 8 | {} 9 | 10 | void CountDownLatch::countDown() 11 | { 12 | std::unique_lock lck(mutex_); 13 | count_--; 14 | if (count_ == 0) 15 | condition_.notify_all(); 16 | } 17 | int CountDownLatch::getCount() const 18 | { 19 | std::unique_lock lck(mutex_); 20 | return count_; 21 | } 22 | void CountDownLatch::wait() 23 | { 24 | std::unique_lock lck(mutex_); 25 | while (count_ > 0) 26 | condition_.wait(lck); 27 | } -------------------------------------------------------------------------------- /third/muduo-win/src/base/count_down_latch.h: -------------------------------------------------------------------------------- 1 | #ifndef CALM_BASE_COUNTDOWNLATCH_H_ 2 | #define CALM_BASE_COUNTDOWNLATCH_H_ 3 | 4 | #include "uncopyable.h" 5 | #include 6 | 7 | #include 8 | #include 9 | namespace muduo 10 | { 11 | class CountDownLatch :muduo::uncopyable 12 | { 13 | public: 14 | explicit CountDownLatch(int count); 15 | void wait(); 16 | void countDown(); 17 | int getCount() const; 18 | private: 19 | mutable std::mutex mutex_; 20 | std::condition_variable condition_; 21 | int count_; 22 | 23 | };//end class CountDownLatch 24 | }//end namespace muduo 25 | 26 | #endif //CALM_BASE_COUNTDOWNLATCH_H_ -------------------------------------------------------------------------------- /third/muduo-win/src/base/file_util.h: -------------------------------------------------------------------------------- 1 | // excerpts from https://github.com/chenshuo/muduo 2 | // modify by:Kevin 3 | // 2016-08-15 13:47:23 file_util.h 4 | 5 | #ifndef CALM_BASE_FILEUTIL_H_ 6 | #define CALM_BASE_FILEUTIL_H_ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | namespace muduo 13 | { 14 | namespace FileUtil 15 | { 16 | //read small file <64k 17 | class ReadSmallFile 18 | { 19 | public: 20 | ReadSmallFile(StringArg filename); 21 | ~ReadSmallFile(); 22 | 23 | template 24 | int readToString(int maxSize, 25 | String* content, 26 | int64_t* fileSize, 27 | int64_t* modifyTime, 28 | int64_t* createTime); 29 | //read at maxium kBufferSize into buf_ 30 | int readToBuffer(int* size); 31 | const char* buffer() const { return buf_; } 32 | static const int kBufferSize = 64 * 1024; 33 | private: 34 | int fd_; // change linux system call open to fopen 35 | int err_; 36 | char buf_[kBufferSize]; 37 | };//end class ReadSmallFile 38 | 39 | //read the file content,returns errno if error happens 40 | template 41 | int readFile(StringArg filename, 42 | int maxSize, 43 | String* content, 44 | int64_t* fileSize = NULL, 45 | int64_t* modifyTime = NULL, 46 | int64_t* createTime = NULL) 47 | { 48 | ReadSmallFile file(filename); 49 | return file.readToString(maxSize, content, fileSize, modifyTime, createTime); 50 | } 51 | 52 | // not thread safe 53 | class AppendFile :muduo::uncopyable 54 | { 55 | public: 56 | explicit AppendFile(StringArg filename); 57 | ~AppendFile(); 58 | 59 | void append(const char* logline, const size_t len); 60 | void flush(); 61 | size_t writtenBytes() const { return writtenBytes_; } 62 | private: 63 | size_t _write(const char* logline, size_t len); 64 | FILE* fp_; 65 | char buffer_[64 * 1024]; 66 | size_t writtenBytes_; 67 | 68 | };// end class AppendFile 69 | }// end namespace FileUtil 70 | 71 | }//end namespace muduo 72 | 73 | #endif //CALM_BASE_FILEUTIL_H_ 74 | -------------------------------------------------------------------------------- /third/muduo-win/src/base/log_file.cc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/no5ix/realtinet/f940677ee7a563291b0071d31cdd952ab8b9566d/third/muduo-win/src/base/log_file.cc -------------------------------------------------------------------------------- /third/muduo-win/src/base/log_file.h: -------------------------------------------------------------------------------- 1 | #ifndef CAML_BASE_LOGFILE_H_ 2 | #define CAML_BASE_LOGFILE_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace muduo 10 | { 11 | 12 | namespace FileUtil 13 | { 14 | class AppendFile; 15 | } 16 | class LogFile : muduo::uncopyable 17 | { 18 | public: 19 | LogFile(const string& basename, 20 | size_t rollSize, 21 | bool threadSafe = true, 22 | int flushInterval = 3, 23 | int checkEveryN = 1024); 24 | ~LogFile(); 25 | 26 | void append(const char* logline, int len); 27 | void flush(); 28 | bool rollFile(); 29 | private: 30 | void _append_unlock(const char* logline, int len); 31 | static string _getLogFileName(const string& basename, time_t* now); 32 | const string basename_; 33 | const size_t rollSize_; 34 | bool threadSafe_; 35 | const int flushInterval_; 36 | const int checkEveryN_; 37 | 38 | int count_; 39 | time_t startOfPeriod_; 40 | time_t lastRoll_; 41 | time_t lashFlush_; 42 | mutable std::mutex mutex_; 43 | std::shared_ptr file_; 44 | const static int kRollPerSeconds = 60 * 60 * 24; 45 | };// end class LogFile 46 | }// end namespace muduo 47 | 48 | #endif CAML_BASE_LOGFILE_H_ -------------------------------------------------------------------------------- /third/muduo-win/src/base/security/base64.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // base64.cpp 3 | // pushservice 4 | // 5 | // Created by yunfan on 14/12/18. 6 | // Copyright (c) 2014 yunfan. All rights reserved. 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | using namespace std; 18 | 19 | static const char b64_table[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 20 | 21 | static const char reverse_table[128] = { 22 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 23 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 24 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, 25 | 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, 26 | 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 27 | 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, 28 | 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 29 | 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64 30 | }; 31 | 32 | string base64_encode(const string &bindata) 33 | { 34 | using std::numeric_limits; 35 | 36 | if (bindata.size() > (numeric_limits::max() / 4u) * 3u) { 37 | //throw length_error("Converting too large a string to base64."); 38 | return ""; 39 | } 40 | 41 | const size_t binlen = bindata.size(); 42 | // Use = signs so the end is properly padded. 43 | string retval((((binlen + 2) / 3) * 4), '='); 44 | size_t outpos = 0; 45 | int bits_collected = 0; 46 | unsigned int accumulator = 0; 47 | const string::const_iterator binend = bindata.end(); 48 | 49 | for (string::const_iterator i = bindata.begin(); i != binend; ++i) { 50 | accumulator = (accumulator << 8) | (*i & 0xffu); 51 | bits_collected += 8; 52 | while (bits_collected >= 6) { 53 | bits_collected -= 6; 54 | retval[outpos++] = b64_table[(accumulator >> bits_collected) & 0x3fu]; 55 | } 56 | } 57 | if (bits_collected > 0) { // Any trailing bits that are missing. 58 | assert(bits_collected < 6); 59 | accumulator <<= 6 - bits_collected; 60 | retval[outpos++] = b64_table[accumulator & 0x3fu]; 61 | } 62 | assert(outpos >= (retval.size() - 2)); 63 | assert(outpos <= retval.size()); 64 | return retval; 65 | } 66 | 67 | string base64_decode(const string &ascdata) 68 | { 69 | string retval; 70 | const string::const_iterator last = ascdata.end(); 71 | int bits_collected = 0; 72 | unsigned int accumulator = 0; 73 | 74 | for (string::const_iterator i = ascdata.begin(); i != last; ++i) { 75 | const int c = *i; 76 | if (isspace(c) || c == '=') { 77 | // Skip whitespace and padding. Be liberal in what you accept. 78 | continue; 79 | } 80 | if ((c > 127) || (c < 0) || (reverse_table[c] > 63)) { 81 | return ""; 82 | } 83 | accumulator = (accumulator << 6) | reverse_table[c]; 84 | bits_collected += 6; 85 | if (bits_collected >= 8) { 86 | bits_collected -= 8; 87 | retval += (char)((accumulator >> bits_collected) & 0xffu); 88 | } 89 | } 90 | return retval; 91 | } 92 | -------------------------------------------------------------------------------- /third/muduo-win/src/base/security/base64.h: -------------------------------------------------------------------------------- 1 | /************************************************************************/ 2 | /* from mogujie */ 3 | /************************************************************************/ 4 | #ifndef CALM_BASE_BASE64_H_ 5 | #define CALM_BASE_BASE64_H_ 6 | #include 7 | using namespace std; 8 | 9 | string base64_decode(const string &ascdata); 10 | string base64_encode(const string &bindata); 11 | 12 | #endif //CALM_BASE_BASE64_H_ 13 | 14 | -------------------------------------------------------------------------------- /third/muduo-win/src/base/security/md5.h: -------------------------------------------------------------------------------- 1 | /************************************************************************/ 2 | /* from mojujie 3 | /************************************************************************/ 4 | #ifndef CALM_BASE_MD5_H_ 5 | #define CALM_BASE_MD5_H_ 6 | void MD5_Calculate (const char* pContent, unsigned int nLen,char* md5); 7 | #endif //CALM_BASE_MD5_H_ 8 | -------------------------------------------------------------------------------- /third/muduo-win/src/base/thread.h: -------------------------------------------------------------------------------- 1 | // 20160812 10:23:34 2 | // kevin 3 | // some func for C++11 thread 4 | #ifndef CALM_BASE_THREAD_H_ 5 | #define CALM_BASE_THREAD_H_ 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | namespace muduo 12 | { 13 | inline const uint64_t convertThreadid(std::thread::id pid_t) 14 | { 15 | std::stringstream ss; 16 | ss << pid_t; 17 | return std::stoull(ss.str()); 18 | } 19 | inline const uint64_t getCurrentThreadId() 20 | { 21 | std::stringstream ss; 22 | ss << std::this_thread::get_id(); 23 | return std::stoull(ss.str()); 24 | } 25 | } 26 | 27 | #endif //CALM_BASE_THREAD_H_ 28 | -------------------------------------------------------------------------------- /third/muduo-win/src/base/thread_pool.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | #include 5 | #include //for_each 6 | #include 7 | 8 | using namespace muduo; 9 | 10 | ThreadPool::ThreadPool(const string& nameArg /* = string("ThreadPool") */) 11 | :mutex_(), 12 | notEmpty_(), 13 | notFull_(), 14 | maxQueueSize_(0), 15 | name_(nameArg), 16 | running_(false) 17 | { 18 | } 19 | 20 | ThreadPool::~ThreadPool() 21 | { 22 | if (running_) 23 | { 24 | stop(); 25 | } 26 | } 27 | void ThreadPool::start(int numThreads) 28 | { 29 | assert(thread_.empty()); 30 | running_ = true; 31 | thread_.reserve(numThreads); 32 | for (int i = 0; i < numThreads; ++i) 33 | { 34 | // or use std::move to move an exits object 35 | thread_.push_back(std::unique_ptr(new std::thread(std::bind(&ThreadPool::_runInThread,this)))); 36 | } 37 | if (numThreads == 0 && threadInitCallback_) 38 | { 39 | threadInitCallback_(); 40 | } 41 | } 42 | void ThreadPool::stop() 43 | { 44 | { 45 | std::unique_lock lck(mutex_); 46 | running_ = false; 47 | notEmpty_.notify_all(); 48 | } 49 | std::vector >::iterator iter; 50 | for (iter = thread_.begin(); iter != thread_.end();++iter) 51 | { 52 | (*iter)->join(); 53 | } 54 | } 55 | void ThreadPool::run(const Task& task) 56 | { 57 | if (thread_.empty()) 58 | { 59 | task(); 60 | } 61 | else 62 | { 63 | std::unique_lock lck(mutex_); 64 | while (_isFull()) 65 | { 66 | notFull_.wait(lck); 67 | } 68 | queue_.push_back(task); 69 | notEmpty_.notify_one(); 70 | } 71 | } 72 | ThreadPool::Task ThreadPool::_take() 73 | { 74 | std::unique_lock lck(mutex_); 75 | while (queue_.empty() && running_) 76 | { 77 | notEmpty_.wait(lck); 78 | } 79 | Task task; 80 | if (!queue_.empty()) 81 | { 82 | task = queue_.front(); 83 | queue_.pop_front(); 84 | if (maxQueueSize_ > 0) 85 | notFull_.notify_one(); 86 | } 87 | return task; 88 | } 89 | void ThreadPool::_runInThread() 90 | { 91 | try 92 | { 93 | if (threadInitCallback_) 94 | { 95 | threadInitCallback_(); 96 | } 97 | while (running_) 98 | { 99 | Task task(_take()); 100 | if (task) 101 | task(); 102 | } 103 | } 104 | catch (const std::exception ex) 105 | { 106 | abort(); 107 | } 108 | catch (...) 109 | { 110 | abort(); 111 | } 112 | 113 | } 114 | 115 | size_t ThreadPool::queueSize() const 116 | { 117 | std::unique_lock lck(mutex_); 118 | return queue_.size(); 119 | } 120 | bool ThreadPool::_isFull() const 121 | { 122 | return maxQueueSize_ > 0 && queue_.size() > maxQueueSize_; 123 | } -------------------------------------------------------------------------------- /third/muduo-win/src/base/thread_pool.h: -------------------------------------------------------------------------------- 1 | #ifndef CALM_BASE_THREADPOOL_H_ 2 | #define CALM_BASE_THREADPOOL_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace muduo 16 | { 17 | 18 | class ThreadPool :muduo::uncopyable 19 | { 20 | public: 21 | typedef std::function Task; 22 | explicit ThreadPool(const string& nameArg = string("ThreadPool")); 23 | ~ThreadPool(); 24 | // must set before start 25 | void setMaxQueueSize(int maxSize){ maxQueueSize_ = maxSize; } 26 | void setThreadInitCallback(const Task& cb) 27 | { 28 | threadInitCallback_ = cb; 29 | } 30 | 31 | void start(int numThreads); 32 | void stop(); 33 | const string& name() const 34 | { 35 | return name_; 36 | } 37 | 38 | size_t queueSize() const; 39 | void run(const Task& f); 40 | 41 | 42 | private: 43 | bool _isFull() const; 44 | void _runInThread(); 45 | Task _take(); 46 | 47 | mutable std::mutex mutex_; 48 | std::condition_variable notEmpty_; 49 | std::condition_variable notFull_; 50 | 51 | std::deque queue_; 52 | //FIXME: 53 | //1.here use: std::vector thread_; can it works ??perform well than blow? 54 | //2.replace boost::ptr_vector use vector 55 | // 56 | std::vector> thread_; 57 | 58 | size_t maxQueueSize_; 59 | Task threadInitCallback_; 60 | string name_; 61 | bool running_; 62 | 63 | };//end class ThreadPool 64 | }//end namespace muduo 65 | #endif //CALM_BASE_THREADPOOL_H_ -------------------------------------------------------------------------------- /third/muduo-win/src/base/timestamp.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | #ifdef _MSC_VER 7 | #define snprintf sprintf_s 8 | #endif 9 | 10 | 11 | using namespace muduo; 12 | 13 | Timestamp Timestamp::now() 14 | { 15 | struct timeval tv; 16 | wgettimeofday(&tv, NULL); 17 | int64_t seconds = tv.tv_sec; 18 | return Timestamp(seconds*Timestamp::kMicroSecondsPerSecond + tv.tv_usec); 19 | } 20 | 21 | std::string Timestamp::toString() const 22 | { 23 | char buf[32] = { 0 }; 24 | int64_t seconds = microSecondsSinceEpoch_ / kMicroSecondsPerSecond; 25 | int64_t microseconds = microSecondsSinceEpoch_ % kMicroSecondsPerSecond; 26 | snprintf(buf, sizeof(buf) - 1, "%" PRId64 ".%06" PRId64 "", seconds, microseconds); 27 | return buf; 28 | } 29 | 30 | std::string Timestamp::toFormattedString(bool showMicroseconds) const 31 | { 32 | char buf[32] = { 0 }; 33 | time_t seconds = static_cast(microSecondsSinceEpoch_ / kMicroSecondsPerSecond); 34 | struct tm tm_time; 35 | gmtime_s(&tm_time, &seconds); 36 | 37 | if (showMicroseconds) 38 | { 39 | int microseconds = static_cast(microSecondsSinceEpoch_ % kMicroSecondsPerSecond); 40 | snprintf(buf, sizeof(buf), "%4d%02d%02d %02d:%02d:%02d.%06d", 41 | tm_time.tm_year + 1900, tm_time.tm_mon + 1, tm_time.tm_mday, 42 | tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec, 43 | microseconds); 44 | } 45 | else 46 | { 47 | snprintf(buf, sizeof(buf), "%4d%02d%02d %02d:%02d:%02d", 48 | tm_time.tm_year + 1900, tm_time.tm_mon + 1, tm_time.tm_mday, 49 | tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec); 50 | } 51 | return buf; 52 | } 53 | 54 | -------------------------------------------------------------------------------- /third/muduo-win/src/base/timestamp.h: -------------------------------------------------------------------------------- 1 | #ifndef CALM_BASE_TIMESTAMP_H_ 2 | #define CALM_BASE_TIMESTAMP_H_ 3 | 4 | #include 5 | #include 6 | 7 | 8 | namespace muduo 9 | { 10 | class Timestamp :muduo::copyable 11 | { 12 | public: 13 | Timestamp() 14 | :microSecondsSinceEpoch_(0) 15 | {} 16 | explicit Timestamp(int64_t microSecondsSinceEpochArg) 17 | : microSecondsSinceEpoch_(microSecondsSinceEpochArg) 18 | {} 19 | void swap(Timestamp& that) 20 | { 21 | std::swap(microSecondsSinceEpoch_, that.microSecondsSinceEpoch_); 22 | } 23 | std::string toString() const; 24 | std::string toFormattedString(bool showMicroseconds =true) const; 25 | bool valid() const{ return microSecondsSinceEpoch_ > 0; } 26 | 27 | int64_t microSecondsSinceEpoch() const 28 | { 29 | return microSecondsSinceEpoch_; 30 | } 31 | time_t secondsSinceEpoch()const 32 | { 33 | return static_cast(microSecondsSinceEpoch_ / kMicroSecondsPerSecond); 34 | } 35 | static Timestamp now(); 36 | static Timestamp invalid() 37 | { 38 | return Timestamp(); 39 | } 40 | static Timestamp fromTime(time_t t) 41 | { 42 | fromTime(t, 0); 43 | } 44 | static Timestamp fromTime(time_t t, int microseconds) 45 | { 46 | return Timestamp(static_cast(t)*kMicroSecondsPerSecond + microseconds); 47 | } 48 | static const int kMicroSecondsPerSecond = 1000 * 1000; 49 | static const int kMicroSecondsPerMillisecond = 1000; 50 | 51 | private: 52 | int64_t microSecondsSinceEpoch_; 53 | };// end class Timestamp 54 | 55 | 56 | inline bool operator==(Timestamp lhs, Timestamp rhs) 57 | { 58 | return lhs.microSecondsSinceEpoch() == rhs.microSecondsSinceEpoch(); 59 | } 60 | inline bool operator!=(Timestamp lhs, Timestamp rhs) 61 | { 62 | return lhs.microSecondsSinceEpoch() != rhs.microSecondsSinceEpoch(); 63 | } 64 | inline bool operator<(Timestamp lhs, Timestamp rhs) 65 | { 66 | return lhs.microSecondsSinceEpoch() < rhs.microSecondsSinceEpoch(); 67 | } 68 | inline bool operator>(Timestamp lhs, Timestamp rhs) 69 | { 70 | return lhs.microSecondsSinceEpoch() > rhs.microSecondsSinceEpoch(); 71 | } 72 | inline bool operator<=(Timestamp lhs, Timestamp rhs) 73 | { 74 | return lhs.microSecondsSinceEpoch() <= rhs.microSecondsSinceEpoch(); 75 | } 76 | inline bool operator>=(Timestamp lhs, Timestamp rhs) 77 | { 78 | return lhs.microSecondsSinceEpoch() >= rhs.microSecondsSinceEpoch(); 79 | } 80 | //get difference of two timestamp,result in seconds 81 | inline double timeDifferenceSeconds(Timestamp high, Timestamp low) 82 | { 83 | int64_t diff = static_cast(high.microSecondsSinceEpoch() - low.microSecondsSinceEpoch()); 84 | return static_cast(diff) / Timestamp::kMicroSecondsPerSecond; 85 | } 86 | //get difference of two timestamp,result in ms 87 | inline int timeDifferenceMs(Timestamp high, Timestamp low) 88 | { 89 | int64_t diff = static_cast(high.microSecondsSinceEpoch() - low.microSecondsSinceEpoch()); 90 | return static_cast(diff / Timestamp::kMicroSecondsPerMillisecond); 91 | } 92 | //add seconds to given timestamp 93 | inline Timestamp addTime(Timestamp timestamp, double seconds) 94 | { 95 | int64_t delta = static_cast(seconds * Timestamp::kMicroSecondsPerSecond); 96 | return Timestamp(timestamp.microSecondsSinceEpoch() + delta); 97 | } 98 | 99 | }// end namespace muduo 100 | #endif //CALM_BASE_TIMESTAMP_H_ -------------------------------------------------------------------------------- /third/muduo-win/src/base/uncopyable.h: -------------------------------------------------------------------------------- 1 | #ifndef CALM_BASE_UNCOPYABLE_H_ 2 | #define CALM_BASE_UNCOPYABLE_H_ 3 | namespace muduo { 4 | namespace detail 5 | { 6 | class uncopyable 7 | { 8 | protected: 9 | uncopyable() {} 10 | ~uncopyable() {} 11 | private: 12 | uncopyable(const uncopyable&); 13 | uncopyable& operator=(const uncopyable&); 14 | }; 15 | 16 | class noncopyable 17 | { 18 | protected: 19 | noncopyable() {} 20 | ~noncopyable() {} 21 | private: 22 | noncopyable(const noncopyable&); 23 | noncopyable& operator=(const noncopyable&); 24 | }; 25 | } 26 | 27 | typedef detail::uncopyable uncopyable; 28 | typedef detail::noncopyable noncopyable; 29 | 30 | } 31 | #endif //CALM_BASE_UNCOPYABLE_H_ -------------------------------------------------------------------------------- /third/muduo-win/src/base/win_time.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int muduo::wgettimeofday(struct timeval *tv, struct timezone *tz) 4 | { 5 | FILETIME ft; 6 | unsigned __int64 tmpres = 0; 7 | static int tzflag = 0; 8 | 9 | if (NULL != tv) 10 | { 11 | GetSystemTimeAsFileTime(&ft); 12 | 13 | tmpres |= ft.dwHighDateTime; 14 | tmpres <<= 32; 15 | tmpres |= ft.dwLowDateTime; 16 | 17 | tmpres /= 10; /*convert into microseconds*/ 18 | /*converting file time to unix epoch*/ 19 | tmpres -= DELTA_EPOCH_IN_MICROSECS; 20 | tv->tv_sec = (long)(tmpres / 1000000UL); 21 | tv->tv_usec = (long)(tmpres % 1000000UL); 22 | } 23 | 24 | if (NULL != tz) 25 | { 26 | if (!tzflag) 27 | { 28 | _tzset(); 29 | tzflag++; 30 | } 31 | tz->tz_minuteswest = _timezone / 60; 32 | tz->tz_dsttime = _daylight; 33 | } 34 | 35 | return 0; 36 | } 37 | 38 | int muduo::wgmtime(struct timeval *tv, SYSTEMTIME *st) 39 | { 40 | FILETIME ft; 41 | unsigned __int64 tmpres = 0; 42 | tmpres = ((unsigned __int64)tv->tv_sec * 1000000UL) + (unsigned __int64)tv->tv_usec; 43 | tmpres += DELTA_EPOCH_IN_MICROSECS; 44 | tmpres *= 10; 45 | 46 | ft.dwLowDateTime = tmpres & 0xFFFFFFFF; 47 | ft.dwHighDateTime = (tmpres >> 32) & 0xFFFFFFFF; 48 | FileTimeToSystemTime(&ft, st); 49 | return 0; 50 | } 51 | 52 | -------------------------------------------------------------------------------- /third/muduo-win/src/base/win_time.h: -------------------------------------------------------------------------------- 1 | /* 2 | * https://gist.github.com/ugovaretto/5875385#file-win-gettimeofday-c 3 | */ 4 | #ifndef CALM_BASE_WINTIME_H_ 5 | #define CALM_BASE_WINTIME_H_ 6 | 7 | #include 8 | #include 9 | 10 | #if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) 11 | #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 12 | #else 13 | #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL 14 | #endif 15 | 16 | namespace muduo 17 | { 18 | struct timezone 19 | { 20 | int tz_minuteswest; /* minutes W of Greenwich */ 21 | int tz_dsttime; /* type of dst correction */ 22 | }; 23 | int wgettimeofday(struct timeval *tv, struct timezone *tz); 24 | int wgmtime(struct timeval *tv, SYSTEMTIME *st); 25 | }// end namespace muduo 26 | #endif //CALM_BASE_WINTIME_H_ -------------------------------------------------------------------------------- /third/muduo-win/src/net/Acceptor.cc: -------------------------------------------------------------------------------- 1 | #include "EventLoop.h" 2 | #include "Acceptor.h" 3 | #include "logging.h" 4 | #include "InetAddress.h" 5 | #include "SocketsOps.h" 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace muduo; 13 | using namespace muduo::net; 14 | 15 | Acceptor::Acceptor(EventLoop* loop, const InetAddress& listenAddr, bool reuseport /* = false */) 16 | :loop_(loop), 17 | acceptSocket_(sockets::createNoneblockOrDie(listenAddr.family())), 18 | acceptChannel_(loop, acceptSocket_.fd()), 19 | listenning_(false), 20 | idleFd_(::_open("nul", O_RDONLY)) 21 | { 22 | assert(idleFd_ >= 0); 23 | acceptSocket_.setReuseAddr(true); 24 | acceptSocket_.setReusePort(reuseport); 25 | acceptSocket_.bindAddress(listenAddr); 26 | acceptChannel_.setReadCallback(std::bind(&Acceptor::handleRead, this)); 27 | } 28 | 29 | Acceptor::~Acceptor() 30 | { 31 | acceptChannel_.disableAll(); 32 | acceptChannel_.remove(); 33 | ::_close(idleFd_); 34 | } 35 | void Acceptor::listen() 36 | { 37 | loop_->assertInLoopThread(); 38 | listenning_ = true; 39 | acceptSocket_.listen(); 40 | acceptChannel_.enableReading(); 41 | } 42 | 43 | void Acceptor::handleRead() 44 | { 45 | loop_->assertInLoopThread(); 46 | InetAddress peerAddr; 47 | int connfd = acceptSocket_.accept(&peerAddr); 48 | int saveErrno = GetLastError(); 49 | if (connfd > 0) 50 | { 51 | if (NewConnectionCallback_) 52 | { 53 | NewConnectionCallback_(connfd, peerAddr); 54 | } 55 | else 56 | { 57 | sockets::close(connfd); 58 | } 59 | } 60 | else 61 | { 62 | errno = saveErrno; 63 | LOG_SYSERR << "in Acceptor::handleRead"; 64 | //do not have enough file descriptor resource 65 | if (errno == WSAEMFILE) 66 | { 67 | ::_close(idleFd_); 68 | idleFd_ = ::accept(acceptSocket_.fd(), NULL, NULL); 69 | ::_close(idleFd_); 70 | idleFd_ = ::_open("nul", O_RDONLY); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /third/muduo-win/src/net/Acceptor.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Copyright(C) 2016, gjm_kevin. All rights reserved. 4 | // Author : gjm_kevin@163.com 5 | // Date : 2016.09.13 6 | // 7 | ////////////////////////////////////////////////////////////////////////// 8 | #ifndef CALM_NET_ACCEPTOR_H_ 9 | #define CALM_NET_ACCEPTOR_H_ 10 | 11 | #include 12 | #include "uncopyable.h" 13 | 14 | 15 | #include "Channel.h" 16 | #include "Socket.h" 17 | 18 | namespace muduo 19 | { 20 | namespace net 21 | { 22 | class EventLoop; 23 | class InetAddress; 24 | 25 | class Acceptor :uncopyable 26 | { 27 | public: 28 | typedef std::function NewConnectionCallback; 29 | Acceptor(EventLoop* loop, const InetAddress& listenAddr, bool reuseport = false); 30 | ~Acceptor(); 31 | void setNewConnectionCallback(const NewConnectionCallback& cb) 32 | { 33 | NewConnectionCallback_ = cb; 34 | } 35 | bool listenning() const { return listenning_; } 36 | void listen(); 37 | private: 38 | void handleRead(); 39 | EventLoop* loop_; 40 | Socket acceptSocket_; 41 | Channel acceptChannel_; 42 | NewConnectionCallback NewConnectionCallback_; 43 | bool listenning_; 44 | int idleFd_; 45 | };// end class Acceptor 46 | 47 | }// end namespace net 48 | }// end namespace muduo 49 | 50 | #endif //CALM_NET_ACCEPTOR_H_ -------------------------------------------------------------------------------- /third/muduo-win/src/net/Buffer.cc: -------------------------------------------------------------------------------- 1 | #include "Buffer.h" 2 | #include "SocketsOps.h" 3 | 4 | using namespace muduo; 5 | using namespace muduo::net; 6 | 7 | const char Buffer::kCRLF[] = "\r\n"; 8 | 9 | ssize_t muduo::net::Buffer::readFd(int fd, int * saveErrno) 10 | { 11 | char extrabuf[65536]; 12 | IOV_TYPE vec[2]; 13 | const size_t writable = writableBytes(); 14 | vec[0].buf = begin() + writerIndex_; 15 | vec[0].len = writable; 16 | vec[1].buf = extrabuf; 17 | vec[1].len = sizeof(extrabuf); 18 | const int iovcnt = (writable < sizeof(extrabuf)) ? 2 : 1; 19 | const ssize_t n = sockets::readv(fd, vec, iovcnt); 20 | if (n < 0) 21 | { 22 | *saveErrno = GetLastError(); 23 | } 24 | else if(implicit_cast(n) <= writable) 25 | { 26 | writerIndex_ += n; 27 | } 28 | else 29 | { 30 | writerIndex_ = buffer_.size(); 31 | append(extrabuf, n - writable); 32 | } 33 | return n; 34 | } 35 | -------------------------------------------------------------------------------- /third/muduo-win/src/net/Callbacks.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Copyright(C) 2016, gjm_kevin. All rights reserved. 4 | // Author : gjm_kevin@163.com 5 | // Date : 2016.09.20 6 | // 7 | ////////////////////////////////////////////////////////////////////////// 8 | #ifndef CALM_NET_CALLBACKS_H_ 9 | #define CALM_NET_CALLBACKS_H_ 10 | #include 11 | #include 12 | #include "timestamp.h" 13 | 14 | namespace muduo 15 | { 16 | 17 | using std::placeholders::_1; 18 | using std::placeholders::_2; 19 | using std::placeholders::_3; 20 | 21 | // should really belong to base/Types.h, but is not included there. 22 | 23 | template 24 | inline T* get_pointer(const std::shared_ptr& ptr) 25 | { 26 | return ptr.get(); 27 | } 28 | 29 | template 30 | inline T* get_pointer(const std::unique_ptr& ptr) 31 | { 32 | return ptr.get(); 33 | } 34 | 35 | // Adapted from google-protobuf stubs/common.h 36 | // see License in muduo/base/Types.h 37 | template 38 | inline ::std::shared_ptr down_pointer_cast(const ::std::shared_ptr& f) 39 | { 40 | if (false) 41 | { 42 | implicit_cast(0); 43 | } 44 | 45 | #ifndef NDEBUG 46 | assert(f == NULL || dynamic_cast(get_pointer(f)) != NULL); 47 | #endif 48 | return ::std::static_pointer_cast(f); 49 | } 50 | 51 | namespace net 52 | { 53 | class Buffer; 54 | class TcpConnection; 55 | typedef std::shared_ptr TcpConnectionPtr; 56 | typedef std::function TimerCallback; 57 | typedef std::function ConnectionCallback; 58 | typedef std::function CloseCallback; 59 | typedef std::function WriteCompleteCallback; 60 | typedef std::function HighWaterMarkCallback; 61 | 62 | typedef std::functionMessageCallback; 63 | 64 | void defaultConnectionCallback(const TcpConnectionPtr& conn); 65 | void defaultMessageCallback(const TcpConnectionPtr& conn, Buffer* buffer, Timestamp receiveTime); 66 | }// end namespace net 67 | }// end namespace muduo 68 | 69 | #endif //CALM_NET_CALLBACKS_H_ -------------------------------------------------------------------------------- /third/muduo-win/src/net/Channel.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | //#include 5 | 6 | #include 7 | #include 8 | 9 | 10 | using namespace muduo; 11 | using namespace muduo::net; 12 | 13 | const int Channel::kNoneEvent = 0; 14 | const int Channel::kReadEvent = POLLIN | POLLPRI; 15 | const int Channel::kWriteEvent = POLLOUT; 16 | 17 | Channel::Channel(EventLoop* loop, int fd) 18 | :loop_(loop), 19 | fd_(fd), 20 | events_(0), 21 | revents_(0), 22 | index_(-1), 23 | logHup_(true), 24 | tied_(false), 25 | eventHandling_(false), 26 | addedToLoop_(false) 27 | { 28 | 29 | } 30 | Channel::~Channel() 31 | { 32 | assert(!eventHandling_); 33 | assert(!addedToLoop_); 34 | if (loop_->isInLoopThread()) 35 | { 36 | assert(!loop_->hasChannel(this)); 37 | } 38 | } 39 | 40 | void Channel::tie(const std::shared_ptr& obj) 41 | { 42 | tie_ = obj; 43 | tied_ = true; 44 | } 45 | void Channel::update() 46 | { 47 | addedToLoop_ = true; 48 | loop_->updateChannel(this); 49 | } 50 | void Channel::remove() 51 | { 52 | assert(isNoneEvent()); 53 | addedToLoop_ = false; 54 | loop_->removeChannel(this); 55 | } 56 | void Channel::handleEvent(Timestamp receiveTime) 57 | { 58 | std::shared_ptr guard; 59 | if (tied_) 60 | { 61 | guard = tie_.lock(); 62 | if(guard) 63 | { 64 | handleEventWithGuard(receiveTime); 65 | } 66 | } 67 | else 68 | { 69 | handleEventWithGuard(receiveTime); 70 | } 71 | } 72 | 73 | void Channel::handleEventWithGuard(Timestamp receiveTime) 74 | { 75 | eventHandling_ = true; 76 | LOG_TRACE << reventsToString(); 77 | if((revents_&POLLHUP)&& !(revents_&POLLIN)) 78 | { 79 | if (logHup_) 80 | { 81 | LOG_WARN << "fd = " << fd_ << "Channel::handle_event() POLLHUP"; 82 | } 83 | if (closeCallback_) closeCallback_(); 84 | } 85 | if (revents_&POLLNVAL) 86 | { 87 | LOG_WARN << "fd = " << fd_ << "Channel::handle_event() POLLNVAL"; 88 | } 89 | if (revents_&(POLLERR | POLLNVAL)) 90 | { 91 | if (errorCallback_) errorCallback_(); 92 | } 93 | if (revents_&(POLLIN | POLLPRI )) 94 | { 95 | if (readCallback_) readCallback_(receiveTime); 96 | } 97 | if (revents_&POLLOUT) 98 | { 99 | if (writeCallback_) writeCallback_(); 100 | } 101 | eventHandling_ = false; 102 | } 103 | 104 | string Channel::reventsToString() const 105 | { 106 | return eventsToString(fd_, revents_); 107 | } 108 | string Channel::eventsToString()const 109 | { 110 | return eventsToString(fd_, events_); 111 | } 112 | string Channel::eventsToString(int fd, int ev) 113 | { 114 | std::ostringstream oss; 115 | oss << fd << ": "; 116 | if (ev & POLLIN) 117 | oss << "IN "; 118 | if (ev & POLLPRI) 119 | oss << "PRI "; 120 | if (ev & POLLOUT) 121 | oss << "OUT "; 122 | if (ev & POLLHUP) 123 | oss << "HUP "; 124 | //if (ev & POLLRDHUP) 125 | // oss << "RDHUP "; 126 | if (ev & POLLERR) 127 | oss << "ERR "; 128 | if (ev & POLLNVAL) 129 | oss << "NVAL "; 130 | 131 | return oss.str().c_str(); 132 | } -------------------------------------------------------------------------------- /third/muduo-win/src/net/Channel.h: -------------------------------------------------------------------------------- 1 | #ifndef CALM_NET_CHANNEL_H_ 2 | #define CALM_NET_CHANNEL_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | namespace muduo 10 | { 11 | namespace net 12 | { 13 | class EventLoop; 14 | 15 | class Channel :muduo::uncopyable 16 | { 17 | public: 18 | typedef std::function EventCallback; 19 | typedef std::function ReadEventCallback; 20 | 21 | Channel(EventLoop* loop, int fd); 22 | ~Channel(); 23 | void handleEvent(Timestamp receiveTime); 24 | void setReadCallback(const ReadEventCallback& cb) 25 | { 26 | readCallback_ = cb; 27 | } 28 | void setWriteCallback(const EventCallback& cb) 29 | { 30 | writeCallback_ = cb; 31 | } 32 | void setCloseCallback(const EventCallback& cb) 33 | { 34 | closeCallback_ = cb; 35 | } 36 | void setErrorCallback(const EventCallback& cb) 37 | { 38 | errorCallback_ = cb; 39 | } 40 | void tie(const std::shared_ptr&); 41 | int fd() const { return fd_; } 42 | int events() const { return events_; } 43 | void set_revents(int revt) { revents_ = revt; } 44 | bool isNoneEvent() const { return events_ == kNoneEvent; } 45 | 46 | void enableReading() 47 | { 48 | events_ |= kReadEvent; 49 | update(); 50 | } 51 | void disableReading() 52 | { 53 | events_ &= ~kReadEvent; 54 | update(); 55 | } 56 | void enableWriting() 57 | { 58 | events_ |= kWriteEvent; 59 | update(); 60 | } 61 | void disableWriting() 62 | { 63 | events_ &= ~kWriteEvent; 64 | update(); 65 | } 66 | void disableAll() 67 | { 68 | events_ = kNoneEvent; 69 | update(); 70 | } 71 | 72 | bool isWriting() const 73 | { 74 | return (events_ & kWriteEvent) != 0; 75 | } 76 | bool isReading() const 77 | { 78 | return (events_ & kReadEvent) != 0; 79 | } 80 | int index() { return index_; } 81 | void set_index(int idx) { index_ = idx; } 82 | 83 | std::string reventsToString()const; 84 | std::string eventsToString()const; 85 | 86 | void doNotLogHup() { logHup_ = false; }; 87 | EventLoop* ownerLoop() { return loop_; } 88 | void remove(); 89 | 90 | private: 91 | static string eventsToString(int fd, int ev); 92 | void update(); 93 | void handleEventWithGuard(Timestamp receiveTime); 94 | static const int kNoneEvent; 95 | static const int kReadEvent; 96 | static const int kWriteEvent; 97 | 98 | int index_; 99 | const int fd_; 100 | int events_; 101 | int revents_; 102 | int logHup_; 103 | 104 | std::weak_ptr tie_; 105 | bool tied_; 106 | bool eventHandling_; 107 | bool addedToLoop_; 108 | 109 | EventLoop* loop_; 110 | ReadEventCallback readCallback_; 111 | EventCallback writeCallback_; 112 | EventCallback closeCallback_; 113 | EventCallback errorCallback_; 114 | 115 | 116 | 117 | }; 118 | }// end namespace net 119 | }// end namespace muduo 120 | 121 | #endif //CALM_NET_CHANNEL_H_ -------------------------------------------------------------------------------- /third/muduo-win/src/net/Connector.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Copyright(C) 2016, gjm_kevin. All rights reserved. 4 | // Author : gjm_kevin@163.com 5 | // 6 | ////////////////////////////////////////////////////////////////////////// 7 | #ifndef CALM_NET_CONNECTOR_H_ 8 | #define CALM_NET_CONNECTOR_H_ 9 | #include "InetAddress.h" 10 | #include "uncopyable.h" 11 | 12 | #include 13 | #include 14 | 15 | namespace muduo 16 | { 17 | namespace net 18 | { 19 | class EventLoop; 20 | class Channel; 21 | class Connector :muduo::uncopyable, public std::enable_shared_from_this 22 | { 23 | public: 24 | typedef std::function NewConnectionCallback; 25 | Connector(EventLoop* loop, const InetAddress& serverAddr); 26 | ~Connector(); 27 | 28 | void setNewConnectionCallback(const NewConnectionCallback& cb) { newConnectionCallback_ = cb; } 29 | 30 | void start(); 31 | void restart(); 32 | void stop(); 33 | 34 | const InetAddress& serverAddress() const { return serverAddr_; } 35 | private: 36 | enum States {kDisconnected,kConnecting,kConnected}; 37 | static const int kMaxRetryDelayMs = 30 * 1000; 38 | static const int kInitRetryDelayMs = 500; 39 | 40 | void setState(States s) { state_ = s; } 41 | 42 | void startInLoop(); 43 | void stopInLoop(); 44 | void connect(); 45 | void connecting(int sockfd); 46 | 47 | void handleWrite(); 48 | void handleError(); 49 | 50 | void retry(int sockfd); 51 | 52 | int removeAndResetChannel(); 53 | void resetChannel(); 54 | 55 | EventLoop* loop_; 56 | InetAddress serverAddr_; 57 | bool connect_; 58 | States state_; 59 | std::shared_ptr channel_; 60 | NewConnectionCallback newConnectionCallback_; 61 | int retryDelayMs_; 62 | };//end class Connector 63 | }// end namespace net 64 | }// end namespace muduo 65 | 66 | 67 | #endif //CALM_NET_CONNECTOR_H_ -------------------------------------------------------------------------------- /third/muduo-win/src/net/Endian.h: -------------------------------------------------------------------------------- 1 | #ifndef CALM_NET_ENDIAN_H_ 2 | #define CALM_NET_ENDIAN_H_ 3 | 4 | #include 5 | #pragma comment( lib, "ws2_32.lib" ) // for select 6 | #pragma comment(lib,"ws2_32") 7 | #include 8 | 9 | 10 | //#ifndef ULONG64 11 | //#define unsigned long long ULONG64 12 | //#endif 13 | 14 | 15 | 16 | namespace muduo 17 | { 18 | namespace net 19 | { 20 | namespace sockets 21 | { 22 | inline uint64_t hostToNetwork64(uint64_t host64) 23 | { 24 | uint64_t ret = 0; 25 | uint32_t high, low; 26 | 27 | low = host64 & 0xFFFFFFFF; 28 | high = (host64 >> 32) & 0xFFFFFFFF; 29 | low = htonl(low); 30 | high = htonl(high); 31 | ret = low; 32 | ret <<= 32; 33 | ret |= high; 34 | return ret; 35 | } 36 | inline uint32_t hostToNetwork32(uint32_t host32) 37 | { 38 | return htonl(host32); 39 | } 40 | inline uint16_t hostToNetwork16(uint16_t host16) 41 | { 42 | return htons(host16); 43 | } 44 | inline uint64_t networkToHost64(uint64_t net64) 45 | { 46 | uint64_t ret = 0; 47 | uint32_t high, low; 48 | 49 | low = net64 & 0xFFFFFFFF; 50 | high = (net64 >> 32) & 0xFFFFFFFF; 51 | low = ntohl(low); 52 | high = ntohl(high); 53 | 54 | ret = low; 55 | ret <<= 32; 56 | ret |= high; 57 | return ret; 58 | } 59 | inline uint32_t networkToHost32(uint32_t net32) 60 | { 61 | return ntohl(net32); 62 | } 63 | inline uint16_t networkToHost16(uint16_t net16) 64 | { 65 | return ntohs(net16); 66 | } 67 | }//end namespace sockets 68 | }//end namespace net 69 | }// end namespace muduo 70 | 71 | #endif //CALM_NET_ENDIAN_H_ -------------------------------------------------------------------------------- /third/muduo-win/src/net/EventLoop.cc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/no5ix/realtinet/f940677ee7a563291b0071d31cdd952ab8b9566d/third/muduo-win/src/net/EventLoop.cc -------------------------------------------------------------------------------- /third/muduo-win/src/net/EventLoopThread.cc: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Copyright(C) 2016, gjm_kevin. All rights reserved. 4 | // Author : gjm_kevin@163.com 5 | // 6 | ////////////////////////////////////////////////////////////////////////// 7 | #include "EventLoop.h" 8 | #include "EventLoopThread.h" 9 | 10 | using namespace muduo; 11 | using namespace muduo::net; 12 | 13 | EventLoopThread::EventLoopThread(const ThreadInitCallback& cb /* = ThreadInitCallback() */) 14 | :loop_(NULL), 15 | exiting_(false), 16 | threadStarting_(false), 17 | thread_(), 18 | mutex_(), 19 | cond_(), 20 | callback_(cb) 21 | {} 22 | EventLoopThread::~EventLoopThread() 23 | { 24 | exiting_ = true; 25 | if (loop_ != NULL) 26 | { 27 | loop_->quit(); 28 | } 29 | if (threadStarting_) 30 | { 31 | thread_.join(); 32 | } 33 | 34 | 35 | } 36 | EventLoop* EventLoopThread::startLoop() 37 | { 38 | thread_ = std::thread(std::bind(&EventLoopThread::threadFunc, this)); 39 | threadStarting_ = true; 40 | { 41 | std::unique_lock lck(mutex_); 42 | while (loop_ == NULL) 43 | { 44 | cond_.wait(lck); 45 | } 46 | } 47 | return loop_; 48 | } 49 | void EventLoopThread::threadFunc() 50 | { 51 | EventLoop loop; 52 | if(callback_) 53 | { 54 | callback_(&loop); 55 | } 56 | { 57 | std::unique_lock lck(mutex_); 58 | loop_ = &loop; 59 | cond_.notify_one(); 60 | } 61 | loop.loop(); 62 | loop_ = NULL; 63 | } 64 | -------------------------------------------------------------------------------- /third/muduo-win/src/net/EventLoopThread.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Copyright(C) 2016, gjm_kevin. All rights reserved. 4 | // Author : gjm_kevin@163.com 5 | // 6 | ////////////////////////////////////////////////////////////////////////// 7 | #ifndef CALM_NET_EVENTLOOPTHREAD_H_ 8 | #define CALM_NET_EVENTLOOPTHREAD_H_ 9 | #include "uncopyable.h" 10 | #include "types.h" 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace muduo 17 | { 18 | namespace net 19 | { 20 | class EventLoop; 21 | class EventLoopThread :muduo::uncopyable 22 | { 23 | public: 24 | typedef std::function ThreadInitCallback; 25 | EventLoopThread(const ThreadInitCallback& cb = ThreadInitCallback()); 26 | ~EventLoopThread(); 27 | 28 | EventLoop* startLoop(); 29 | 30 | private: 31 | void threadFunc(); 32 | 33 | EventLoop* loop_; 34 | bool exiting_; 35 | // if thread_ not started, dtor will abort 36 | bool threadStarting_; 37 | std::thread thread_; 38 | std::mutex mutex_; 39 | std::condition_variable cond_; 40 | ThreadInitCallback callback_; 41 | 42 | 43 | };// end class EventLoopThread 44 | }// end namespace net 45 | }// end namespace muduo 46 | #endif //CALM_NET_EVENTLOOPTHREAD_H_ 47 | -------------------------------------------------------------------------------- /third/muduo-win/src/net/EventLoopThreadPool.cc: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Copyright(C) 2016, gjm_kevin. All rights reserved. 4 | // Author : gjm_kevin@163.com 5 | // 6 | ////////////////////////////////////////////////////////////////////////// 7 | #include "EventLoop.h" 8 | #include "EventLoopThread.h" 9 | #include "EventLoopThreadPool.h" 10 | #include 11 | using namespace muduo; 12 | using namespace muduo::net; 13 | 14 | EventLoopThreadPool::EventLoopThreadPool(EventLoop* baseLoop, const string& nameArg) 15 | : baseLoop_(baseLoop), 16 | name_(nameArg), 17 | started_(false), 18 | numThreads_(0), 19 | next_(0) 20 | {} 21 | 22 | //EventLoopThreadPool::EventLoopThreadPool(EventLoop* baseLoop) 23 | // :baseLoop_(baseLoop), 24 | // started_(false), 25 | // numThreads_(0), 26 | // next_(0) 27 | //{} 28 | EventLoopThreadPool::~EventLoopThreadPool() 29 | { 30 | // Don't delete loop, it's stack variable 31 | } 32 | void EventLoopThreadPool::start(const ThreadInitCallback& cb /* = ThreadInitCallback() */) 33 | { 34 | assert(!started_); 35 | baseLoop_->assertInLoopThread(); 36 | started_ = true; 37 | 38 | for (int i=0;i foo(new EventLoopThread(cb)) ; 41 | loops_.push_back(foo->startLoop()); 42 | threads_.push_back(std::move(foo)); 43 | } 44 | if (numThreads_ == 0 && cb) 45 | { 46 | cb(baseLoop_); 47 | } 48 | } 49 | 50 | EventLoop* EventLoopThreadPool::getNextLoop() 51 | { 52 | baseLoop_->assertInLoopThread(); 53 | assert(started_); 54 | EventLoop* loop = baseLoop_; 55 | if (!loops_.empty()) 56 | { 57 | //round-robin 58 | loop = loops_[next_]; 59 | ++next_; 60 | if (implicit_cast(next_) >= loops_.size()) 61 | { 62 | next_ = 0; 63 | } 64 | } 65 | return loop; 66 | } 67 | EventLoop* EventLoopThreadPool::getLoopForHash(size_t hashCode) 68 | { 69 | baseLoop_->assertInLoopThread(); 70 | EventLoop* loop = baseLoop_; 71 | 72 | if (!loops_.empty()) 73 | { 74 | loop = loops_[hashCode % loops_.size()]; 75 | } 76 | return loop; 77 | } 78 | 79 | std::vector EventLoopThreadPool::getAllLoops() 80 | { 81 | baseLoop_->assertInLoopThread(); 82 | assert(started_); 83 | if (loops_.empty()) 84 | { 85 | return std::vector(1, baseLoop_); 86 | } 87 | else 88 | { 89 | return loops_; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /third/muduo-win/src/net/EventLoopThreadPool.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Copyright(C) 2016, gjm_kevin. All rights reserved. 4 | // Author : gjm_kevin@163.com 5 | // 6 | ////////////////////////////////////////////////////////////////////////// 7 | #ifndef CALM_NET_EVENTLOOPTHREADPOOL_H_ 8 | #define CALM_NET_EVENTLOOPTHREADPOOL_H_ 9 | #include "types.h" 10 | #include "uncopyable.h" 11 | #include 12 | #include 13 | #include 14 | 15 | namespace muduo 16 | { 17 | namespace net 18 | { 19 | class EventLoop; 20 | class EventLoopThread; 21 | class EventLoopThreadPool :muduo::uncopyable 22 | { 23 | public: 24 | typedef std::function ThreadInitCallback; 25 | 26 | EventLoopThreadPool(EventLoop* baseLoop, const string& nameArg); 27 | //EventLoopThreadPool(EventLoop* baseLoop); 28 | ~EventLoopThreadPool(); 29 | void setThreadNum(int numThreads) { numThreads_ = numThreads; } 30 | void start(const ThreadInitCallback& cb = ThreadInitCallback()); 31 | 32 | //valid after calling start() 33 | // round-robin 34 | EventLoop* getNextLoop(); 35 | /// with the same hash code, it will always return the same EventLoop 36 | EventLoop* getLoopForHash(size_t hashCode); 37 | 38 | std::vector getAllLoops(); 39 | 40 | bool started() const { return started_; } 41 | 42 | const string& name() const 43 | { return name_; } 44 | 45 | private: 46 | EventLoop* baseLoop_; 47 | string name_; 48 | bool started_; 49 | int numThreads_; 50 | int next_; 51 | std::vector > threads_; 52 | // just use the pointer, dtor use threads_ unique_ptr 53 | std::vector loops_; 54 | 55 | };// end class EventLoopThreadPool 56 | }// end namespace net 57 | }// end namespace muduo 58 | 59 | #endif //CALM_NET_EVENTLOOPTHREADPOOL_H_ -------------------------------------------------------------------------------- /third/muduo-win/src/net/InetAddress.cc: -------------------------------------------------------------------------------- 1 | #include "InetAddress.h" 2 | #include "logging.h" 3 | #include "Endian.h" 4 | 5 | //#include "types.h" 6 | 7 | using namespace muduo; 8 | using namespace muduo::net; 9 | 10 | InetAddress::InetAddress(uint16_t port /* = 0 */, bool loopbackOnly /* = false */) 11 | { 12 | memset(&addr_, 0, sizeof(addr_)); 13 | addr_.sin_family = AF_INET; 14 | if (loopbackOnly) 15 | { 16 | addr_.sin_addr.s_addr = sockets::hostToNetwork32(INADDR_LOOPBACK); 17 | } 18 | else 19 | { 20 | addr_.sin_addr.s_addr = sockets::hostToNetwork32(INADDR_ANY); 21 | } 22 | addr_.sin_port = sockets::hostToNetwork16(port); 23 | } 24 | 25 | InetAddress::InetAddress(StringArg ip, uint16_t port) 26 | { 27 | memset(&addr_, 0, sizeof(addr_)); 28 | sockets::fromIpPort(ip.c_str(), port, &addr_); 29 | } 30 | 31 | string InetAddress::toIp() const 32 | { 33 | char buf[64] = { 0 }; 34 | sockets::toIp(buf, sizeof(buf), getSockAddr()); 35 | return buf; 36 | } 37 | 38 | uint16_t InetAddress::toPort() const 39 | { 40 | return sockets::networkToHost16(addr_.sin_port); 41 | } 42 | 43 | string InetAddress::toIpPort() const 44 | { 45 | char buf[64] = { 0 }; 46 | sockets::toIpPort(buf, sizeof(buf), getSockAddr()); 47 | return buf; 48 | } 49 | uint32_t InetAddress::ipNetEndian() const 50 | { 51 | return addr_.sin_addr.s_addr; 52 | } 53 | 54 | bool InetAddress::operator<(const InetAddress& other) const 55 | { 56 | const struct sockaddr_in6* thisAddr = this->getSockAddr6(); 57 | const struct sockaddr_in6* otherAddr = other.getSockAddr6(); 58 | if (thisAddr->sin6_family == AF_INET) 59 | { 60 | const struct sockaddr_in* laddr4 = reinterpret_cast(thisAddr); 61 | const struct sockaddr_in* raddr4 = reinterpret_cast(otherAddr); 62 | if (laddr4->sin_addr.s_addr < raddr4->sin_addr.s_addr) 63 | { 64 | return true; 65 | } 66 | else if (laddr4->sin_port < raddr4->sin_port) 67 | { 68 | return true; 69 | } 70 | else 71 | { 72 | return false; 73 | } 74 | } 75 | else if (thisAddr->sin6_family == AF_INET6) 76 | { 77 | if (memcmp(&thisAddr->sin6_addr, &otherAddr->sin6_addr, sizeof thisAddr->sin6_addr) < 0) 78 | { 79 | return true; 80 | } 81 | else if (thisAddr->sin6_port < otherAddr->sin6_port) 82 | { 83 | return true; 84 | } 85 | else 86 | { 87 | return false; 88 | } 89 | } 90 | else 91 | { 92 | return false; 93 | } 94 | } -------------------------------------------------------------------------------- /third/muduo-win/src/net/InetAddress.h: -------------------------------------------------------------------------------- 1 | #ifndef CALM_NET_INETADDRESS_H_ 2 | #define CALM_NET_INETADDRESS_H_ 3 | #include "copyable.h" 4 | #include "stringpiece.h" 5 | #include "SocketsOps.h" 6 | 7 | namespace muduo 8 | { 9 | namespace net 10 | { 11 | 12 | namespace sockets 13 | { 14 | const struct sockaddr* sockaddr_cast(const struct sockaddr_in6* addr); 15 | //const struct sockaddr* sockaddr_cast(const struct sockaddr_in* addr) ; 16 | } 17 | 18 | class InetAddress :public muduo::copyable 19 | { 20 | public: 21 | // mostly used in tcp server listening 22 | // loopbackOnly is refer to 127.0.0.1 23 | explicit InetAddress(uint16_t port = 0, bool loopbackOnly = false); 24 | InetAddress(StringArg ip, uint16_t port); 25 | 26 | /// Constructs an endpoint with given struct @c sockaddr_in 27 | /// Mostly used when accepting new connections 28 | explicit InetAddress(const struct sockaddr_in& addr) 29 | : addr_(addr) 30 | {} 31 | 32 | explicit InetAddress(const struct sockaddr_in6& addr) 33 | : addr6_(addr) 34 | {} 35 | 36 | void setSockAddrIn(const struct sockaddr_in& addr) { addr_ = addr; } 37 | ADDRESS_FAMILY family()const { return addr_.sin_family; } 38 | string toIp() const; 39 | string toIpPort() const; 40 | uint16_t toPort() const; 41 | 42 | const struct sockaddr* getSockAddr() const { return sockets::sockaddr_cast(&addr6_); } 43 | 44 | void setSockAddrInet6(const struct sockaddr_in6& addr6) { addr6_ = addr6; } 45 | 46 | uint32_t ipNetEndian() const; 47 | uint16_t portNetEndian() const { return addr_.sin_port; }; 48 | 49 | 50 | // for UdpAcceptor::peerAddrs_ 51 | const struct sockaddr_in6* getSockAddr6() const { return &addr6_; } 52 | bool operator<(const InetAddress& other) const; 53 | 54 | 55 | //private: 56 | //struct sockaddr_in addr_; 57 | private: 58 | union 59 | { 60 | struct sockaddr_in addr_; 61 | struct sockaddr_in6 addr6_; 62 | }; 63 | }; 64 | }//end namespace net 65 | }// end namespace muduo 66 | 67 | #endif //CALM_NET_INETADDRESS_H_ -------------------------------------------------------------------------------- /third/muduo-win/src/net/Poller.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace muduo; 5 | using namespace muduo::net; 6 | 7 | Poller::Poller(EventLoop* loop) 8 | :ownerLoop_(loop) 9 | {} 10 | 11 | Poller::~Poller() 12 | {} 13 | bool Poller::hasChannel(Channel* channel) const 14 | { 15 | assertInLoopThread(); 16 | ChannelMap::const_iterator it = channels_.find(channel->fd()); 17 | return it != channels_.end() && it->second == channel; 18 | } -------------------------------------------------------------------------------- /third/muduo-win/src/net/Poller.h: -------------------------------------------------------------------------------- 1 | #ifndef CALM_NET_POLLER_H_ 2 | #define CALM_NET_POLLER_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | namespace muduo 12 | { 13 | namespace net 14 | { 15 | class Channel; 16 | class Poller :muduo::uncopyable 17 | { 18 | public: 19 | typedef std::vector ChannelList; 20 | 21 | Poller(EventLoop* loop); 22 | virtual ~Poller(); 23 | 24 | virtual Timestamp poll(int timeoutMs, ChannelList* activeChannels) = 0; 25 | 26 | virtual void updateChannel(Channel* channel) = 0; 27 | 28 | virtual void removeChannel(Channel* channel) = 0; 29 | 30 | virtual bool hasChannel(Channel* channel) const; 31 | 32 | static Poller* newDefaultPoller(EventLoop* loop); 33 | 34 | void assertInLoopThread() const { 35 | ownerLoop_->assertInLoopThread(); 36 | } 37 | protected: 38 | typedef std::map ChannelMap; 39 | ChannelMap channels_; 40 | 41 | private: 42 | EventLoop* ownerLoop_; 43 | 44 | };// end class Poller 45 | }// end namespace net 46 | }// end namespace muduo; 47 | 48 | #endif //CALM_NET_POLLER_H_ -------------------------------------------------------------------------------- /third/muduo-win/src/net/Poller/DefaultPoller.cc: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Copyright(C) 2016, gjm_kevin. All rights reserved. 4 | // Author : gjm_kevin@163.com 5 | // Date : 2016.09.13 6 | // 7 | ////////////////////////////////////////////////////////////////////////// 8 | 9 | #include "Poller.h" 10 | #include "SelectPoller.h" 11 | 12 | #include 13 | 14 | using namespace muduo::net; 15 | 16 | Poller* Poller::newDefaultPoller(EventLoop* loop) 17 | { 18 | if (1) 19 | { 20 | return new SelectPoller(loop); 21 | } 22 | } -------------------------------------------------------------------------------- /third/muduo-win/src/net/Poller/SelectPoller.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Copyright(C) 2016, gjm_kevin. All rights reserved. 4 | // Author : gjm_kevin@163.com 5 | // Date : 2016.09.13 6 | // 7 | ////////////////////////////////////////////////////////////////////////// 8 | #ifndef CALM_NET_SELECT_POLLER_H_ 9 | #define CALM_NET_SELECT_POLLER_H_ 10 | #include "Poller.h" 11 | #include 12 | struct pollfd; 13 | namespace muduo 14 | { 15 | namespace net 16 | { 17 | class SelectPoller :public Poller 18 | { 19 | public: 20 | SelectPoller(EventLoop* loop); 21 | virtual ~SelectPoller(); 22 | 23 | virtual Timestamp poll(int timeoutMs, ChannelList* activeChannels); 24 | virtual void updateChannel(Channel* channel); 25 | virtual void removeChannel(Channel* channel); 26 | private: 27 | void fillActiveChannels(int numEvents, ChannelList* activeChannels) const; 28 | 29 | typedef std::vector PollFdList; 30 | PollFdList pollfds_; 31 | fd_set rfds_; 32 | fd_set wfds_; 33 | fd_set efds_; 34 | };// end class SelectPoller 35 | }// end namespace net 36 | }// end namespace muduo 37 | 38 | #endif //CALM_NET_SELECT_POLLER_H_ 39 | 40 | 41 | -------------------------------------------------------------------------------- /third/muduo-win/src/net/Socket.cc: -------------------------------------------------------------------------------- 1 | #include "SocketsOps.h" 2 | #include "Socket.h" 3 | #include "logging.h" 4 | #include "InetAddress.h" 5 | 6 | using namespace muduo; 7 | using namespace muduo::net; 8 | 9 | Socket::~Socket() 10 | { 11 | sockets::close(sockfd_); 12 | } 13 | void Socket::bindAddress(const InetAddress& localaddr) 14 | { 15 | sockets::bindOrDie(sockfd_,localaddr.getSockAddr()); 16 | } 17 | void Socket::listen() 18 | { 19 | sockets::listenOrDie(sockfd_); 20 | } 21 | int Socket::accept(InetAddress* peeraddr) 22 | { 23 | struct sockaddr_in6 addr; 24 | memset(&addr, 0, sizeof(addr)); 25 | int connfd = sockets::accept(sockfd_, &addr); 26 | if (connfd > 0) 27 | { 28 | peeraddr->setSockAddrInet6(addr); 29 | } 30 | return connfd; 31 | } 32 | 33 | void Socket::shutdownWrite() 34 | { 35 | sockets::shutdownWrite(sockfd_); 36 | } 37 | 38 | void Socket::setTcpNoDelay(bool on) 39 | { 40 | int optval = on ? 1 : 0; 41 | ::setsockopt(sockfd_, IPPROTO_TCP, TCP_NODELAY, (char*)&optval, sizeof(optval)); 42 | } 43 | void Socket::setReuseAddr(bool on) 44 | { 45 | int optval = on ? 1 : 0; 46 | ::setsockopt(sockfd_, SOL_SOCKET, SO_REUSEADDR, (char*)&optval, sizeof(optval)); 47 | } 48 | void Socket::setReusePort(bool on) 49 | { 50 | #ifdef SO_REUSEPORT 51 | int optval = on ? 1 : 0; 52 | int ret = ::setsockopt(sockfd_, SOL_SOCKET, SO_REUSEPORT, 53 | &optval, static_cast(sizeof optval)); 54 | if (ret < 0 && on) 55 | { 56 | LOG_SYSERR << "SO_REUSEPORT failed."; 57 | } 58 | #else 59 | if (on) 60 | { 61 | //LOG_ERROR << "SO_REUSEPORT is not supported."; 62 | ; 63 | } 64 | #endif 65 | } 66 | 67 | void Socket::setKeepAlive(bool on) 68 | { 69 | int optval = on ? 1 : 0; 70 | ::setsockopt(sockfd_, SOL_SOCKET, SO_KEEPALIVE, (char*)&optval, sizeof(optval)); 71 | } -------------------------------------------------------------------------------- /third/muduo-win/src/net/Socket.h: -------------------------------------------------------------------------------- 1 | #ifndef CALM_NET_SOCKET_H_ 2 | #define CALM_NET_SOCKET_H_ 3 | #include "uncopyable.h" 4 | namespace muduo 5 | { 6 | namespace net 7 | { 8 | class InetAddress; 9 | 10 | class Socket :muduo::uncopyable 11 | { 12 | public: 13 | explicit Socket(int sockfd) 14 | :sockfd_(sockfd) 15 | {} 16 | ~Socket(); 17 | int fd() const { return sockfd_; } 18 | void bindAddress(const InetAddress& localaddr); 19 | void listen(); 20 | int accept(InetAddress* peeraddr); 21 | 22 | void shutdownWrite(); 23 | void setTcpNoDelay(bool on); 24 | void setReuseAddr(bool on); 25 | void setReusePort(bool on); 26 | void setKeepAlive(bool on); 27 | 28 | 29 | private: 30 | const int sockfd_; 31 | }; 32 | } 33 | }// end namespace muduo 34 | 35 | #endif //CALM_NET_SOCKET_H_ -------------------------------------------------------------------------------- /third/muduo-win/src/net/SocketsOps.h: -------------------------------------------------------------------------------- 1 | #ifndef CALM_NET_SOCKETSOPS_H_ 2 | #define CALM_NET_SOCKETSOPS_H_ 3 | 4 | #include 5 | #include 6 | 7 | #ifdef _MSC_VER 8 | #include 9 | typedef SSIZE_T ssize_t; 10 | // sockets 11 | #ifndef WIN32_LEAN_AND_MEAN 12 | #define WIN32_LEAN_AND_MEAN 13 | #endif 14 | #include 15 | #include 16 | #include 17 | #endif // _MSC_VER 18 | #ifndef _MSC_VER 19 | #define IOV_TYPE struct iovec 20 | #define IOV_PTR_FIELD iov_base 21 | #define IOV_LEN_FIELD iov_len 22 | #define IOV_LEN_TYPE size_t 23 | #else 24 | #define NUM_WRITE_IOVEC 16 25 | #define IOV_TYPE WSABUF 26 | #define IOV_PTR_FIELD buf 27 | #define IOV_LEN_FIELD len 28 | #define IOV_LEN_TYPE unsigned long 29 | #endif 30 | typedef struct _stPipe 31 | { 32 | int pipe_read; 33 | int pipe_write; 34 | }stPipe; 35 | 36 | namespace muduo 37 | { 38 | namespace net 39 | { 40 | namespace sockets 41 | { 42 | int createNoneblockOrDie(int family); 43 | int createOrDie(int family); 44 | int connect(int socketfd, const struct sockaddr* addr); 45 | void bindOrDie(int sockfd, const struct sockaddr* addr); 46 | void listenOrDie(int sockfd); 47 | 48 | int accept(int sockfd, struct sockaddr_in6* addr); 49 | 50 | ssize_t read(int sockfd, void *buf, size_t count); 51 | ssize_t write(int sockfd, const void* buf, size_t count); 52 | ssize_t readv(int sockfd, IOV_TYPE *iov, int iovcnt); 53 | 54 | void close(int sockfd); 55 | void shutdownWrite(int sockfd); 56 | void toIpPort(char* buf, size_t size,const struct sockaddr* addr); 57 | void toIp(char* buf, size_t size, const struct sockaddr* addr); 58 | 59 | void fromIpPort(const char* ip, uint16_t port, struct sockaddr_in* addr); 60 | 61 | int getSocketError(int sockfd); 62 | 63 | //const struct sockaddr* sockaddr_cast(const struct sockaddr_in* addr) ; 64 | //const struct sockaddr_in* sockaddr_in_cast(const struct sockaddr* addr) ; 65 | //struct sockaddr* sockaddr_cast(struct sockaddr_in* addr); 66 | //struct sockaddr_in* sockaddr_in_cast(struct sockaddr* addr); 67 | 68 | const struct sockaddr* sockaddr_cast(const struct sockaddr_in* addr); 69 | const struct sockaddr* sockaddr_cast(const struct sockaddr_in6* addr); 70 | struct sockaddr* sockaddr_cast(struct sockaddr_in6* addr); 71 | struct sockaddr* sockaddr_cast(struct sockaddr_in* addr); 72 | const struct sockaddr_in* sockaddr_in_cast(const struct sockaddr* addr); 73 | const struct sockaddr_in6* sockaddr_in6_cast(const struct sockaddr* addr); 74 | 75 | struct sockaddr_in6 getLocalAddr(int sockfd); 76 | struct sockaddr_in6 getPeerAddr(int sockfd); 77 | 78 | bool isSelfConnect(int sockfd); 79 | int pipe(int fildes[2]); 80 | stPipe pipe(); 81 | }// end namespace sockets 82 | }// end namespace net 83 | }// end namespace muduo 84 | 85 | #endif //CALM_NET_SOCKETSOPS_H_ -------------------------------------------------------------------------------- /third/muduo-win/src/net/TcpClient.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Copyright(C) 2016, gjm_kevin. All rights reserved. 4 | // Author : gjm_kevin@163.com 5 | // 6 | ////////////////////////////////////////////////////////////////////////// 7 | #ifndef CALM_NET_TCPCLIENT_H_ 8 | #define CALM_NET_TCPCLIENT_H_ 9 | #include "uncopyable.h" 10 | #include 11 | #include "TcpConnection.h" 12 | 13 | namespace muduo 14 | { 15 | namespace net 16 | { 17 | class Connector; 18 | typedef std::shared_ptr ConnectorPtr; 19 | 20 | class TcpClient :muduo::uncopyable 21 | { 22 | public: 23 | TcpClient(EventLoop*loop, 24 | const InetAddress& serverAddr, 25 | const string& nameArg); 26 | ~TcpClient(); 27 | 28 | void connect(); 29 | void disconnect(); 30 | void stop(); 31 | 32 | TcpConnectionPtr connection() const 33 | { 34 | std::unique_lock lck(mutex_); 35 | return connection_; 36 | } 37 | 38 | EventLoop* getLoop() const { return loop_; } 39 | bool retry() const { return retry_; } 40 | void enableRetry() { retry_ = true; } 41 | const string& name() const { return name_; } 42 | 43 | /// Not thread safe. 44 | void setConnectionCallback(const ConnectionCallback& cb) { connectionCallback_ = cb; } 45 | void setMessageCallback(const MessageCallback& cb) { messageCallback_ = cb; } 46 | void setWriteCompleteCallback_(const WriteCompleteCallback& cb) { writeCompleteCallback_ = cb; } 47 | private: 48 | /// Not thread safe, but in loop 49 | void newConnection(int sockfd); 50 | /// Not thread safe, but in loop 51 | void removeConnection(const TcpConnectionPtr& conn); 52 | 53 | EventLoop* loop_; 54 | ConnectorPtr connector_; 55 | const string name_; 56 | ConnectionCallback connectionCallback_; 57 | MessageCallback messageCallback_; 58 | WriteCompleteCallback writeCompleteCallback_; 59 | bool retry_; 60 | bool connect_; 61 | int nextConnId_; 62 | mutable std::mutex mutex_; 63 | TcpConnectionPtr connection_; 64 | 65 | };//end class TcpClient 66 | }// end namespace net 67 | }// end namespace muduo 68 | 69 | #endif //CALM_NET_TCPCLIENT_H_ -------------------------------------------------------------------------------- /third/muduo-win/src/net/TcpServer.cc: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Copyright(C) 2016, gjm_kevin. All rights reserved. 4 | // Author : gjm_kevin@163.com 5 | // 6 | ////////////////////////////////////////////////////////////////////////// 7 | #include "TcpServer.h" 8 | 9 | 10 | using namespace muduo; 11 | using namespace muduo::net; 12 | 13 | TcpServer::TcpServer(EventLoop* loop, const InetAddress& listenAddr,const string& nameArg, Option option /* = kNoReusePort */) 14 | :loop_(CHECK_NOTNULL(loop)), 15 | ipPort_(listenAddr.toIpPort()), 16 | name_(nameArg), 17 | acceptor_(new Acceptor(loop,listenAddr,option==kReusePort)), 18 | threadPool_(new EventLoopThreadPool(loop, nameArg)), 19 | connectionCallback_(defaultConnectionCallback), 20 | messageCallback_(defaultMessageCallback), 21 | nextConnId_(1), 22 | started_(false) 23 | { 24 | acceptor_->setNewConnectionCallback(std::bind(&TcpServer::newConnection, this, std::placeholders::_1, std::placeholders::_2)); 25 | } 26 | 27 | TcpServer::~TcpServer() 28 | { 29 | loop_->assertInLoopThread(); 30 | LOG_TRACE << "TcpServer::~TcpServer [" << name_<<"] dtor"; 31 | for (ConnectionMap::iterator it(connections_.begin()); it != connections_.end(); ++it) 32 | { 33 | TcpConnectionPtr conn = it->second; 34 | it->second.reset(); 35 | conn->getLoop()->runInLoop( 36 | std::bind(&TcpConnection::connectDestroyed, conn)); 37 | conn.reset(); 38 | } 39 | } 40 | void TcpServer::setThreadNum(int numThreads) 41 | { 42 | //assert(0 <= numThreads); 43 | threadPool_->setThreadNum(numThreads); 44 | } 45 | void TcpServer::start() 46 | { 47 | if (!started_) 48 | { 49 | started_ = true; 50 | threadPool_->start(threadInitCallback_); 51 | //assert(!acceptor_->listenning()); 52 | loop_->runInLoop(std::bind(&Acceptor::listen,acceptor_.get())); 53 | } 54 | } 55 | void TcpServer::newConnection(int sockfd, const InetAddress& peerAddr) 56 | { 57 | loop_->assertInLoopThread(); 58 | EventLoop* ioLoop = threadPool_->getNextLoop(); 59 | char buf[64]; 60 | snprintf(buf, sizeof buf, "-%s#%d", ipPort_.c_str(), nextConnId_); 61 | ++nextConnId_; 62 | string connName = name_ + buf; 63 | LOG_INFO << "TcpServer::newConnection ["<setConnectionCallback(connectionCallback_); 69 | conn->setMessageCallback(messageCallback_); 70 | conn->setWriteCompleteCallback(writeCompleteCallback_); 71 | conn->setCloseCallback(std::bind(&TcpServer::removeConnection, this, std::placeholders::_1)); 72 | 73 | ioLoop->runInLoop(std::bind(&TcpConnection::connectEstablished, conn)); 74 | } 75 | 76 | void TcpServer::removeConnection(const TcpConnectionPtr& conn) 77 | { 78 | loop_->runInLoop(std::bind(&TcpServer::removeConnectionInLoop, this, conn)); 79 | } 80 | void TcpServer::removeConnectionInLoop(const TcpConnectionPtr& conn) 81 | { 82 | loop_->assertInLoopThread(); 83 | LOG_INFO << "TcpServer::removeConnectionInLoop [" << name_ << "] - connection " << conn->name(); 84 | size_t n = connections_.erase(conn->name()); 85 | (void)n; 86 | //assert(n == 1); 87 | EventLoop* ioLoop = conn->getLoop(); 88 | ioLoop->queueInLoop(std::bind(&TcpConnection::connectDestroyed, conn)); 89 | 90 | } -------------------------------------------------------------------------------- /third/muduo-win/src/net/TcpServer.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Copyright(C) 2016, gjm_kevin. All rights reserved. 4 | // Author : gjm_kevin@163.com 5 | // 6 | ////////////////////////////////////////////////////////////////////////// 7 | #ifndef CALM_NET_TCPSERVER_H_ 8 | #define CALM_NET_TCPSERVER_H_ 9 | #pragma warning(disable : 4996) 10 | 11 | #include "SocketsOps.h" 12 | #include "EventLoopThreadPool.h" 13 | #include "EventLoop.h" 14 | #include "logging.h" 15 | #include "Acceptor.h" 16 | #include "TcpConnection.h" 17 | 18 | #include "uncopyable.h" 19 | #include "types.h" 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | namespace muduo 26 | { 27 | namespace net 28 | { 29 | class Acceptor; 30 | class EventLoop; 31 | class EventLoopThreadPool; 32 | /// 33 | /// TCP server, supports single-threaded and thread-pool models. 34 | /// 35 | /// This is an interface class, so don't expose too much details. 36 | class TcpServer :muduo::uncopyable 37 | { 38 | public: 39 | typedef std::function ThreadInitCallback; 40 | enum Option 41 | { 42 | kNoReusePort, 43 | kReusePort, 44 | }; 45 | TcpServer(EventLoop* loop, 46 | const InetAddress& listenAddr, 47 | const string& nameArg, 48 | Option option = kNoReusePort); 49 | ~TcpServer(); 50 | const string& ipPort()const { return ipPort_; } 51 | EventLoop* getLoop() const { return loop_; } 52 | 53 | ///set the number of threads for handling input. 54 | /// 55 | /// Always accepts new connection in loop's thread. 56 | /// Must be called before @c start 57 | /// @param numThreads 58 | /// - 0 means all I/O in loop's thread, no thread will created. 59 | /// this is the default value. 60 | /// - 1 means all I/O in another thread. 61 | /// - N means a thread pool with N threads, new connections 62 | /// are assigned on a round-robin basis. 63 | void setThreadNum(int numThreads); 64 | void setThreadInitCallback(const ThreadInitCallback& cb) { threadInitCallback_ = cb; } 65 | 66 | std::shared_ptr threadPool() { return threadPool_; } 67 | 68 | ///Starts the server if it's not listening. 69 | ///It's harmless to call it multiple times. 70 | ///Thread safe 71 | void start(); 72 | 73 | /// set callbacks 74 | void setConnectionCallback(const ConnectionCallback& cb) { connectionCallback_ = cb; } 75 | void setMessageCallback(const MessageCallback& cb) { messageCallback_ = cb; } 76 | void setWriteCompleteCallback(const WriteCompleteCallback& cb) { writeCompleteCallback_ = cb; } 77 | private: 78 | 79 | ///Not thread safe, but in loop 80 | void newConnection(int sockfd, const InetAddress& peerAddr); 81 | ///Thread safe 82 | void removeConnection(const TcpConnectionPtr& conn); 83 | ///Not thread safe, but in loop 84 | void removeConnectionInLoop(const TcpConnectionPtr& conn); 85 | 86 | typedef std::map ConnectionMap; 87 | 88 | EventLoop * loop_; 89 | const string ipPort_; 90 | const string name_; 91 | std::shared_ptr acceptor_; 92 | std::shared_ptr threadPool_; 93 | ConnectionCallback connectionCallback_; 94 | MessageCallback messageCallback_; 95 | WriteCompleteCallback writeCompleteCallback_; 96 | ThreadInitCallback threadInitCallback_; 97 | int nextConnId_; 98 | bool started_; 99 | ConnectionMap connections_; 100 | 101 | 102 | };// end class TcpServer 103 | }// end namespace net 104 | }// end namespace muduo 105 | 106 | #endif //CALM_NET_TCPSERVER_H_ -------------------------------------------------------------------------------- /third/muduo-win/src/net/Timer.cc: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Copyright(C) 2016, gjm_kevin. All rights reserved. 4 | // Author : gjm_kevin@163.com 5 | // 6 | ////////////////////////////////////////////////////////////////////////// 7 | #include "Timer.h" 8 | using namespace muduo; 9 | using namespace muduo::net; 10 | std::atomic_int64_t Timer::s_numCreated_ = 0; 11 | 12 | void Timer::restart(Timestamp now) 13 | { 14 | if (repeat_) 15 | { 16 | expiration_ = addTime(now, interval_); 17 | } 18 | else 19 | { 20 | expiration_ = Timestamp::invalid(); 21 | } 22 | } -------------------------------------------------------------------------------- /third/muduo-win/src/net/Timer.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Copyright(C) 2016, gjm_kevin. All rights reserved. 4 | // Author : gjm_kevin@163.com 5 | // 6 | ////////////////////////////////////////////////////////////////////////// 7 | #ifndef CALM_NET_TIMER_H_ 8 | #define CALM_NET_TIMER_H_ 9 | #include "uncopyable.h" 10 | #include "timestamp.h" 11 | #include "Callbacks.h" 12 | 13 | #include 14 | 15 | namespace muduo 16 | { 17 | namespace net 18 | { 19 | class Timer :muduo::uncopyable 20 | { 21 | public: 22 | Timer(const TimerCallback& cb, Timestamp when, double interval) 23 | :callback_(cb), 24 | expiration_(when), 25 | interval_(interval), 26 | repeat_(interval > 0.0), 27 | sequence_(s_numCreated_++) 28 | {} 29 | void run() const 30 | { 31 | if(callback_)callback_(); 32 | } 33 | void restart(Timestamp now); 34 | 35 | Timestamp expiration() const { return expiration_; } 36 | bool repeat() const { return repeat_; } 37 | int64_t sequence() const { return sequence_; } 38 | static int64_t numCreated() { return s_numCreated_; } 39 | int min_heap_idx; 40 | private: 41 | const TimerCallback callback_; 42 | Timestamp expiration_; 43 | const double interval_; 44 | const bool repeat_; 45 | const int64_t sequence_; 46 | 47 | static std::atomic_int64_t s_numCreated_; 48 | };// end class Timer 49 | }// end namespace net 50 | }//end namespace muduo 51 | #endif //CALM_NET_TIMER_H_ -------------------------------------------------------------------------------- /third/muduo-win/src/net/TimerId.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Copyright(C) 2016, gjm_kevin. All rights reserved. 4 | // Author : gjm_kevin@163.com 5 | // 6 | ////////////////////////////////////////////////////////////////////////// 7 | #ifndef CALM_NET_TIMERID_H_ 8 | #define CALM_NET_TIMERID_H_ 9 | #include "copyable.h" 10 | #include "types.h" 11 | namespace muduo 12 | { 13 | namespace net 14 | { 15 | class Timer; 16 | class TimerId :muduo::copyable 17 | { 18 | public: 19 | TimerId() 20 | :timer_(NULL), 21 | sequence_(0) 22 | {} 23 | TimerId(Timer* timer,int64_t seq) 24 | :timer_(timer), 25 | sequence_(seq) 26 | {} 27 | // default copy-ctor, dtor and assignment are okay 28 | 29 | friend class TimerQueue; 30 | private: 31 | Timer* timer_; 32 | int64_t sequence_; 33 | }; 34 | }//end namespace net 35 | }// end namespace muduo 36 | #endif //CALM_NET_TIMERID_H_ -------------------------------------------------------------------------------- /third/muduo-win/src/net/TimerQueue.cc: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Copyright(C) 2016, gjm_kevin. All rights reserved. 4 | // Author : gjm_kevin@163.com 5 | // 6 | ////////////////////////////////////////////////////////////////////////// 7 | #include "EventLoop.h" 8 | #include "TimerQueue.h" 9 | #include "logging.h" 10 | #include "Timer.h" 11 | #include "TimerId.h" 12 | #include 13 | 14 | using namespace muduo; 15 | using namespace muduo::net; 16 | 17 | namespace 18 | { 19 | const int defaultOuttime = 100; 20 | const int defaultTimeout = 10000; 21 | } 22 | 23 | 24 | TimerQueue::TimerQueue(EventLoop* loop) 25 | :loop_(loop), 26 | timerSet_() 27 | { 28 | min_heap_ctor(&timeMinHeap_); 29 | } 30 | TimerQueue::~TimerQueue() 31 | { 32 | for (TimerSet::iterator it = timerSet_.begin(); 33 | it != timerSet_.end(); ++it) 34 | { 35 | delete *it; 36 | } 37 | min_heap_dtor(&timeMinHeap_); 38 | } 39 | TimerId TimerQueue::addTimer(const TimerCallback& cb, Timestamp when, double interval) 40 | { 41 | Timer* timer = new Timer(cb, when, interval); 42 | loop_->runInLoop(std::bind(&TimerQueue::addTimerInLoop, this, timer)); 43 | return TimerId(timer, timer->sequence()); 44 | } 45 | void TimerQueue::cancel(TimerId timerId) 46 | { 47 | loop_->runInLoop(std::bind(&TimerQueue::cancelInLoop, this, timerId)); 48 | } 49 | void TimerQueue::addTimerInLoop(Timer* timer) 50 | { 51 | loop_->assertInLoopThread(); 52 | Timestamp when = timer->expiration(); 53 | min_heap_push(&timeMinHeap_, timer); 54 | timerSet_.insert(timer); 55 | } 56 | void TimerQueue::cancelInLoop(TimerId timerId) 57 | { 58 | loop_->assertInLoopThread(); 59 | //FIXME:May run timeout func after cancel. Do not delete from PendingFunctors. 60 | //Memory not delete here, because we may use the pointer in PendingFunctors. 61 | min_heap_erase(&timeMinHeap_, timerId.timer_); 62 | //TimerSet::iterator it = timerSet_.find(timerId.timer_); 63 | //if (it != timerSet_.end()) 64 | //{ 65 | // timerSet_.erase(timerId.timer_); 66 | //} 67 | 68 | } 69 | 70 | void TimerQueue::expiredProcess(Timestamp now) 71 | { 72 | while (1) 73 | { 74 | Timer* timer = min_heap_top(&timeMinHeap_); 75 | if(!timer) 76 | break; 77 | if (timer->expiration().microSecondsSinceEpoch() > now.microSecondsSinceEpoch()) 78 | break; 79 | 80 | loop_->runInLoop(std::bind(&Timer::run,timer)); 81 | min_heap_pop(&timeMinHeap_); 82 | if (timer->repeat()) 83 | { 84 | timer->restart(now); 85 | min_heap_push(&timeMinHeap_, timer); 86 | } 87 | } 88 | } 89 | 90 | int TimerQueue::earliestExpiredTime(Timestamp now) 91 | { 92 | Timer* timer = min_heap_top(&timeMinHeap_); 93 | // No timer 94 | if (!timer) 95 | return defaultTimeout; 96 | if (timer->expiration().microSecondsSinceEpoch() > now.microSecondsSinceEpoch()) 97 | { 98 | return timeDifferenceMs( timer->expiration(),now); 99 | } 100 | // Already has timeout timer 101 | return defaultOuttime; 102 | } 103 | 104 | 105 | -------------------------------------------------------------------------------- /third/muduo-win/src/net/TimerQueue.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Copyright(C) 2016, gjm_kevin. All rights reserved. 4 | // Author : gjm_kevin@163.com 5 | // 6 | ////////////////////////////////////////////////////////////////////////// 7 | #ifndef CALM_NET_TIMERQUEUE_H_ 8 | #define CALM_NET_TIMERQUEUE_H_ 9 | 10 | #include "TimeMinHeap.h" 11 | #include "uncopyable.h" 12 | #include "timestamp.h" 13 | #include "Callbacks.h" 14 | 15 | #include 16 | 17 | namespace muduo 18 | { 19 | namespace net 20 | { 21 | class EventLoop; 22 | class Timer; 23 | class TimerId; 24 | 25 | class TimerQueue:muduo::uncopyable 26 | { 27 | public: 28 | TimerQueue(EventLoop* loop); 29 | ~TimerQueue(); 30 | 31 | TimerId addTimer(const TimerCallback& cb, 32 | Timestamp when, 33 | double interval); 34 | 35 | void cancel(TimerId timerId); 36 | 37 | void expiredProcess(Timestamp now); 38 | int earliestExpiredTime(Timestamp now); 39 | private: 40 | typedef std::set TimerSet; 41 | 42 | void addTimerInLoop(Timer* timer); 43 | void cancelInLoop(TimerId timerId); 44 | 45 | 46 | 47 | /* void reset(const std::vector& expired, Timestamp now); 48 | bool insert(Timer* timer);*/ 49 | 50 | EventLoop* loop_; 51 | min_heap_t timeMinHeap_; 52 | TimerSet timerSet_; 53 | bool callingExpiredTimers_; 54 | };// end class TimerQueue 55 | }//end namespace net 56 | }//end namespace muduo 57 | #endif //CALM_NET_TIMERQUEUE_H_ -------------------------------------------------------------------------------- /third/muduo-win/src/net/poll.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 1997-2014 Free Software Foundation, Inc. 2 | This file is part of the GNU C Library. 3 | 4 | The GNU C Library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | The GNU C Library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with the GNU C Library; if not, see 16 | . */ 17 | 18 | 19 | // delete some pre-compiler option 20 | 21 | /* Event types that can be polled for. These bits may be set in `events' 22 | to indicate the interesting event types; they will appear in `revents' 23 | to indicate the status of the file descriptor. */ 24 | 25 | /* release definitions for WSAPoll(). */ 26 | #ifdef POLLIN 27 | #undef POLLIN 28 | #endif 29 | #define POLLIN 0x001 /* There is data to read. */ 30 | 31 | #ifdef POLLPRI 32 | #undef POLLPRI 33 | #endif 34 | #define POLLPRI 0x002 /* There is urgent data to read. */ 35 | 36 | #ifdef POLLOUT 37 | #undef POLLOUT 38 | #endif 39 | #define POLLOUT 0x004 /* Writing now will not block. */ 40 | 41 | 42 | /* These values are defined in XPG4.2. */ 43 | #ifdef POLLRDNORM 44 | #undef POLLRDNORM 45 | #endif 46 | # define POLLRDNORM 0x040 /* Normal data may be read. */ 47 | 48 | #ifdef POLLRDBAND 49 | #undef POLLRDBAND 50 | #endif 51 | # define POLLRDBAND 0x080 /* Priority data may be read. */ 52 | 53 | #ifdef POLLWRNORM 54 | #undef POLLWRNORM 55 | #endif 56 | # define POLLWRNORM 0x100 /* Writing now will not block. */ 57 | 58 | #ifdef POLLWRBAND 59 | #undef POLLWRBAND 60 | #endif 61 | # define POLLWRBAND 0x200 /* Priority data may be written. */ 62 | 63 | 64 | 65 | /* These are extensions for Linux. */ 66 | #ifdef POLLMSG 67 | #undef POLLMSG 68 | #endif 69 | # define POLLMSG 0x400 70 | 71 | #ifdef POLLREMOVE 72 | #undef POLLREMOVE 73 | #endif 74 | # define POLLREMOVE 0x1000 75 | 76 | #ifdef POLLRDHUP 77 | #undef POLLRDHUP 78 | #endif 79 | # define POLLRDHUP 0x2000 80 | 81 | /* Event types always implicitly polled for. These bits need not be set in 82 | `events', but they will appear in `revents' to indicate the status of 83 | the file descriptor. */ 84 | #ifdef POLLERR 85 | #undef POLLERR 86 | #endif 87 | #define POLLERR 0x008 /* Error condition. */ 88 | 89 | #ifdef POLLHUP 90 | #undef POLLHUP 91 | #endif 92 | #define POLLHUP 0x010 /* Hung up. */ 93 | 94 | #ifdef POLLNVAL 95 | #undef POLLNVAL 96 | #endif 97 | #define POLLNVAL 0x020 /* Invalid polling request. */ 98 | 99 | -------------------------------------------------------------------------------- /third/muduo-win/src/test/ThreadPool_test.cc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/no5ix/realtinet/f940677ee7a563291b0071d31cdd952ab8b9566d/third/muduo-win/src/test/ThreadPool_test.cc -------------------------------------------------------------------------------- /third/muduo-win/src/test/acceptor_test.cc: -------------------------------------------------------------------------------- 1 | #include "EventLoop.h" 2 | #include "Acceptor.h" 3 | #include "InetAddress.h" 4 | #include "logging.h" 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace muduo; 10 | using namespace muduo::net; 11 | 12 | void newConnection(int sockfd,const InetAddress& peerAddr) 13 | { 14 | LOG_INFO << "new connection from " << peerAddr.toIpPort(); 15 | // can not use write in windows socket. use send 16 | sockets::write(sockfd, "hello muduo\r\n", strlen("hello muduo\r\n")); 17 | sockets::close(sockfd); 18 | LOG_INFO << "close"; 19 | } 20 | 21 | int main_acceptor() 22 | { 23 | LOG_INFO << "main threadId = " << getCurrentThreadId(); 24 | 25 | InetAddress listenAddr(2016); 26 | EventLoop loop; 27 | Acceptor acceptor(&loop, listenAddr, true); 28 | acceptor.setNewConnectionCallback(newConnection); 29 | acceptor.listen(); 30 | loop.loop(); 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /third/muduo-win/src/test/async_logging_test.cc: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | 11 | 12 | 13 | int kRollSize = 500 * 1024 * 1024; 14 | 15 | muduo::AsyncLogging* g_asyncLog = NULL; 16 | 17 | void asyncOutput(const char* msg, int len) 18 | { 19 | g_asyncLog->append(msg, len); 20 | } 21 | 22 | void bench(bool longLog) 23 | { 24 | muduo::Logger::setOutput(asyncOutput); 25 | 26 | int cnt = 0; 27 | const int kBatch = 1000; 28 | muduo::string empty = " "; 29 | muduo::string longStr(3000, 'X'); 30 | longStr += " "; 31 | 32 | for (int t = 0; t < 30; ++t) 33 | { 34 | muduo::Timestamp start = muduo::Timestamp::now(); 35 | for (int i = 0; i < kBatch; ++i) 36 | { 37 | LOG_INFO << "Hello 0123456789" << " abcdefghijklmnopqrstuvwxyz " 38 | << (longLog ? longStr : empty) 39 | << cnt; 40 | ++cnt; 41 | } 42 | muduo::Timestamp end = muduo::Timestamp::now(); 43 | printf("%f\n", timeDifferenceSeconds(end, start) * 1000000 / kBatch); 44 | std::this_thread::sleep_for(std::chrono::milliseconds(1000)); 45 | } 46 | } 47 | 48 | int main1(int argc, char* argv[]) 49 | { 50 | //{ 51 | // // set max virtual memory to 2GB. 52 | // size_t kOneGB = 1000 * 1024 * 1024; 53 | // rlimit rl = { 2 * kOneGB, 2 * kOneGB }; 54 | // setrlimit(RLIMIT_AS, &rl); 55 | //} 56 | 57 | // printf("pid = %d\n", getpid()); 58 | 59 | char name[256]; 60 | strncpy(name, argv[0], 256); 61 | muduo::AsyncLogging log("kevin_ming", kRollSize); 62 | log.start(); 63 | g_asyncLog = &log; 64 | 65 | bool longLog = true; 66 | bench(longLog); 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /third/muduo-win/src/test/config_file_read_test.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace muduo; 4 | 5 | int main2() 6 | { 7 | //E:\muduo\src\build\muduo\Debug\muduo.exe 8 | ConfigFileReader config_file("E:\\muduo\\src\\build\\muduo\\Debug\\msgserver.conf"); 9 | 10 | char* listen_ip = config_file.GetConfigName("ListenIP"); 11 | char* str_listen_port = config_file.GetConfigName("ListenPort"); 12 | char* ip_addr1 = config_file.GetConfigName("IpAddr1"); 13 | char* ip_addr2 = config_file.GetConfigName("IpAddr2"); 14 | char* str_max_conn_cnt = config_file.GetConfigName("MaxConnCnt"); 15 | char* str_aes_key = config_file.GetConfigName("aesKey"); 16 | return 0; 17 | } -------------------------------------------------------------------------------- /third/muduo-win/src/test/connector_test.cc: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Copyright(C) 2016, gjm_kevin. All rights reserved. 4 | // Author : gjm_kevin@163.com 5 | // 6 | ////////////////////////////////////////////////////////////////////////// 7 | 8 | #include "Connector.h" 9 | #include "EventLoop.h" 10 | #include "logging.h" 11 | #include 12 | #include 13 | 14 | using namespace muduo; 15 | using namespace muduo::net; 16 | 17 | EventLoop * g_loop_connector; 18 | 19 | void connectCallback(int sockfd) 20 | { 21 | LOG_INFO << "connected"; 22 | g_loop_connector->quit(); 23 | } 24 | 25 | int main_connector() 26 | { 27 | EventLoop loop; 28 | g_loop_connector = &loop; 29 | 30 | InetAddress serverAddr("192.168.255.130", 2000); 31 | std::shared_ptr conn(new Connector(&loop, serverAddr)); 32 | conn->setNewConnectionCallback(connectCallback); 33 | conn->start(); 34 | 35 | loop.loop(); 36 | std::cin.get(); 37 | return 0; 38 | } -------------------------------------------------------------------------------- /third/muduo-win/src/test/echoclient_test.cc: -------------------------------------------------------------------------------- 1 | //#include 2 | // 3 | //#include 4 | //#include 5 | //#include 6 | //#include 7 | 8 | 9 | 10 | //#include "EventLoopThread.h" 11 | 12 | #include 13 | //#include 14 | //#include "logging.h"" 15 | #include 16 | 17 | //#include 18 | #include 19 | //#include 20 | 21 | //#include 22 | 23 | //#include 24 | //#include 25 | 26 | using namespace muduo; 27 | using namespace muduo::net; 28 | 29 | int numThreads = 0; 30 | class EchoClient; 31 | std::vector> clients; 32 | int current = 0; 33 | 34 | class EchoClient 35 | { 36 | public: 37 | EchoClient(EventLoop* loop, const InetAddress& listenAddr, const string& id) 38 | : loop_(loop), 39 | client_(loop, listenAddr, "EchoClient" + id) 40 | { 41 | client_.setConnectionCallback( 42 | std::bind(&EchoClient::onConnection, this, std::placeholders::_1)); 43 | client_.setMessageCallback( 44 | std::bind(&EchoClient::onMessage, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); 45 | //client_.enableRetry(); 46 | } 47 | 48 | void connect() 49 | { 50 | client_.connect(); 51 | } 52 | // void stop(); 53 | 54 | private: 55 | void onConnection(const TcpConnectionPtr& conn) 56 | { 57 | //LOG_TRACE << conn->localAddress().toIpPort() << " -> " 58 | // << conn->peerAddress().toIpPort() << " is " 59 | // << (conn->connected() ? "UP" : "DOWN"); 60 | 61 | if (conn->connected()) 62 | { 63 | ++current; 64 | if (implicit_cast(current) < clients.size()) 65 | { 66 | clients[current]->connect(); 67 | } 68 | //LOG_INFO << "*** connected " << current; 69 | } 70 | conn->send("world "); 71 | } 72 | 73 | void onMessage(const TcpConnectionPtr& conn, Buffer* buf, Timestamp time) 74 | { 75 | string msg(buf->retrieveAllAsString()); 76 | //LOG_TRACE << conn->name() << " recv " << msg.size() << " bytes at " << time.toString(); 77 | LOG_INFO << conn->name() << " recv " << msg; 78 | 79 | if (msg == "quit\n") 80 | { 81 | conn->send("bye\n"); 82 | conn->shutdown(); 83 | } 84 | else if (msg == "shutdown\n") 85 | { 86 | loop_->quit(); 87 | } 88 | else 89 | { 90 | conn->send(msg); 91 | } 92 | } 93 | 94 | EventLoop* loop_; 95 | TcpClient client_; 96 | }; 97 | 98 | void massin(int argc, char* argv[]) 99 | //int main(int argc, char* argv[]) 100 | { 101 | //LOG_INFO << "pid = " << getpid() << ", tid = " << CurrentThread::tid(); 102 | //if (argc > 1) 103 | { 104 | EventLoop loop; 105 | //bool ipv6 = argc > 3; 106 | InetAddress serverAddr("127.0.0.1", 2000); 107 | 108 | int n = 5; 109 | if (argc > 2) 110 | { 111 | n = atoi(argv[2]); 112 | } 113 | 114 | clients.reserve(n); 115 | for (int i = 0; i < n; ++i) 116 | { 117 | char buf[32]; 118 | snprintf(buf, sizeof buf, "%d", i + 1); 119 | clients.emplace_back(new EchoClient(&loop, serverAddr, buf)); 120 | } 121 | 122 | clients[current]->connect(); 123 | loop.loop(); 124 | } 125 | //else 126 | //{ 127 | // printf("Usage: %s host_ip [current#]\n", argv[0]); 128 | //} 129 | } 130 | 131 | -------------------------------------------------------------------------------- /third/muduo-win/src/test/eventloop_test.cc: -------------------------------------------------------------------------------- 1 | #include "EventLoop.h" 2 | #include "logging.h" 3 | 4 | #include 5 | #include 6 | 7 | using namespace muduo; 8 | using namespace muduo::net; 9 | 10 | EventLoop *g_loop; 11 | void net_func() 12 | { 13 | LOG_INFO << "func:pid = " << getCurrentThreadId(); 14 | } 15 | void threadFunc() 16 | { 17 | Sleep(2000); 18 | LOG_INFO << "threadFunc:pid = " << getCurrentThreadId(); 19 | g_loop->runInLoop(net_func); 20 | } 21 | 22 | //int main() 23 | //{ 24 | // WSADATA Ws; 25 | // //Init Windows Socket 26 | // if (WSAStartup(MAKEWORD(2, 2), &Ws) != 0) 27 | // { 28 | // LOG_FATAL<< "Init Windows Socket Failed::" << GetLastError(); 29 | // return -1; 30 | // } 31 | // EventLoop loop; 32 | // g_loop = &loop; 33 | // std::thread th(threadFunc); 34 | // loop.loop(); 35 | // //std::cin.get(); 36 | // return 0; 37 | //} -------------------------------------------------------------------------------- /third/muduo-win/src/test/eventloopthread_test.cc: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Copyright(C) 2016, gjm_kevin. All rights reserved. 4 | // Author : gjm_kevin@163.com 5 | // 6 | ////////////////////////////////////////////////////////////////////////// 7 | #include "EventLoopThread.h" 8 | #include "EventLoop.h" 9 | #include "logging.h" 10 | #include "count_down_latch.h" 11 | 12 | using namespace muduo; 13 | using namespace muduo::net; 14 | 15 | void print(EventLoop* loop = NULL) 16 | { 17 | LOG_INFO << "threadId = " << getCurrentThreadId() << " loop = " << loop; 18 | } 19 | void quit(EventLoop* loop) 20 | { 21 | print(loop); 22 | loop->quit(); 23 | } 24 | 25 | int main_eventLoop() 26 | { 27 | print(); 28 | { 29 | EventLoopThread th1; 30 | } 31 | { 32 | EventLoopThread th2; 33 | EventLoop* loop = th2.startLoop(); 34 | loop->runInLoop(std::bind(print, loop)); 35 | std::this_thread::sleep_for(std::chrono::seconds(5)); 36 | } 37 | { 38 | EventLoopThread th3; 39 | EventLoop* loop = th3.startLoop(); 40 | loop->runInLoop(std::bind(quit, loop)); 41 | std::this_thread::sleep_for(std::chrono::seconds(5)); 42 | } 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /third/muduo-win/src/test/eventloopthreadpool_test.cc: -------------------------------------------------------------------------------- 1 | //#include "EventLoopThreadPool.h" 2 | //#include "EventLoop.h" 3 | //#include "thread.h" 4 | //#include "logging.h" 5 | //#include 6 | // 7 | //using namespace muduo; 8 | //using namespace muduo::net; 9 | // 10 | //void print_id(EventLoop* p = NULL) 11 | //{ 12 | // LOG_INFO << "print_id func: threadId = " << getCurrentThreadId() << " loop = " << p; 13 | //} 14 | //void init(EventLoop* p) 15 | //{ 16 | // LOG_INFO << "init func: threadId = " << getCurrentThreadId() << " loop = " << p; 17 | //} 18 | // 19 | //int main_eventloopthreadpool() 20 | //{ 21 | // print_id(); 22 | // EventLoop loop; 23 | // 24 | // { 25 | // LOG_INFO << "single thread : " << &loop; 26 | // EventLoopThreadPool model(&loop); 27 | // model.setThreadNum(0); 28 | // model.start(init); 29 | // assert(model.getNextLoop() == &loop); 30 | // assert(model.getNextLoop() == &loop); 31 | // assert(model.getNextLoop() == &loop); 32 | // std::this_thread::sleep_for(std::chrono::seconds(5)); 33 | // } 34 | // 35 | // { 36 | // LOG_INFO<<"Another thread"; 37 | // EventLoopThreadPool model(&loop); 38 | // model.setThreadNum(1); 39 | // model.start(init); 40 | // EventLoop* nextLoop = model.getNextLoop(); 41 | // nextLoop->queueInLoop(std::bind(print_id, nextLoop)); 42 | // assert(nextLoop != &loop); 43 | // assert(nextLoop == model.getNextLoop()); 44 | // assert(nextLoop == model.getNextLoop()); 45 | // std::this_thread::sleep_for(std::chrono::seconds(3)); 46 | // } 47 | // 48 | // { 49 | // LOG_INFO << "Three threads"; 50 | // EventLoopThreadPool model(&loop); 51 | // model.setThreadNum(3); 52 | // model.start(init); 53 | // EventLoop* nextLoop = model.getNextLoop(); 54 | // nextLoop->runInLoop(std::bind(print_id, nextLoop)); 55 | // assert(nextLoop != &loop); 56 | // assert(nextLoop != model.getNextLoop()); 57 | // assert(nextLoop != model.getNextLoop()); 58 | // assert(nextLoop == model.getNextLoop()); 59 | // } 60 | // 61 | // //loop.loop(); 62 | // return 0; 63 | //} -------------------------------------------------------------------------------- /third/muduo-win/src/test/log_file_test.cc: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | std::shared_ptr g_logFile; 8 | 9 | void outputFunc(const char* msg, int len) 10 | { 11 | g_logFile->append(msg, len); 12 | } 13 | 14 | void flushFunc() 15 | { 16 | g_logFile->flush(); 17 | } 18 | 19 | int main3(int argc, char* argv[]) 20 | { 21 | char name[256]; 22 | strncpy(name, argv[0], 256); 23 | g_logFile.reset(new muduo::LogFile("kevin", 200 * 1000)); 24 | muduo::Logger::setOutput(outputFunc); 25 | muduo::Logger::setFlush(flushFunc); 26 | 27 | std::string line = "1234567890 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ "; 28 | 29 | for (int i = 0; i < 10000; ++i) 30 | { 31 | LOG_INFO << line << i; 32 | 33 | std::this_thread::sleep_for(std::chrono::microseconds(500)); 34 | } 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /third/muduo-win/src/test/log_stream_bench.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #ifdef _MSC_VER 10 | #define snprintf sprintf_s 11 | #endif 12 | 13 | 14 | using namespace muduo; 15 | 16 | const size_t N = 1000000; 17 | 18 | 19 | 20 | template 21 | void benchPrintf(const char* fmt) 22 | { 23 | char buf[32]; 24 | Timestamp start(Timestamp::now()); 25 | for (size_t i = 0; i < N; ++i) 26 | snprintf(buf, sizeof buf, fmt, (T)(i)); 27 | Timestamp end(Timestamp::now()); 28 | 29 | printf("benchPrintf %f\n", timeDifferenceSeconds(end, start)); 30 | } 31 | 32 | template 33 | void benchStringStream() 34 | { 35 | Timestamp start(Timestamp::now()); 36 | std::ostringstream os; 37 | 38 | for (size_t i = 0; i < N; ++i) 39 | { 40 | os << (T)(i); 41 | os.seekp(0, std::ios_base::beg); 42 | } 43 | Timestamp end(Timestamp::now()); 44 | 45 | printf("benchStringStream %f\n", timeDifferenceSeconds(end, start)); 46 | } 47 | 48 | template 49 | void benchLogStream() 50 | { 51 | Timestamp start(Timestamp::now()); 52 | LogStream os; 53 | for (size_t i = 0; i < N; ++i) 54 | { 55 | os << (T)(i); 56 | os.resetBuffer(); 57 | } 58 | Timestamp end(Timestamp::now()); 59 | 60 | printf("benchLogStream %f\n", timeDifferenceSeconds(end, start)); 61 | } 62 | 63 | int main4() 64 | { 65 | std::cout << __FILE__ << std::endl; 66 | benchPrintf("%d"); 67 | 68 | puts("int"); 69 | benchPrintf("%d"); 70 | benchStringStream(); 71 | benchLogStream(); 72 | 73 | puts("double"); 74 | benchPrintf("%.12g"); 75 | benchStringStream(); 76 | benchLogStream(); 77 | 78 | puts("int64_t"); 79 | benchPrintf("%" PRId64); 80 | benchStringStream(); 81 | benchLogStream(); 82 | 83 | puts("void*"); 84 | benchPrintf("%p"); 85 | benchStringStream(); 86 | benchLogStream(); 87 | std::cin.get(); 88 | return 0; 89 | } -------------------------------------------------------------------------------- /third/muduo-win/src/test/logging_test.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int g_total; 7 | FILE* g_file; 8 | 9 | using namespace muduo; 10 | void dummyOutput(const char* msg, int len) 11 | { 12 | g_total += len; 13 | if (g_file) 14 | { 15 | fwrite(msg, 1, len, g_file); 16 | } 17 | } 18 | 19 | void bench(const char* type) 20 | { 21 | muduo::Logger::setOutput(dummyOutput); 22 | muduo::Timestamp start(muduo::Timestamp::now()); 23 | g_total = 0; 24 | 25 | int n = 1000 * 1000; 26 | const bool kLongLog = false; 27 | muduo::string empty = " "; 28 | muduo::string longStr(3000, 'X'); 29 | longStr += " "; 30 | for (int i = 0; i < n; ++i) 31 | { 32 | LOG_INFO << "Hello 0123456789" << " abcdefghijklmnopqrstuvwxyz" 33 | << (kLongLog ? longStr : empty) 34 | << i; 35 | } 36 | muduo::Timestamp end(muduo::Timestamp::now()); 37 | double seconds = timeDifferenceSeconds(end, start); 38 | printf("%12s: %f seconds, %d bytes, %10.2f msg/s, %.2f MiB/s\n", 39 | type, seconds, g_total, n / seconds, g_total / seconds / (1024 * 1024)); 40 | } 41 | 42 | void logInThread() 43 | { 44 | LOG_INFO << "logInThread"; 45 | std::this_thread::sleep_for(std::chrono::seconds(1)); 46 | } 47 | 48 | int main5() 49 | { 50 | 51 | muduo::ThreadPool pool("pool"); 52 | pool.start(5); 53 | pool.run(logInThread); 54 | pool.run(logInThread); 55 | pool.run(logInThread); 56 | pool.run(logInThread); 57 | pool.run(logInThread); 58 | 59 | LOG_TRACE << "trace"; 60 | LOG_DEBUG << "debug"; 61 | LOG_INFO << "Hello"; 62 | LOG_WARN << "World"; 63 | LOG_ERROR << "Error"; 64 | LOG_INFO << sizeof(muduo::Logger); 65 | LOG_INFO << sizeof(muduo::LogStream); 66 | LOG_INFO << sizeof(muduo::Fmt); 67 | LOG_INFO << sizeof(muduo::LogStream::Buffer); 68 | 69 | //g_file = stdout; 70 | bench("nop"); 71 | 72 | g_file = fopen("E:\\log", "w"); 73 | 74 | bench("E:\\log"); 75 | fclose(g_file); 76 | std::cin.get(); 77 | return 0; 78 | } -------------------------------------------------------------------------------- /third/muduo-win/src/test/min_heap_test.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "min_heap.h" 3 | 4 | int main_min_heap() 5 | { 6 | struct element *inserted[1024]; 7 | struct min_heap heap; 8 | min_heap_ctor(&heap,NULL); 9 | for (int i = 1023; i >= 0 ; --i) { 10 | inserted[i] = (struct element *)malloc(sizeof(struct element)); 11 | inserted[i]->value = malloc(sizeof(int)); 12 | *(int *)(inserted[i]->value) = i; 13 | min_heap_push(&heap, inserted[i]); 14 | } 15 | for (int i = 0; i < 512; ++i) { 16 | min_heap_erase(&heap, inserted[i]); 17 | } 18 | std::cout << "size = " << heap.size << std::endl; 19 | while (true) 20 | { 21 | struct element* p = (struct element *)min_heap_pop(&heap); 22 | if(!p) 23 | break; 24 | printf("%d,", *(int *)(p->value)); 25 | } 26 | for (int i = 0; i < 1024; ++i) 27 | { 28 | free(inserted[i]->value); 29 | free(inserted[i]); 30 | } 31 | min_heap_dtor(&heap); 32 | std::cin.get(); 33 | return 0; 34 | } -------------------------------------------------------------------------------- /third/muduo-win/src/test/security_test.cc: -------------------------------------------------------------------------------- 1 | #include "security/md5.h" 2 | #include "security/base64.h" 3 | #include "security/aes.h" 4 | #include 5 | #include 6 | #include 7 | 8 | int ggmain() 9 | { 10 | std::string str = "hello"; 11 | char md5[64] = { 0 }; 12 | MD5_Calculate(str.c_str(), str.length(), md5); 13 | std::cout << md5 << std::endl; 14 | std::cout << base64_encode(str) << std::endl; 15 | std::cout << base64_decode(base64_encode(str)) << std::endl; 16 | 17 | 18 | // code from https://github.com/bozhu/AES-C/tree/5a150c094c7efb3c76dedf58e174d42e7d757d8b 19 | int i; 20 | 21 | const unsigned char master_key[16] = { 22 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 23 | 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 24 | }; 25 | const unsigned char text[16] = { 26 | 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 27 | 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 28 | }; 29 | 30 | unsigned char encrypted[16], decrypted[16]; 31 | 32 | AES_KEY key; 33 | 34 | printf("plaintext:\n"); 35 | for (i = 0; i < 16; i++) { 36 | printf("%02x ", (unsigned int)text[i]); 37 | } 38 | printf("\n\n"); 39 | 40 | printf("encrypted:\n"); 41 | AES_set_encrypt_key(master_key, 128, &key); // 128 for 128-bit version AES 42 | AES_encrypt(text, encrypted, &key); 43 | for (i = 0; i < 16; i++) { 44 | printf("%02x ", (unsigned int)encrypted[i]); 45 | } 46 | printf("\n\n"); 47 | 48 | printf("decrypted:\n"); 49 | AES_set_decrypt_key(master_key, 128, &key); 50 | AES_decrypt(encrypted, decrypted, &key); 51 | for (i = 0; i < 16; i++) { 52 | printf("%02x ", (unsigned int)decrypted[i]); 53 | } 54 | printf("\n"); 55 | 56 | std::cin.get(); 57 | return 0; 58 | } -------------------------------------------------------------------------------- /third/muduo-win/src/test/socketsOps_test.cc: -------------------------------------------------------------------------------- 1 | #define _WINSOCK_DEPRECATED_NO_WARNINGS 2 | #include 3 | 4 | #pragma comment(lib, "ws2_32.lib") 5 | #include "logging.h" 6 | #include "Endian.h" 7 | #include "SocketsOps.h" 8 | 9 | #include 10 | 11 | 12 | 13 | using namespace std; 14 | using namespace muduo; 15 | using namespace muduo::net; 16 | 17 | //int main() 18 | int main914() 19 | { 20 | WSADATA Ws; 21 | char SendBuffer[MAX_PATH]; 22 | //Init Windows Socket 23 | if (WSAStartup(MAKEWORD(2, 2), &Ws) != 0) 24 | { 25 | cout << "Init Windows Socket Failed::" << GetLastError() << endl; 26 | return -1; 27 | } 28 | struct sockaddr_in addr; 29 | addr.sin_family = AF_INET; 30 | //inet_pton(AF_INET,"192.168.255.130",) 31 | addr.sin_addr.s_addr = inet_addr("127.0.0.1"); 32 | addr.sin_port = sockets::hostToNetwork16(2000); 33 | memset(addr.sin_zero, 0, 8); 34 | 35 | int sockfd = sockets::createOrDie(AF_INET); 36 | int ret = sockets::connect(sockfd, sockets::sockaddr_cast(&addr)); 37 | if (ret == SOCKET_ERROR) 38 | { 39 | LOG_ERROR << "connect error" << GetLastError(); 40 | } 41 | else 42 | { 43 | while (true) 44 | { 45 | cin.getline(SendBuffer, sizeof(SendBuffer)); 46 | ret = sockets::write(sockfd, SendBuffer, static_cast(strlen(SendBuffer))); 47 | 48 | } 49 | } 50 | cin.get(); 51 | sockets::close(sockfd); 52 | WSACleanup(); 53 | return 0; 54 | } -------------------------------------------------------------------------------- /third/muduo-win/src/test/tcpclient_test.cc: -------------------------------------------------------------------------------- 1 | #pragma warning(disable : 4996) 2 | #include "EventLoopThread.h" 3 | #include "logging.h" 4 | #include "TcpClient.h" 5 | #include 6 | 7 | using namespace muduo; 8 | using namespace muduo::net; 9 | 10 | 11 | //int main() 12 | int main_tcpclient() 13 | { 14 | Logger::setLogLevel(Logger::DEBUG); 15 | 16 | EventLoopThread loopThread; 17 | { 18 | InetAddress serverAddr("127.0.0.1", 2016); // should succeed 19 | TcpClient client(loopThread.startLoop(), serverAddr, "TcpClient"); 20 | client.connect(); 21 | std::this_thread::sleep_for(std::chrono::seconds(5)); 22 | client.disconnect(); 23 | } 24 | std::this_thread::sleep_for(std::chrono::seconds(3)); 25 | 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /third/muduo-win/src/test/time_min_heap_test.cc: -------------------------------------------------------------------------------- 1 | //#include 2 | //#include "TimeMinHeap.h" 3 | // 4 | //int main() 5 | //{ 6 | // struct element *inserted[1024]; 7 | // struct min_heap heap; 8 | // min_heap_ctor(&heap); 9 | // for (int i = 1023; i >= 0; --i) { 10 | // inserted[i] = (struct element *)malloc(sizeof(struct element)); 11 | // inserted[i]->timeout = i; 12 | // min_heap_push(&heap, inserted[i]); 13 | // } 14 | // for (int i = 0; i < 512; ++i) { 15 | // min_heap_erase(&heap, inserted[i]); 16 | // } 17 | // std::cout << "size = " << heap.size << std::endl; 18 | // while (true) 19 | // { 20 | // struct element* p = (struct element *)min_heap_pop(&heap); 21 | // if (!p) 22 | // break; 23 | // printf("%d,",p->timeout); 24 | // } 25 | // for (int i = 0; i < 1024; ++i) 26 | // { 27 | // free(inserted[i]); 28 | // } 29 | // min_heap_dtor(&heap); 30 | // std::cin.get(); 31 | // return 0; 32 | // return 0; 33 | //} -------------------------------------------------------------------------------- /third/muduo-win/src/test/timerqueue_test.cc: -------------------------------------------------------------------------------- 1 | #include "EventLoop.h" 2 | #include "EventLoopThread.h" 3 | #include "logging.h" 4 | #include "thread.h" 5 | #include 6 | #include 7 | 8 | 9 | using namespace muduo; 10 | using namespace muduo::net; 11 | 12 | int cnt = 0; 13 | EventLoop* g_timequeue_loop; 14 | 15 | void printid() 16 | { 17 | LOG_INFO << "pid = " << getCurrentThreadId(); 18 | LOG_INFO << "now " << Timestamp::now().toFormattedString(); 19 | } 20 | void print(const char* msg) 21 | { 22 | LOG_INFO << "time:" << Timestamp::now().toFormattedString()<<" msg:" << msg; 23 | if (++cnt == 20) 24 | { 25 | g_timequeue_loop->quit(); 26 | } 27 | } 28 | void cancel(TimerId timer) 29 | { 30 | g_timequeue_loop->cancel(timer); 31 | LOG_INFO << "cancelled at" << Timestamp::now().toFormattedString(); 32 | } 33 | //int main() 34 | int main_timerqueue() 35 | { 36 | printid(); 37 | std::this_thread::sleep_for(std::chrono::seconds(1)); 38 | { 39 | EventLoop loop; 40 | g_timequeue_loop = &loop; 41 | 42 | LOG_INFO << "main"; 43 | loop.runAfter(1, std::bind(print, "once1")); 44 | loop.runAfter(1.5, std::bind(print, "once1.5")); 45 | loop.runAfter(2.5, std::bind(print, "once2.5")); 46 | loop.runAfter(3.5, std::bind(print, "once3.5")); 47 | 48 | TimerId t45 = loop.runAfter(4.5, std::bind(print, "once4.5")); 49 | loop.runAfter(4.2, std::bind(cancel, t45)); 50 | loop.runAfter(4.8, std::bind(cancel, t45)); 51 | loop.runEvery(2, std::bind(print, "every2")); 52 | TimerId t3 = loop.runEvery(3, std::bind(print, "every3")); 53 | loop.runAfter(9.001, std::bind(cancel, t3)); 54 | 55 | loop.loop(); 56 | LOG_INFO << "main loop exits"; 57 | } 58 | std::this_thread::sleep_for(std::chrono::seconds(1)); 59 | { 60 | EventLoopThread loopThread; 61 | EventLoop* loop = loopThread.startLoop(); 62 | loop->runAfter(2, printid); 63 | std::this_thread::sleep_for(std::chrono::seconds(3)); 64 | LOG_INFO << "thread loop exits"; 65 | } 66 | std::cin.get(); 67 | return 0; 68 | } -------------------------------------------------------------------------------- /third/muduo/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set (LIB_NAME muduo) 2 | 3 | IF(UNIX) 4 | 5 | # aux_source_directory(. muduo_SRCS) 6 | file(GLOB_RECURSE muduo_SRCS "./*.*") 7 | 8 | add_library(${LIB_NAME} ${muduo_SRCS}) 9 | target_link_libraries(${LIB_NAME} pthread rt) 10 | 11 | # elseif(WIN32) # Check if we are on Windows 12 | 13 | # create_win_proj(${LIB_NAME}) 14 | 15 | else() 16 | message(SEND_ERROR "You are on an unsupported platform! (Not Win32 or Unix)") 17 | ENDIF() -------------------------------------------------------------------------------- /third/muduo/base/Atomic.h: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a BSD-style license 2 | // that can be found in the License file. 3 | // 4 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 5 | 6 | #ifndef MUDUO_BASE_ATOMIC_H 7 | #define MUDUO_BASE_ATOMIC_H 8 | 9 | #include 10 | 11 | #include 12 | 13 | namespace muduo 14 | { 15 | 16 | namespace detail 17 | { 18 | template 19 | class AtomicIntegerT : noncopyable 20 | { 21 | public: 22 | AtomicIntegerT() 23 | : value_( 0 ) 24 | {} 25 | 26 | // uncomment if you need copying and assignment 27 | // 28 | // AtomicIntegerT(const AtomicIntegerT& that) 29 | // : value_(that.get()) 30 | // {} 31 | // 32 | // AtomicIntegerT& operator=(const AtomicIntegerT& that) 33 | // { 34 | // getAndSet(that.get()); 35 | // return *this; 36 | // } 37 | 38 | T get() 39 | { 40 | // in gcc >= 4.7: __atomic_load_n(&value_, __ATOMIC_SEQ_CST) 41 | return __sync_val_compare_and_swap( &value_, 0, 0 ); 42 | } 43 | 44 | T getAndAdd( T x ) 45 | { 46 | // in gcc >= 4.7: __atomic_fetch_add(&value_, x, __ATOMIC_SEQ_CST) 47 | return __sync_fetch_and_add( &value_, x ); 48 | } 49 | 50 | T addAndGet( T x ) 51 | { 52 | return getAndAdd( x ) + x; 53 | } 54 | 55 | T incrementAndGet() 56 | { 57 | return addAndGet( 1 ); 58 | } 59 | 60 | T decrementAndGet() 61 | { 62 | return addAndGet( -1 ); 63 | } 64 | 65 | void add( T x ) 66 | { 67 | getAndAdd( x ); 68 | } 69 | 70 | void increment() 71 | { 72 | incrementAndGet(); 73 | } 74 | 75 | void decrement() 76 | { 77 | decrementAndGet(); 78 | } 79 | 80 | T getAndSet( T newValue ) 81 | { 82 | // in gcc >= 4.7: __atomic_exchange_n(&value, newValue, __ATOMIC_SEQ_CST) 83 | return __sync_lock_test_and_set( &value_, newValue ); 84 | } 85 | 86 | private: 87 | volatile T value_; 88 | }; 89 | } 90 | 91 | typedef detail::AtomicIntegerT AtomicInt32; 92 | typedef detail::AtomicIntegerT AtomicInt64; 93 | } 94 | 95 | #endif // MUDUO_BASE_ATOMIC_H 96 | -------------------------------------------------------------------------------- /third/muduo/base/Condition.cc: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a BSD-style license 2 | // that can be found in the License file. 3 | // 4 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 5 | 6 | #include 7 | 8 | #include 9 | 10 | // returns true if time out, false otherwise. 11 | bool muduo::Condition::waitForSeconds(double seconds) 12 | { 13 | struct timespec abstime; 14 | // FIXME: use CLOCK_MONOTONIC or CLOCK_MONOTONIC_RAW to prevent time rewind. 15 | clock_gettime(CLOCK_REALTIME, &abstime); 16 | 17 | const int64_t kNanoSecondsPerSecond = 1000000000; 18 | int64_t nanoseconds = static_cast(seconds * kNanoSecondsPerSecond); 19 | 20 | abstime.tv_sec += static_cast((abstime.tv_nsec + nanoseconds) / kNanoSecondsPerSecond); 21 | abstime.tv_nsec = static_cast((abstime.tv_nsec + nanoseconds) % kNanoSecondsPerSecond); 22 | 23 | MutexLock::UnassignGuard ug(mutex_); 24 | return ETIMEDOUT == pthread_cond_timedwait(&pcond_, mutex_.getPthreadMutex(), &abstime); 25 | } 26 | 27 | -------------------------------------------------------------------------------- /third/muduo/base/Condition.h: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a BSD-style license 2 | // that can be found in the License file. 3 | // 4 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 5 | 6 | #ifndef MUDUO_BASE_CONDITION_H 7 | #define MUDUO_BASE_CONDITION_H 8 | 9 | #include 10 | 11 | #include 12 | 13 | namespace muduo 14 | { 15 | 16 | class Condition : noncopyable 17 | { 18 | public: 19 | explicit Condition(MutexLock& mutex) 20 | : mutex_(mutex) 21 | { 22 | MCHECK(pthread_cond_init(&pcond_, NULL)); 23 | } 24 | 25 | ~Condition() 26 | { 27 | MCHECK(pthread_cond_destroy(&pcond_)); 28 | } 29 | 30 | void wait() 31 | { 32 | MutexLock::UnassignGuard ug(mutex_); 33 | MCHECK(pthread_cond_wait(&pcond_, mutex_.getPthreadMutex())); 34 | } 35 | 36 | // returns true if time out, false otherwise. 37 | bool waitForSeconds(double seconds); 38 | 39 | void notify() 40 | { 41 | MCHECK(pthread_cond_signal(&pcond_)); 42 | } 43 | 44 | void notifyAll() 45 | { 46 | MCHECK(pthread_cond_broadcast(&pcond_)); 47 | } 48 | 49 | private: 50 | MutexLock& mutex_; 51 | pthread_cond_t pcond_; 52 | }; 53 | 54 | } 55 | #endif // MUDUO_BASE_CONDITION_H 56 | -------------------------------------------------------------------------------- /third/muduo/base/CountDownLatch.cc: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a BSD-style license 2 | // that can be found in the License file. 3 | // 4 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 5 | 6 | #include 7 | 8 | using namespace muduo; 9 | 10 | CountDownLatch::CountDownLatch(int count) 11 | : mutex_(), 12 | condition_(mutex_), 13 | count_(count) 14 | { 15 | } 16 | 17 | void CountDownLatch::wait() 18 | { 19 | MutexLockGuard lock(mutex_); 20 | while (count_ > 0) 21 | { 22 | condition_.wait(); 23 | } 24 | } 25 | 26 | void CountDownLatch::countDown() 27 | { 28 | MutexLockGuard lock(mutex_); 29 | --count_; 30 | if (count_ == 0) 31 | { 32 | condition_.notifyAll(); 33 | } 34 | } 35 | 36 | int CountDownLatch::getCount() const 37 | { 38 | MutexLockGuard lock(mutex_); 39 | return count_; 40 | } 41 | 42 | -------------------------------------------------------------------------------- /third/muduo/base/CountDownLatch.h: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a BSD-style license 2 | // that can be found in the License file. 3 | // 4 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 5 | 6 | #ifndef MUDUO_BASE_COUNTDOWNLATCH_H 7 | #define MUDUO_BASE_COUNTDOWNLATCH_H 8 | 9 | #include 10 | #include 11 | 12 | namespace muduo 13 | { 14 | 15 | class CountDownLatch : noncopyable 16 | { 17 | public: 18 | 19 | explicit CountDownLatch(int count); 20 | 21 | void wait(); 22 | 23 | void countDown(); 24 | 25 | int getCount() const; 26 | 27 | private: 28 | mutable MutexLock mutex_; 29 | Condition condition_; 30 | int count_; 31 | }; 32 | 33 | } 34 | #endif // MUDUO_BASE_COUNTDOWNLATCH_H 35 | -------------------------------------------------------------------------------- /third/muduo/base/CurrentThread.h: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a BSD-style license 2 | // that can be found in the License file. 3 | // 4 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 5 | 6 | #ifndef MUDUO_BASE_CURRENTTHREAD_H 7 | #define MUDUO_BASE_CURRENTTHREAD_H 8 | 9 | #include 10 | 11 | namespace muduo 12 | { 13 | namespace CurrentThread 14 | { 15 | // internal 16 | extern __thread int t_cachedTid; 17 | extern __thread char t_tidString[32]; 18 | extern __thread int t_tidStringLength; 19 | extern __thread const char* t_threadName; 20 | void cacheTid(); 21 | 22 | inline int tid() 23 | { 24 | if (__builtin_expect(t_cachedTid == 0, 0)) 25 | { 26 | cacheTid(); 27 | } 28 | return t_cachedTid; 29 | } 30 | 31 | inline const char* tidString() // for logging 32 | { 33 | return t_tidString; 34 | } 35 | 36 | inline int tidStringLength() // for logging 37 | { 38 | return t_tidStringLength; 39 | } 40 | 41 | inline const char* name() 42 | { 43 | return t_threadName; 44 | } 45 | 46 | bool isMainThread(); 47 | 48 | void sleepUsec(int64_t usec); 49 | } 50 | } 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /third/muduo/base/Date.cc: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a BSD-style license 2 | // that can be found in the License file. 3 | // 4 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 5 | 6 | #include 7 | #include // snprintf 8 | 9 | namespace muduo 10 | { 11 | namespace detail 12 | { 13 | 14 | char require_32_bit_integer_at_least[sizeof(int) >= sizeof(int32_t) ? 1 : -1]; 15 | 16 | // algorithm and explanation see: 17 | // http://www.faqs.org/faqs/calendars/faq/part2/ 18 | // http://blog.csdn.net/Solstice 19 | 20 | int getJulianDayNumber(int year, int month, int day) 21 | { 22 | (void) require_32_bit_integer_at_least; // no warning please 23 | int a = (14 - month) / 12; 24 | int y = year + 4800 - a; 25 | int m = month + 12 * a - 3; 26 | return day + (153*m + 2) / 5 + y*365 + y/4 - y/100 + y/400 - 32045; 27 | } 28 | 29 | struct Date::YearMonthDay getYearMonthDay(int julianDayNumber) 30 | { 31 | int a = julianDayNumber + 32044; 32 | int b = (4 * a + 3) / 146097; 33 | int c = a - ((b * 146097) / 4); 34 | int d = (4 * c + 3) / 1461; 35 | int e = c - ((1461 * d) / 4); 36 | int m = (5 * e + 2) / 153; 37 | Date::YearMonthDay ymd; 38 | ymd.day = e - ((153 * m + 2) / 5) + 1; 39 | ymd.month = m + 3 - 12 * (m / 10); 40 | ymd.year = b * 100 + d - 4800 + (m / 10); 41 | return ymd; 42 | } 43 | } 44 | const int Date::kJulianDayOf1970_01_01 = detail::getJulianDayNumber(1970, 1, 1); 45 | } 46 | 47 | using namespace muduo; 48 | using namespace muduo::detail; 49 | 50 | Date::Date(int y, int m, int d) 51 | : julianDayNumber_(getJulianDayNumber(y, m, d)) 52 | { 53 | } 54 | 55 | Date::Date(const struct tm& t) 56 | : julianDayNumber_(getJulianDayNumber( 57 | t.tm_year+1900, 58 | t.tm_mon+1, 59 | t.tm_mday)) 60 | { 61 | } 62 | 63 | string Date::toIsoString() const 64 | { 65 | char buf[32]; 66 | YearMonthDay ymd(yearMonthDay()); 67 | snprintf(buf, sizeof buf, "%4d-%02d-%02d", ymd.year, ymd.month, ymd.day); 68 | return buf; 69 | } 70 | 71 | Date::YearMonthDay Date::yearMonthDay() const 72 | { 73 | return getYearMonthDay(julianDayNumber_); 74 | } 75 | 76 | -------------------------------------------------------------------------------- /third/muduo/base/Date.h: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a BSD-style license 2 | // that can be found in the License file. 3 | // 4 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 5 | 6 | #ifndef MUDUO_BASE_DATE_H 7 | #define MUDUO_BASE_DATE_H 8 | 9 | #include 10 | #include 11 | 12 | struct tm; 13 | 14 | namespace muduo 15 | { 16 | 17 | /// 18 | /// Date in Gregorian calendar. 19 | /// 20 | /// This class is immutable. 21 | /// It's recommended to pass it by value, since it's passed in register on x64. 22 | /// 23 | class Date : public muduo::copyable 24 | // public boost::less_than_comparable, 25 | // public boost::equality_comparable 26 | { 27 | public: 28 | 29 | struct YearMonthDay 30 | { 31 | int year; // [1900..2500] 32 | int month; // [1..12] 33 | int day; // [1..31] 34 | }; 35 | 36 | static const int kDaysPerWeek = 7; 37 | static const int kJulianDayOf1970_01_01; 38 | 39 | /// 40 | /// Constucts an invalid Date. 41 | /// 42 | Date() 43 | : julianDayNumber_(0) 44 | {} 45 | 46 | /// 47 | /// Constucts a yyyy-mm-dd Date. 48 | /// 49 | /// 1 <= month <= 12 50 | Date(int year, int month, int day); 51 | 52 | /// 53 | /// Constucts a Date from Julian Day Number. 54 | /// 55 | explicit Date(int julianDayNum) 56 | : julianDayNumber_(julianDayNum) 57 | {} 58 | 59 | /// 60 | /// Constucts a Date from struct tm 61 | /// 62 | explicit Date(const struct tm&); 63 | 64 | // default copy/assignment/dtor are Okay 65 | 66 | void swap(Date& that) 67 | { 68 | std::swap(julianDayNumber_, that.julianDayNumber_); 69 | } 70 | 71 | bool valid() const { return julianDayNumber_ > 0; } 72 | 73 | /// 74 | /// Converts to yyyy-mm-dd format. 75 | /// 76 | string toIsoString() const; 77 | 78 | struct YearMonthDay yearMonthDay() const; 79 | 80 | int year() const 81 | { 82 | return yearMonthDay().year; 83 | } 84 | 85 | int month() const 86 | { 87 | return yearMonthDay().month; 88 | } 89 | 90 | int day() const 91 | { 92 | return yearMonthDay().day; 93 | } 94 | 95 | // [0, 1, ..., 6] => [Sunday, Monday, ..., Saturday ] 96 | int weekDay() const 97 | { 98 | return (julianDayNumber_+1) % kDaysPerWeek; 99 | } 100 | 101 | int julianDayNumber() const { return julianDayNumber_; } 102 | 103 | private: 104 | int julianDayNumber_; 105 | }; 106 | 107 | inline bool operator<(Date x, Date y) 108 | { 109 | return x.julianDayNumber() < y.julianDayNumber(); 110 | } 111 | 112 | inline bool operator==(Date x, Date y) 113 | { 114 | return x.julianDayNumber() == y.julianDayNumber(); 115 | } 116 | 117 | } 118 | #endif // MUDUO_BASE_DATE_H 119 | -------------------------------------------------------------------------------- /third/muduo/base/Exception.cc: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a BSD-style license 2 | // that can be found in the License file. 3 | // 4 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 5 | 6 | #include 7 | 8 | //#include 9 | #include 10 | #include 11 | 12 | using namespace muduo; 13 | 14 | Exception::Exception(const char* msg) 15 | : message_(msg) 16 | { 17 | fillStackTrace(); 18 | } 19 | 20 | Exception::Exception(const string& msg) 21 | : message_(msg) 22 | { 23 | fillStackTrace(); 24 | } 25 | 26 | Exception::~Exception() throw () 27 | { 28 | } 29 | 30 | const char* Exception::what() const throw() 31 | { 32 | return message_.c_str(); 33 | } 34 | 35 | const char* Exception::stackTrace() const throw() 36 | { 37 | return stack_.c_str(); 38 | } 39 | 40 | void Exception::fillStackTrace() 41 | { 42 | const int len = 200; 43 | void* buffer[len]; 44 | int nptrs = ::backtrace(buffer, len); 45 | char** strings = ::backtrace_symbols(buffer, nptrs); 46 | if (strings) 47 | { 48 | for (int i = 0; i < nptrs; ++i) 49 | { 50 | // TODO demangle funcion name with abi::__cxa_demangle 51 | stack_.append(strings[i]); 52 | stack_.push_back('\n'); 53 | } 54 | free(strings); 55 | } 56 | } 57 | 58 | -------------------------------------------------------------------------------- /third/muduo/base/Exception.h: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a BSD-style license 2 | // that can be found in the License file. 3 | // 4 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 5 | 6 | #ifndef MUDUO_BASE_EXCEPTION_H 7 | #define MUDUO_BASE_EXCEPTION_H 8 | 9 | #include 10 | #include 11 | 12 | namespace muduo 13 | { 14 | 15 | class Exception : public std::exception 16 | { 17 | public: 18 | explicit Exception(const char* what); 19 | explicit Exception(const string& what); 20 | virtual ~Exception() throw(); 21 | virtual const char* what() const throw(); 22 | const char* stackTrace() const throw(); 23 | 24 | private: 25 | void fillStackTrace(); 26 | 27 | string message_; 28 | string stack_; 29 | }; 30 | 31 | } 32 | 33 | #endif // MUDUO_BASE_EXCEPTION_H 34 | -------------------------------------------------------------------------------- /third/muduo/base/Thread.h: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a BSD-style license 2 | // that can be found in the License file. 3 | // 4 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 5 | 6 | #ifndef MUDUO_BASE_THREAD_H 7 | #define MUDUO_BASE_THREAD_H 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | namespace muduo 18 | { 19 | 20 | class Thread : noncopyable 21 | { 22 | public: 23 | typedef std::function ThreadFunc; 24 | 25 | explicit Thread( ThreadFunc, const string& name = string() ); 26 | // FIXME: make it movable in C++11 27 | ~Thread(); 28 | 29 | void start(); 30 | int join(); // return pthread_join() 31 | 32 | bool started() const { return started_; } 33 | // pthread_t pthreadId() const { return pthreadId_; } 34 | pid_t tid() const { return tid_; } 35 | const string& name() const { return name_; } 36 | 37 | static int numCreated() { return numCreated_.get(); } 38 | 39 | private: 40 | void setDefaultName(); 41 | 42 | bool started_; 43 | bool joined_; 44 | pthread_t pthreadId_; 45 | pid_t tid_; 46 | ThreadFunc func_; 47 | string name_; 48 | CountDownLatch latch_; 49 | 50 | static AtomicInt32 numCreated_; 51 | }; 52 | 53 | } 54 | #endif 55 | -------------------------------------------------------------------------------- /third/muduo/base/ThreadLocal.h: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a BSD-style license 2 | // that can be found in the License file. 3 | // 4 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 5 | 6 | #ifndef MUDUO_BASE_THREADLOCAL_H 7 | #define MUDUO_BASE_THREADLOCAL_H 8 | 9 | #include // MCHECK 10 | #include 11 | 12 | #include 13 | 14 | namespace muduo 15 | { 16 | 17 | template 18 | class ThreadLocal : noncopyable 19 | { 20 | public: 21 | ThreadLocal() 22 | { 23 | MCHECK(pthread_key_create(&pkey_, &ThreadLocal::destructor)); 24 | } 25 | 26 | ~ThreadLocal() 27 | { 28 | MCHECK(pthread_key_delete(pkey_)); 29 | } 30 | 31 | T& value() 32 | { 33 | T* perThreadValue = static_cast(pthread_getspecific(pkey_)); 34 | if (!perThreadValue) 35 | { 36 | T* newObj = new T(); 37 | MCHECK(pthread_setspecific(pkey_, newObj)); 38 | perThreadValue = newObj; 39 | } 40 | return *perThreadValue; 41 | } 42 | 43 | private: 44 | 45 | static void destructor(void *x) 46 | { 47 | T* obj = static_cast(x); 48 | typedef char T_must_be_complete_type[sizeof(T) == 0 ? -1 : 1]; 49 | T_must_be_complete_type dummy; (void) dummy; 50 | delete obj; 51 | } 52 | 53 | private: 54 | pthread_key_t pkey_; 55 | }; 56 | 57 | } 58 | #endif 59 | -------------------------------------------------------------------------------- /third/muduo/base/ThreadLocalSingleton.h: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a BSD-style license 2 | // that can be found in the License file. 3 | // 4 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 5 | 6 | #ifndef MUDUO_BASE_THREADLOCALSINGLETON_H 7 | #define MUDUO_BASE_THREADLOCALSINGLETON_H 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | namespace muduo 15 | { 16 | 17 | template 18 | class ThreadLocalSingleton : noncopyable 19 | { 20 | public: 21 | 22 | static T& instance() 23 | { 24 | if ( !t_value_ ) 25 | { 26 | t_value_ = new T(); 27 | deleter_.set( t_value_ ); 28 | } 29 | return *t_value_; 30 | } 31 | 32 | static T* pointer() 33 | { 34 | return t_value_; 35 | } 36 | 37 | private: 38 | ThreadLocalSingleton(); 39 | ~ThreadLocalSingleton(); 40 | 41 | static void destructor( void* obj ) 42 | { 43 | assert( obj == t_value_ ); 44 | typedef char T_must_be_complete_type[sizeof( T ) == 0 ? -1 : 1]; 45 | T_must_be_complete_type dummy; ( void )dummy; 46 | delete t_value_; 47 | t_value_ = 0; 48 | } 49 | 50 | class Deleter 51 | { 52 | public: 53 | Deleter() 54 | { 55 | pthread_key_create( &pkey_, &ThreadLocalSingleton::destructor ); 56 | } 57 | 58 | ~Deleter() 59 | { 60 | pthread_key_delete( pkey_ ); 61 | } 62 | 63 | void set( T* newObj ) 64 | { 65 | assert( pthread_getspecific( pkey_ ) == NULL ); 66 | pthread_setspecific( pkey_, newObj ); 67 | } 68 | 69 | pthread_key_t pkey_; 70 | }; 71 | 72 | static __thread T* t_value_; 73 | static Deleter deleter_; 74 | }; 75 | 76 | template 77 | __thread T* ThreadLocalSingleton::t_value_ = 0; 78 | 79 | template 80 | typename ThreadLocalSingleton::Deleter ThreadLocalSingleton::deleter_; 81 | 82 | } 83 | #endif 84 | -------------------------------------------------------------------------------- /third/muduo/base/ThreadPool.cc: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a BSD-style license 2 | // that can be found in the License file. 3 | // 4 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 5 | 6 | #include 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | using namespace muduo; 14 | 15 | ThreadPool::ThreadPool(const string& nameArg) 16 | : mutex_(), 17 | notEmpty_(mutex_), 18 | notFull_(mutex_), 19 | name_(nameArg), 20 | maxQueueSize_(0), 21 | running_(false) 22 | { 23 | } 24 | 25 | ThreadPool::~ThreadPool() 26 | { 27 | if (running_) 28 | { 29 | stop(); 30 | } 31 | } 32 | 33 | void ThreadPool::start(int numThreads) 34 | { 35 | assert(threads_.empty()); 36 | running_ = true; 37 | threads_.reserve(numThreads); 38 | for (int i = 0; i < numThreads; ++i) 39 | { 40 | char id[32]; 41 | snprintf(id, sizeof id, "%d", i+1); 42 | threads_.emplace_back(new muduo::Thread( 43 | std::bind(&ThreadPool::runInThread, this), name_+id)); 44 | threads_[i]->start(); 45 | } 46 | if (numThreads == 0 && threadInitCallback_) 47 | { 48 | threadInitCallback_(); 49 | } 50 | } 51 | 52 | void ThreadPool::stop() 53 | { 54 | { 55 | MutexLockGuard lock(mutex_); 56 | running_ = false; 57 | notEmpty_.notifyAll(); 58 | } 59 | for (auto& thr : threads_) 60 | { 61 | thr->join(); 62 | } 63 | } 64 | 65 | size_t ThreadPool::queueSize() const 66 | { 67 | MutexLockGuard lock(mutex_); 68 | return queue_.size(); 69 | } 70 | 71 | void ThreadPool::run(Task task) 72 | { 73 | if (threads_.empty()) 74 | { 75 | task(); 76 | } 77 | else 78 | { 79 | MutexLockGuard lock(mutex_); 80 | while (isFull()) 81 | { 82 | notFull_.wait(); 83 | } 84 | assert(!isFull()); 85 | 86 | queue_.push_back(std::move(task)); 87 | notEmpty_.notify(); 88 | } 89 | } 90 | 91 | ThreadPool::Task ThreadPool::take() 92 | { 93 | MutexLockGuard lock(mutex_); 94 | // always use a while-loop, due to spurious wakeup 95 | while (queue_.empty() && running_) 96 | { 97 | notEmpty_.wait(); 98 | } 99 | Task task; 100 | if (!queue_.empty()) 101 | { 102 | task = queue_.front(); 103 | queue_.pop_front(); 104 | if (maxQueueSize_ > 0) 105 | { 106 | notFull_.notify(); 107 | } 108 | } 109 | return task; 110 | } 111 | 112 | bool ThreadPool::isFull() const 113 | { 114 | mutex_.assertLocked(); 115 | return maxQueueSize_ > 0 && queue_.size() >= maxQueueSize_; 116 | } 117 | 118 | void ThreadPool::runInThread() 119 | { 120 | try 121 | { 122 | if (threadInitCallback_) 123 | { 124 | threadInitCallback_(); 125 | } 126 | while (running_) 127 | { 128 | Task task(take()); 129 | if (task) 130 | { 131 | task(); 132 | } 133 | } 134 | } 135 | catch (const Exception& ex) 136 | { 137 | fprintf(stderr, "exception caught in ThreadPool %s\n", name_.c_str()); 138 | fprintf(stderr, "reason: %s\n", ex.what()); 139 | fprintf(stderr, "stack trace: %s\n", ex.stackTrace()); 140 | abort(); 141 | } 142 | catch (const std::exception& ex) 143 | { 144 | fprintf(stderr, "exception caught in ThreadPool %s\n", name_.c_str()); 145 | fprintf(stderr, "reason: %s\n", ex.what()); 146 | abort(); 147 | } 148 | catch (...) 149 | { 150 | fprintf(stderr, "unknown exception caught in ThreadPool %s\n", name_.c_str()); 151 | throw; // rethrow 152 | } 153 | } 154 | 155 | -------------------------------------------------------------------------------- /third/muduo/base/ThreadPool.h: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a BSD-style license 2 | // that can be found in the License file. 3 | // 4 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 5 | 6 | #ifndef MUDUO_BASE_THREADPOOL_H 7 | #define MUDUO_BASE_THREADPOOL_H 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | namespace muduo 18 | { 19 | 20 | class ThreadPool : noncopyable 21 | { 22 | public: 23 | typedef std::function Task; 24 | 25 | explicit ThreadPool(const string& nameArg = string("ThreadPool")); 26 | ~ThreadPool(); 27 | 28 | // Must be called before start(). 29 | void setMaxQueueSize(int maxSize) { maxQueueSize_ = maxSize; } 30 | void setThreadInitCallback(const Task& cb) 31 | { threadInitCallback_ = cb; } 32 | 33 | void start(int numThreads); 34 | void stop(); 35 | 36 | const string& name() const 37 | { return name_; } 38 | 39 | size_t queueSize() const; 40 | 41 | // Could block if maxQueueSize > 0 42 | void run(Task f); 43 | 44 | private: 45 | bool isFull() const; 46 | void runInThread(); 47 | Task take(); 48 | 49 | mutable MutexLock mutex_; 50 | Condition notEmpty_; 51 | Condition notFull_; 52 | string name_; 53 | Task threadInitCallback_; 54 | std::vector> threads_; 55 | std::deque queue_; 56 | size_t maxQueueSize_; 57 | bool running_; 58 | }; 59 | 60 | } 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /third/muduo/base/TimeZone.h: -------------------------------------------------------------------------------- 1 | // Use of this source code is governed by a BSD-style license 2 | // that can be found in the License file. 3 | // 4 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 5 | 6 | #ifndef MUDUO_BASE_TIMEZONE_H 7 | #define MUDUO_BASE_TIMEZONE_H 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | namespace muduo 14 | { 15 | 16 | // TimeZone for 1970~2030 17 | class TimeZone : public muduo::copyable 18 | { 19 | public: 20 | explicit TimeZone(const char* zonefile); 21 | TimeZone(int eastOfUtc, const char* tzname); // a fixed timezone 22 | TimeZone() {} // an invalid timezone 23 | 24 | // default copy ctor/assignment/dtor are Okay. 25 | 26 | bool valid() const 27 | { 28 | // 'explicit operator bool() const' in C++11 29 | return static_cast(data_); 30 | } 31 | 32 | struct tm toLocalTime(time_t secondsSinceEpoch) const; 33 | time_t fromLocalTime(const struct tm&) const; 34 | 35 | // gmtime(3) 36 | static struct tm toUtcTime(time_t secondsSinceEpoch, bool yday = false); 37 | // timegm(3) 38 | static time_t fromUtcTime(const struct tm&); 39 | // year in [1900..2500], month in [1..12], day in [1..31] 40 | static time_t fromUtcTime(int year, int month, int day, 41 | int hour, int minute, int seconds); 42 | 43 | struct Data; 44 | 45 | private: 46 | 47 | std::shared_ptr data_; 48 | }; 49 | 50 | } 51 | #endif // MUDUO_BASE_TIMEZONE_H 52 | -------------------------------------------------------------------------------- /third/muduo/base/Timestamp.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | #ifndef __STDC_FORMAT_MACROS 7 | #define __STDC_FORMAT_MACROS 8 | #endif 9 | 10 | #include 11 | 12 | using namespace muduo; 13 | 14 | static_assert(sizeof(Timestamp) == sizeof(int64_t), 15 | "Timestamp is same size as int64_t"); 16 | 17 | string Timestamp::toString() const 18 | { 19 | char buf[32] = {0}; 20 | int64_t seconds = microSecondsSinceEpoch_ / kMicroSecondsPerSecond; 21 | int64_t microseconds = microSecondsSinceEpoch_ % kMicroSecondsPerSecond; 22 | snprintf(buf, sizeof(buf)-1, "%" PRId64 ".%06" PRId64 "", seconds, microseconds); 23 | return buf; 24 | } 25 | 26 | string Timestamp::toFormattedString(bool showMicroseconds) const 27 | { 28 | char buf[32] = {0}; 29 | time_t seconds = static_cast(microSecondsSinceEpoch_ / kMicroSecondsPerSecond); 30 | struct tm tm_time; 31 | gmtime_r(&seconds, &tm_time); 32 | 33 | if (showMicroseconds) 34 | { 35 | int microseconds = static_cast(microSecondsSinceEpoch_ % kMicroSecondsPerSecond); 36 | snprintf(buf, sizeof(buf), "%4d%02d%02d %02d:%02d:%02d.%06d", 37 | tm_time.tm_year + 1900, tm_time.tm_mon + 1, tm_time.tm_mday, 38 | tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec, 39 | microseconds); 40 | } 41 | else 42 | { 43 | snprintf(buf, sizeof(buf), "%4d%02d%02d %02d:%02d:%02d", 44 | tm_time.tm_year + 1900, tm_time.tm_mon + 1, tm_time.tm_mday, 45 | tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec); 46 | } 47 | return buf; 48 | } 49 | 50 | Timestamp Timestamp::now() 51 | { 52 | struct timeval tv; 53 | gettimeofday(&tv, NULL); 54 | int64_t seconds = tv.tv_sec; 55 | return Timestamp(seconds * kMicroSecondsPerSecond + tv.tv_usec); 56 | } 57 | 58 | -------------------------------------------------------------------------------- /third/muduo/base/Timestamp.h: -------------------------------------------------------------------------------- 1 | #ifndef MUDUO_BASE_TIMESTAMP_H 2 | #define MUDUO_BASE_TIMESTAMP_H 3 | 4 | #include 5 | #include 6 | 7 | //#include 8 | #include 9 | 10 | namespace muduo 11 | { 12 | 13 | /// 14 | /// Time stamp in UTC, in microseconds resolution. 15 | /// 16 | /// This class is immutable. 17 | /// It's recommended to pass it by value, since it's passed in register on x64. 18 | /// 19 | class Timestamp : public muduo::copyable 20 | //, 21 | //public boost::equality_comparable, 22 | //public boost::less_than_comparable 23 | { 24 | public: 25 | /// 26 | /// Constucts an invalid Timestamp. 27 | /// 28 | Timestamp() 29 | : microSecondsSinceEpoch_(0) 30 | { 31 | } 32 | 33 | /// 34 | /// Constucts a Timestamp at specific time 35 | /// 36 | /// @param microSecondsSinceEpoch 37 | explicit Timestamp(int64_t microSecondsSinceEpochArg) 38 | : microSecondsSinceEpoch_(microSecondsSinceEpochArg) 39 | { 40 | } 41 | 42 | void swap(Timestamp& that) 43 | { 44 | std::swap(microSecondsSinceEpoch_, that.microSecondsSinceEpoch_); 45 | } 46 | 47 | // default copy/assignment/dtor are Okay 48 | 49 | string toString() const; 50 | string toFormattedString(bool showMicroseconds = true) const; 51 | 52 | bool valid() const { return microSecondsSinceEpoch_ > 0; } 53 | 54 | // for internal usage. 55 | int64_t microSecondsSinceEpoch() const { return microSecondsSinceEpoch_; } 56 | time_t secondsSinceEpoch() const 57 | { return static_cast(microSecondsSinceEpoch_ / kMicroSecondsPerSecond); } 58 | 59 | /// 60 | /// Get time of now. 61 | /// 62 | static Timestamp now(); 63 | static Timestamp invalid() 64 | { 65 | return Timestamp(); 66 | } 67 | 68 | static Timestamp fromUnixTime(time_t t) 69 | { 70 | return fromUnixTime(t, 0); 71 | } 72 | 73 | static Timestamp fromUnixTime(time_t t, int microseconds) 74 | { 75 | return Timestamp(static_cast(t) * kMicroSecondsPerSecond + microseconds); 76 | } 77 | 78 | static const int kMicroSecondsPerSecond = 1000 * 1000; 79 | 80 | private: 81 | int64_t microSecondsSinceEpoch_; 82 | }; 83 | 84 | inline bool operator<(Timestamp lhs, Timestamp rhs) 85 | { 86 | return lhs.microSecondsSinceEpoch() < rhs.microSecondsSinceEpoch(); 87 | } 88 | 89 | inline bool operator==(Timestamp lhs, Timestamp rhs) 90 | { 91 | return lhs.microSecondsSinceEpoch() == rhs.microSecondsSinceEpoch(); 92 | } 93 | 94 | /// 95 | /// Gets time difference of two timestamps, result in seconds. 96 | /// 97 | /// @param high, low 98 | /// @return (high-low) in seconds 99 | /// @c double has 52-bit precision, enough for one-microsecond 100 | /// resolution for next 100 years. 101 | inline double timeDifference(Timestamp high, Timestamp low) 102 | { 103 | int64_t diff = high.microSecondsSinceEpoch() - low.microSecondsSinceEpoch(); 104 | return static_cast(diff) / Timestamp::kMicroSecondsPerSecond; 105 | } 106 | 107 | /// 108 | /// Add @c seconds to given timestamp. 109 | /// 110 | /// @return timestamp+seconds as Timestamp 111 | /// 112 | inline Timestamp addTime(Timestamp timestamp, double seconds) 113 | { 114 | int64_t delta = static_cast(seconds * Timestamp::kMicroSecondsPerSecond); 115 | return Timestamp(timestamp.microSecondsSinceEpoch() + delta); 116 | } 117 | 118 | } 119 | #endif // MUDUO_BASE_TIMESTAMP_H 120 | -------------------------------------------------------------------------------- /third/muduo/base/WeakCallback.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010, Shuo Chen. All rights reserved. 2 | // http://code.google.com/p/muduo/ 3 | // 4 | // Use of this source code is governed by a BSD-style license 5 | // that can be found in the License file. 6 | // 7 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 8 | 9 | #ifndef MUDUO_BASE_WEAKCALLBACK_H 10 | #define MUDUO_BASE_WEAKCALLBACK_H 11 | 12 | #include 13 | #include 14 | 15 | namespace muduo 16 | { 17 | 18 | // A barely usable WeakCallback 19 | 20 | #ifdef __GXX_EXPERIMENTAL_CXX0X__ 21 | 22 | template 23 | class WeakCallback 24 | { 25 | public: 26 | 27 | WeakCallback(const std::weak_ptr& object, 28 | const std::function& function) 29 | : object_(object), function_(function) 30 | { 31 | } 32 | 33 | // Default dtor, copy ctor and assignment are okay 34 | 35 | void operator()(ARGS&&... args) const 36 | { 37 | std::shared_ptr ptr(object_.lock()); 38 | if (ptr) 39 | { 40 | function_(ptr.get(), std::forward(args)...); 41 | } 42 | // else 43 | // { 44 | // LOG_TRACE << "expired"; 45 | // } 46 | } 47 | 48 | private: 49 | 50 | std::weak_ptr object_; 51 | std::function function_; 52 | }; 53 | 54 | template 55 | WeakCallback makeWeakCallback(const std::shared_ptr& object, 56 | void (CLASS::*function)(ARGS...)) 57 | { 58 | return WeakCallback(object, function); 59 | } 60 | 61 | template 62 | WeakCallback makeWeakCallback(const std::shared_ptr& object, 63 | void (CLASS::*function)(ARGS...) const) 64 | { 65 | return WeakCallback(object, function); 66 | } 67 | 68 | #else // __GXX_EXPERIMENTAL_CXX0X__ 69 | 70 | // the C++98/03 version doesn't support arguments. 71 | 72 | template 73 | class WeakCallback 74 | { 75 | public: 76 | 77 | WeakCallback(const std::weak_ptr& object, 78 | const std::function& function) 79 | : object_(object), function_(function) 80 | { 81 | } 82 | 83 | // Default dtor, copy ctor and assignment are okay 84 | 85 | void operator()() const 86 | { 87 | std::shared_ptr ptr(object_.lock()); 88 | if (ptr) 89 | { 90 | function_(ptr.get()); 91 | } 92 | // else 93 | // { 94 | // LOG_TRACE << "expired"; 95 | // } 96 | } 97 | 98 | private: 99 | 100 | std::weak_ptr object_; 101 | std::function function_; 102 | }; 103 | 104 | template 105 | WeakCallback makeWeakCallback(const std::shared_ptr& object, 106 | void (CLASS::*function)()) 107 | { 108 | return WeakCallback(object, function); 109 | } 110 | 111 | template 112 | WeakCallback makeWeakCallback(const std::shared_ptr& object, 113 | void (CLASS::*function)() const) 114 | { 115 | return WeakCallback(object, function); 116 | } 117 | 118 | #endif // __GXX_EXPERIMENTAL_CXX0X__ 119 | } 120 | 121 | #endif 122 | -------------------------------------------------------------------------------- /third/muduo/base/copyable.h: -------------------------------------------------------------------------------- 1 | #ifndef MUDUO_BASE_COPYABLE_H 2 | #define MUDUO_BASE_COPYABLE_H 3 | 4 | namespace muduo 5 | { 6 | 7 | /// A tag class emphasises the objects are copyable. 8 | /// The empty base class optimization applies. 9 | /// Any derived class of copyable should be a value type. 10 | class copyable 11 | { 12 | protected: 13 | copyable() = default; 14 | ~copyable() = default; 15 | }; 16 | 17 | }; 18 | 19 | #endif // MUDUO_BASE_COPYABLE_H 20 | -------------------------------------------------------------------------------- /third/muduo/base/noncopyable.h: -------------------------------------------------------------------------------- 1 | #ifndef MUDUO_BASE_NONCOPYABLE_H 2 | #define MUDUO_BASE_NONCOPYABLE_H 3 | 4 | namespace muduo 5 | { 6 | 7 | class noncopyable 8 | { 9 | protected: 10 | noncopyable() = default; 11 | ~noncopyable() = default; 12 | 13 | private: 14 | noncopyable( const noncopyable& ) = delete; 15 | void operator=( const noncopyable& ) = delete; 16 | }; 17 | 18 | } 19 | 20 | #endif // MUDUO_BASE_NONCOPYABLE_H 21 | -------------------------------------------------------------------------------- /third/muduo/net/Acceptor.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2010, Shuo Chen. All rights reserved. 2 | // http://code.google.com/p/muduo/ 3 | // 4 | // Use of this source code is governed by a BSD-style license 5 | // that can be found in the License file. 6 | 7 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | #include 18 | //#include 19 | //#include 20 | #include 21 | 22 | using namespace muduo; 23 | using namespace muduo::net; 24 | 25 | Acceptor::Acceptor(EventLoop* loop, const InetAddress& listenAddr, bool reuseport) 26 | : loop_(loop), 27 | acceptSocket_(sockets::createNonblockingOrDie(listenAddr.family())), 28 | acceptChannel_(loop, acceptSocket_.fd()), 29 | listenning_(false), 30 | idleFd_(::open("/dev/null", O_RDONLY | O_CLOEXEC)) 31 | { 32 | assert(idleFd_ >= 0); 33 | acceptSocket_.setReuseAddr(true); 34 | acceptSocket_.setReusePort(reuseport); 35 | acceptSocket_.bindAddress(listenAddr); 36 | acceptChannel_.setReadCallback( 37 | std::bind(&Acceptor::handleRead, this)); 38 | } 39 | 40 | Acceptor::~Acceptor() 41 | { 42 | acceptChannel_.disableAll(); 43 | acceptChannel_.remove(); 44 | ::close(idleFd_); 45 | } 46 | 47 | void Acceptor::listen() 48 | { 49 | loop_->assertInLoopThread(); 50 | listenning_ = true; 51 | acceptSocket_.listen(); 52 | acceptChannel_.enableReading(); 53 | } 54 | 55 | void Acceptor::handleRead() 56 | { 57 | loop_->assertInLoopThread(); 58 | InetAddress peerAddr; 59 | //FIXME loop until no more 60 | int connfd = acceptSocket_.accept(&peerAddr); 61 | if (connfd >= 0) 62 | { 63 | // string hostport = peerAddr.toIpPort(); 64 | // LOG_TRACE << "Accepts of " << hostport; 65 | if (newConnectionCallback_) 66 | { 67 | newConnectionCallback_(connfd, peerAddr); 68 | } 69 | else 70 | { 71 | sockets::close(connfd); 72 | } 73 | } 74 | else 75 | { 76 | LOG_SYSERR << "in Acceptor::handleRead"; 77 | // Read the section named "The special problem of 78 | // accept()ing when you can't" in libev's doc. 79 | // By Marc Lehmann, author of libev. 80 | if (errno == EMFILE) 81 | { 82 | ::close(idleFd_); 83 | idleFd_ = ::accept(acceptSocket_.fd(), NULL, NULL); 84 | ::close(idleFd_); 85 | idleFd_ = ::open("/dev/null", O_RDONLY | O_CLOEXEC); 86 | } 87 | } 88 | } 89 | 90 | -------------------------------------------------------------------------------- /third/muduo/net/Acceptor.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010, Shuo Chen. All rights reserved. 2 | // http://code.google.com/p/muduo/ 3 | // 4 | // Use of this source code is governed by a BSD-style license 5 | // that can be found in the License file. 6 | 7 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 8 | // 9 | // This is an internal header file, you should not include this. 10 | 11 | #ifndef MUDUO_NET_ACCEPTOR_H 12 | #define MUDUO_NET_ACCEPTOR_H 13 | 14 | #include 15 | 16 | #include 17 | #include 18 | 19 | namespace muduo 20 | { 21 | namespace net 22 | { 23 | 24 | class EventLoop; 25 | class InetAddress; 26 | 27 | /// 28 | /// Acceptor of incoming TCP connections. 29 | /// 30 | class Acceptor : noncopyable 31 | { 32 | public: 33 | typedef std::function NewConnectionCallback; 34 | 35 | Acceptor(EventLoop* loop, const InetAddress& listenAddr, bool reuseport); 36 | ~Acceptor(); 37 | 38 | void setNewConnectionCallback(const NewConnectionCallback& cb) 39 | { newConnectionCallback_ = cb; } 40 | 41 | bool listenning() const { return listenning_; } 42 | void listen(); 43 | 44 | private: 45 | void handleRead(); 46 | 47 | EventLoop* loop_; 48 | Socket acceptSocket_; 49 | Channel acceptChannel_; 50 | NewConnectionCallback newConnectionCallback_; 51 | bool listenning_; 52 | int idleFd_; 53 | }; 54 | 55 | } 56 | } 57 | 58 | #endif // MUDUO_NET_ACCEPTOR_H 59 | -------------------------------------------------------------------------------- /third/muduo/net/Buffer.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2010, Shuo Chen. All rights reserved. 2 | // http://code.google.com/p/muduo/ 3 | // 4 | // Use of this source code is governed by a BSD-style license 5 | // that can be found in the License file. 6 | 7 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 8 | // 9 | 10 | #include 11 | 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | using namespace muduo; 18 | using namespace muduo::net; 19 | 20 | const char Buffer::kCRLF[] = "\r\n"; 21 | 22 | const size_t Buffer::kCheapPrepend; 23 | const size_t Buffer::kInitialSize; 24 | 25 | ssize_t Buffer::readFd( int fd, int* savedErrno ) 26 | { 27 | // saved an ioctl()/FIONREAD call to tell how much to read 28 | char extrabuf[65536]; 29 | struct iovec vec[2]; 30 | const size_t writable = writableBytes(); 31 | vec[0].iov_base = begin() + writerIndex_; 32 | vec[0].iov_len = writable; 33 | vec[1].iov_base = extrabuf; 34 | vec[1].iov_len = sizeof extrabuf; 35 | // when there is enough space in this buffer, don't read into extrabuf. 36 | // when extrabuf is used, we read 128k-1 bytes at most. 37 | const int iovcnt = ( writable < sizeof extrabuf ) ? 2 : 1; 38 | const ssize_t n = sockets::readv( fd, vec, iovcnt ); 39 | if ( n < 0 ) 40 | { 41 | *savedErrno = errno; 42 | } 43 | else if ( implicit_cast< size_t >( n ) <= writable ) 44 | { 45 | writerIndex_ += n; 46 | } 47 | else 48 | { 49 | writerIndex_ = buffer_.size(); 50 | append( extrabuf, n - writable ); 51 | } 52 | // if (n == writable + sizeof extrabuf) 53 | // { 54 | // goto line_30; 55 | // } 56 | return n; 57 | } 58 | 59 | -------------------------------------------------------------------------------- /third/muduo/net/Callbacks.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010, Shuo Chen. All rights reserved. 2 | // http://code.google.com/p/muduo/ 3 | // 4 | // Use of this source code is governed by a BSD-style license 5 | // that can be found in the License file. 6 | 7 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 8 | // 9 | // This is a public header file, it must only include public header files. 10 | 11 | #ifndef MUDUO_NET_CALLBACKS_H 12 | #define MUDUO_NET_CALLBACKS_H 13 | 14 | #include 15 | 16 | #include 17 | #include 18 | 19 | namespace muduo 20 | { 21 | 22 | using std::placeholders::_1; 23 | using std::placeholders::_2; 24 | using std::placeholders::_3; 25 | 26 | // should really belong to base/Types.h, but is not included there. 27 | 28 | template 29 | inline T* get_pointer(const std::shared_ptr& ptr) 30 | { 31 | return ptr.get(); 32 | } 33 | 34 | template 35 | inline T* get_pointer(const std::unique_ptr& ptr) 36 | { 37 | return ptr.get(); 38 | } 39 | 40 | // Adapted from google-protobuf stubs/common.h 41 | // see License in muduo/base/Types.h 42 | template 43 | inline ::std::shared_ptr down_pointer_cast(const ::std::shared_ptr& f) { 44 | if (false) 45 | { 46 | implicit_cast(0); 47 | } 48 | 49 | #ifndef NDEBUG 50 | assert(f == NULL || dynamic_cast(get_pointer(f)) != NULL); 51 | #endif 52 | return ::std::static_pointer_cast(f); 53 | } 54 | 55 | namespace net 56 | { 57 | 58 | // All client visible callbacks go here. 59 | 60 | class Buffer; 61 | class TcpConnection; 62 | typedef std::shared_ptr TcpConnectionPtr; 63 | typedef std::function TimerCallback; 64 | typedef std::function ConnectionCallback; 65 | typedef std::function CloseCallback; 66 | typedef std::function WriteCompleteCallback; 67 | typedef std::function HighWaterMarkCallback; 68 | 69 | // the data has been read to (buf, len) 70 | typedef std::function MessageCallback; 73 | 74 | void defaultConnectionCallback(const TcpConnectionPtr& conn); 75 | void defaultMessageCallback(const TcpConnectionPtr& conn, 76 | Buffer* buffer, 77 | Timestamp receiveTime); 78 | 79 | } 80 | } 81 | 82 | #endif // MUDUO_NET_CALLBACKS_H 83 | -------------------------------------------------------------------------------- /third/muduo/net/Channel.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2010, Shuo Chen. All rights reserved. 2 | // http://code.google.com/p/muduo/ 3 | // 4 | // Use of this source code is governed by a BSD-style license 5 | // that can be found in the License file. 6 | 7 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | #include 16 | 17 | using namespace muduo; 18 | using namespace muduo::net; 19 | 20 | const int Channel::kNoneEvent = 0; 21 | const int Channel::kReadEvent = POLLIN | POLLPRI; 22 | const int Channel::kWriteEvent = POLLOUT; 23 | 24 | Channel::Channel( EventLoop* loop, int fd__ ) 25 | : loop_( loop ), 26 | fd_( fd__ ), 27 | events_( 0 ), 28 | revents_( 0 ), 29 | index_( -1 ), 30 | logHup_( true ), 31 | tied_( false ), 32 | eventHandling_( false ), 33 | addedToLoop_( false ) 34 | {} 35 | 36 | Channel::~Channel() 37 | { 38 | assert( !eventHandling_ ); 39 | assert( !addedToLoop_ ); 40 | if ( loop_->isInLoopThread() ) 41 | { 42 | assert( !loop_->hasChannel( this ) ); 43 | } 44 | } 45 | 46 | void Channel::tie( const std::shared_ptr& obj ) 47 | { 48 | tie_ = obj; 49 | tied_ = true; 50 | } 51 | 52 | void Channel::update() 53 | { 54 | addedToLoop_ = true; 55 | loop_->updateChannel( this ); 56 | } 57 | 58 | void Channel::remove() 59 | { 60 | assert( isNoneEvent() ); 61 | addedToLoop_ = false; 62 | loop_->removeChannel( this ); 63 | } 64 | 65 | void Channel::handleEvent( Timestamp receiveTime ) 66 | { 67 | std::shared_ptr guard; 68 | if ( tied_ ) 69 | { 70 | guard = tie_.lock(); 71 | if ( guard ) 72 | { 73 | handleEventWithGuard( receiveTime ); 74 | } 75 | } 76 | else 77 | { 78 | handleEventWithGuard( receiveTime ); 79 | } 80 | } 81 | 82 | void Channel::handleEventWithGuard( Timestamp receiveTime ) 83 | { 84 | eventHandling_ = true; 85 | LOG_TRACE << reventsToString(); 86 | if ( ( revents_ & POLLHUP ) && !( revents_ & POLLIN ) ) 87 | { 88 | if ( logHup_ ) 89 | { 90 | LOG_WARN << "fd = " << fd_ << " Channel::handle_event() POLLHUP"; 91 | } 92 | if ( closeCallback_ ) closeCallback_(); 93 | } 94 | 95 | if ( revents_ & POLLNVAL ) 96 | { 97 | LOG_WARN << "fd = " << fd_ << " Channel::handle_event() POLLNVAL"; 98 | } 99 | 100 | if ( revents_ & ( POLLERR | POLLNVAL ) ) 101 | { 102 | if ( errorCallback_ ) errorCallback_(); 103 | } 104 | if ( revents_ & ( POLLIN | POLLPRI | POLLRDHUP ) ) 105 | { 106 | if ( readCallback_ ) readCallback_( receiveTime ); 107 | } 108 | if ( revents_ & POLLOUT ) 109 | { 110 | if ( writeCallback_ ) writeCallback_(); 111 | } 112 | eventHandling_ = false; 113 | } 114 | 115 | string Channel::reventsToString() const 116 | { 117 | return eventsToString( fd_, revents_ ); 118 | } 119 | 120 | string Channel::eventsToString() const 121 | { 122 | return eventsToString( fd_, events_ ); 123 | } 124 | 125 | string Channel::eventsToString( int fd, int ev ) 126 | { 127 | std::ostringstream oss; 128 | oss << fd << ": "; 129 | if ( ev & POLLIN ) 130 | oss << "IN "; 131 | if ( ev & POLLPRI ) 132 | oss << "PRI "; 133 | if ( ev & POLLOUT ) 134 | oss << "OUT "; 135 | if ( ev & POLLHUP ) 136 | oss << "HUP "; 137 | if ( ev & POLLRDHUP ) 138 | oss << "RDHUP "; 139 | if ( ev & POLLERR ) 140 | oss << "ERR "; 141 | if ( ev & POLLNVAL ) 142 | oss << "NVAL "; 143 | 144 | return oss.str().c_str(); 145 | } 146 | -------------------------------------------------------------------------------- /third/muduo/net/Connector.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010, Shuo Chen. All rights reserved. 2 | // http://code.google.com/p/muduo/ 3 | // 4 | // Use of this source code is governed by a BSD-style license 5 | // that can be found in the License file. 6 | 7 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 8 | // 9 | // This is an internal header file, you should not include this. 10 | 11 | #ifndef MUDUO_NET_CONNECTOR_H 12 | #define MUDUO_NET_CONNECTOR_H 13 | 14 | #include 15 | 16 | #include 17 | #include 18 | 19 | namespace muduo 20 | { 21 | namespace net 22 | { 23 | 24 | class Channel; 25 | class EventLoop; 26 | 27 | class Connector : noncopyable, 28 | public std::enable_shared_from_this 29 | { 30 | public: 31 | typedef std::function NewConnectionCallback; 32 | 33 | Connector(EventLoop* loop, const InetAddress& serverAddr); 34 | ~Connector(); 35 | 36 | void setNewConnectionCallback(const NewConnectionCallback& cb) 37 | { newConnectionCallback_ = cb; } 38 | 39 | void start(); // can be called in any thread 40 | void restart(); // must be called in loop thread 41 | void stop(); // can be called in any thread 42 | 43 | const InetAddress& serverAddress() const { return serverAddr_; } 44 | 45 | private: 46 | enum States { kDisconnected, kConnecting, kConnected }; 47 | static const int kMaxRetryDelayMs = 30*1000; 48 | static const int kInitRetryDelayMs = 500; 49 | 50 | void setState(States s) { state_ = s; } 51 | void startInLoop(); 52 | void stopInLoop(); 53 | void connect(); 54 | void connecting(int sockfd); 55 | void handleWrite(); 56 | void handleError(); 57 | void retry(int sockfd); 58 | int removeAndResetChannel(); 59 | void resetChannel(); 60 | 61 | EventLoop* loop_; 62 | InetAddress serverAddr_; 63 | bool connect_; // atomic 64 | States state_; // FIXME: use atomic variable 65 | std::unique_ptr channel_; 66 | NewConnectionCallback newConnectionCallback_; 67 | int retryDelayMs_; 68 | }; 69 | 70 | } 71 | } 72 | 73 | #endif // MUDUO_NET_CONNECTOR_H 74 | -------------------------------------------------------------------------------- /third/muduo/net/Endian.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010, Shuo Chen. All rights reserved. 2 | // http://code.google.com/p/muduo/ 3 | // 4 | // Use of this source code is governed by a BSD-style license 5 | // that can be found in the License file. 6 | 7 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 8 | // 9 | // This is a public header file, it must only include public header files. 10 | 11 | #ifndef MUDUO_NET_ENDIAN_H 12 | #define MUDUO_NET_ENDIAN_H 13 | 14 | #include 15 | #include 16 | 17 | namespace muduo 18 | { 19 | namespace net 20 | { 21 | namespace sockets 22 | { 23 | 24 | // the inline assembler code makes type blur, 25 | // so we disable warnings for a while. 26 | #if defined(__clang__) || __GNUC_PREREQ (4,6) 27 | #pragma GCC diagnostic push 28 | #endif 29 | #pragma GCC diagnostic ignored "-Wconversion" 30 | #pragma GCC diagnostic ignored "-Wold-style-cast" 31 | inline uint64_t hostToNetwork64(uint64_t host64) 32 | { 33 | return htobe64(host64); 34 | } 35 | 36 | inline uint32_t hostToNetwork32(uint32_t host32) 37 | { 38 | return htobe32(host32); 39 | } 40 | 41 | inline uint16_t hostToNetwork16(uint16_t host16) 42 | { 43 | return htobe16(host16); 44 | } 45 | 46 | inline uint64_t networkToHost64(uint64_t net64) 47 | { 48 | return be64toh(net64); 49 | } 50 | 51 | inline uint32_t networkToHost32(uint32_t net32) 52 | { 53 | return be32toh(net32); 54 | } 55 | 56 | inline uint16_t networkToHost16(uint16_t net16) 57 | { 58 | return be16toh(net16); 59 | } 60 | #if defined(__clang__) || __GNUC_PREREQ (4,6) 61 | #pragma GCC diagnostic pop 62 | #else 63 | #pragma GCC diagnostic warning "-Wconversion" 64 | #pragma GCC diagnostic warning "-Wold-style-cast" 65 | #endif 66 | 67 | 68 | } 69 | } 70 | } 71 | 72 | #endif // MUDUO_NET_ENDIAN_H 73 | -------------------------------------------------------------------------------- /third/muduo/net/EventLoopThread.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2010, Shuo Chen. All rights reserved. 2 | // http://code.google.com/p/muduo/ 3 | // 4 | // Use of this source code is governed by a BSD-style license 5 | // that can be found in the License file. 6 | 7 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 8 | 9 | #include 10 | 11 | #include 12 | 13 | using namespace muduo; 14 | using namespace muduo::net; 15 | 16 | EventLoopThread::EventLoopThread( const ThreadInitCallback& cb, 17 | const string& name ) 18 | : loop_( NULL ), 19 | exiting_( false ), 20 | thread_( std::bind( &EventLoopThread::threadFunc, this ), name ), 21 | mutex_(), 22 | cond_( mutex_ ), 23 | callback_( cb ) 24 | {} 25 | 26 | EventLoopThread::~EventLoopThread() 27 | { 28 | exiting_ = true; 29 | if ( loop_ != NULL ) // not 100% race-free, eg. threadFunc could be running callback_. 30 | { 31 | // still a tiny chance to call destructed object, if threadFunc exits just now. 32 | // but when EventLoopThread destructs, usually programming is exiting anyway. 33 | loop_->quit(); 34 | thread_.join(); 35 | } 36 | } 37 | 38 | EventLoop* EventLoopThread::startLoop() 39 | { 40 | assert( !thread_.started() ); 41 | thread_.start(); 42 | 43 | { 44 | MutexLockGuard lock( mutex_ ); 45 | while ( loop_ == NULL ) 46 | { 47 | cond_.wait(); 48 | } 49 | } 50 | 51 | return loop_; 52 | } 53 | 54 | void EventLoopThread::threadFunc() 55 | { 56 | EventLoop loop; 57 | 58 | if ( callback_ ) 59 | { 60 | callback_( &loop ); 61 | } 62 | 63 | { 64 | MutexLockGuard lock( mutex_ ); 65 | loop_ = &loop; 66 | cond_.notify(); 67 | } 68 | 69 | loop.loop(); 70 | //assert(exiting_); 71 | loop_ = NULL; 72 | } 73 | 74 | -------------------------------------------------------------------------------- /third/muduo/net/EventLoopThread.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010, Shuo Chen. All rights reserved. 2 | // http://code.google.com/p/muduo/ 3 | // 4 | // Use of this source code is governed by a BSD-style license 5 | // that can be found in the License file. 6 | 7 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 8 | // 9 | // This is a public header file, it must only include public header files. 10 | 11 | #ifndef MUDUO_NET_EVENTLOOPTHREAD_H 12 | #define MUDUO_NET_EVENTLOOPTHREAD_H 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | namespace muduo 19 | { 20 | namespace net 21 | { 22 | 23 | class EventLoop; 24 | 25 | class EventLoopThread : noncopyable 26 | { 27 | public: 28 | typedef std::function ThreadInitCallback; 29 | 30 | EventLoopThread( const ThreadInitCallback& cb = ThreadInitCallback(), 31 | const string& name = string() ); 32 | ~EventLoopThread(); 33 | EventLoop* startLoop(); 34 | 35 | private: 36 | void threadFunc(); 37 | 38 | EventLoop* loop_; 39 | bool exiting_; 40 | Thread thread_; 41 | MutexLock mutex_; 42 | Condition cond_; 43 | ThreadInitCallback callback_; 44 | }; 45 | 46 | } 47 | } 48 | 49 | #endif // MUDUO_NET_EVENTLOOPTHREAD_H 50 | 51 | -------------------------------------------------------------------------------- /third/muduo/net/EventLoopThreadPool.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2010, Shuo Chen. All rights reserved. 2 | // http://code.google.com/p/muduo/ 3 | // 4 | // Use of this source code is governed by a BSD-style license 5 | // that can be found in the License file. 6 | 7 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | using namespace muduo; 17 | using namespace muduo::net; 18 | 19 | EventLoopThreadPool::EventLoopThreadPool( EventLoop* baseLoop, const string& nameArg ) 20 | : baseLoop_( baseLoop ), 21 | name_( nameArg ), 22 | started_( false ), 23 | numThreads_( 0 ), 24 | next_( 0 ) 25 | {} 26 | 27 | EventLoopThreadPool::~EventLoopThreadPool() 28 | { 29 | // Don't delete loop, it's stack variable 30 | } 31 | 32 | void EventLoopThreadPool::start( const ThreadInitCallback& cb ) 33 | { 34 | assert( !started_ ); 35 | baseLoop_->assertInLoopThread(); 36 | 37 | started_ = true; 38 | 39 | for ( int i = 0; i < numThreads_; ++i ) 40 | { 41 | char buf[name_.size() + 32]; 42 | snprintf( buf, sizeof buf, "%s%d", name_.c_str(), i ); 43 | EventLoopThread* t = new EventLoopThread( cb, buf ); 44 | threads_.push_back( std::unique_ptr( t ) ); 45 | loops_.push_back( t->startLoop() ); 46 | } 47 | if ( numThreads_ == 0 && cb ) 48 | { 49 | cb( baseLoop_ ); 50 | } 51 | } 52 | 53 | EventLoop* EventLoopThreadPool::getNextLoop() 54 | { 55 | baseLoop_->assertInLoopThread(); 56 | assert( started_ ); 57 | EventLoop* loop = baseLoop_; 58 | 59 | if ( !loops_.empty() ) 60 | { 61 | // round-robin 62 | loop = loops_[next_]; 63 | ++next_; 64 | if ( implicit_cast< size_t >( next_ ) >= loops_.size() ) 65 | { 66 | next_ = 0; 67 | } 68 | } 69 | return loop; 70 | } 71 | 72 | EventLoop* EventLoopThreadPool::getLoopForHash( size_t hashCode ) 73 | { 74 | baseLoop_->assertInLoopThread(); 75 | EventLoop* loop = baseLoop_; 76 | 77 | if ( !loops_.empty() ) 78 | { 79 | loop = loops_[hashCode % loops_.size()]; 80 | } 81 | return loop; 82 | } 83 | 84 | std::vector EventLoopThreadPool::getAllLoops() 85 | { 86 | baseLoop_->assertInLoopThread(); 87 | assert( started_ ); 88 | if ( loops_.empty() ) 89 | { 90 | return std::vector( 1, baseLoop_ ); 91 | } 92 | else 93 | { 94 | return loops_; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /third/muduo/net/EventLoopThreadPool.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010, Shuo Chen. All rights reserved. 2 | // http://code.google.com/p/muduo/ 3 | // 4 | // Use of this source code is governed by a BSD-style license 5 | // that can be found in the License file. 6 | 7 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 8 | // 9 | // This is an internal header file, you should not include this. 10 | 11 | #ifndef MUDUO_NET_EVENTLOOPTHREADPOOL_H 12 | #define MUDUO_NET_EVENTLOOPTHREADPOOL_H 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | namespace muduo 22 | { 23 | 24 | namespace net 25 | { 26 | 27 | class EventLoop; 28 | class EventLoopThread; 29 | 30 | class EventLoopThreadPool : noncopyable 31 | { 32 | public: 33 | typedef std::function ThreadInitCallback; 34 | 35 | EventLoopThreadPool(EventLoop* baseLoop, const string& nameArg); 36 | ~EventLoopThreadPool(); 37 | void setThreadNum(int numThreads) { numThreads_ = numThreads; } 38 | void start(const ThreadInitCallback& cb = ThreadInitCallback()); 39 | 40 | // valid after calling start() 41 | /// round-robin 42 | EventLoop* getNextLoop(); 43 | 44 | /// with the same hash code, it will always return the same EventLoop 45 | EventLoop* getLoopForHash(size_t hashCode); 46 | 47 | std::vector getAllLoops(); 48 | 49 | bool started() const 50 | { return started_; } 51 | 52 | const string& name() const 53 | { return name_; } 54 | 55 | private: 56 | 57 | EventLoop* baseLoop_; 58 | string name_; 59 | bool started_; 60 | int numThreads_; 61 | int next_; 62 | std::vector> threads_; 63 | std::vector loops_; 64 | }; 65 | 66 | } 67 | } 68 | 69 | #endif // MUDUO_NET_EVENTLOOPTHREADPOOL_H 70 | -------------------------------------------------------------------------------- /third/muduo/net/InetAddress.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010, Shuo Chen. All rights reserved. 2 | // http://code.google.com/p/muduo/ 3 | // 4 | // Use of this source code is governed by a BSD-style license 5 | // that can be found in the License file. 6 | 7 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 8 | // 9 | // This is a public header file, it must only include public header files. 10 | 11 | #ifndef MUDUO_NET_INETADDRESS_H 12 | #define MUDUO_NET_INETADDRESS_H 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | namespace muduo 20 | { 21 | namespace net 22 | { 23 | namespace sockets 24 | { 25 | const struct sockaddr* sockaddr_cast(const struct sockaddr_in6* addr); 26 | } 27 | 28 | /// 29 | /// Wrapper of sockaddr_in. 30 | /// 31 | /// This is an POD interface class. 32 | class InetAddress : public muduo::copyable 33 | { 34 | public: 35 | /// Constructs an endpoint with given port number. 36 | /// Mostly used in TcpServer listening. 37 | explicit InetAddress(uint16_t port = 0, bool loopbackOnly = false, bool ipv6 = false); 38 | 39 | /// Constructs an endpoint with given ip and port. 40 | /// @c ip should be "1.2.3.4" 41 | InetAddress(StringArg ip, uint16_t port, bool ipv6 = false); 42 | 43 | /// Constructs an endpoint with given struct @c sockaddr_in 44 | /// Mostly used when accepting new connections 45 | explicit InetAddress(const struct sockaddr_in& addr) 46 | : addr_(addr) 47 | { } 48 | 49 | explicit InetAddress(const struct sockaddr_in6& addr) 50 | : addr6_(addr) 51 | { } 52 | 53 | sa_family_t family() const { return addr_.sin_family; } 54 | string toIp() const; 55 | string toIpPort() const; 56 | uint16_t toPort() const; 57 | 58 | // default copy/assignment are Okay 59 | 60 | const struct sockaddr* getSockAddr() const { return sockets::sockaddr_cast( &addr6_ ); } 61 | void setSockAddrInet6(const struct sockaddr_in6& addr6) { addr6_ = addr6; } 62 | 63 | uint32_t ipNetEndian() const; 64 | uint16_t portNetEndian() const { return addr_.sin_port; } 65 | 66 | // resolve hostname to IP address, not changing port or sin_family 67 | // return true on success. 68 | // thread safe 69 | static bool resolve(StringArg hostname, InetAddress* result); 70 | // static std::vector resolveAll(const char* hostname, uint16_t port = 0); 71 | 72 | // for UdpAcceptor::peerAddrs_ 73 | const struct sockaddr_in6* getSockAddr6() const { return &addr6_; } 74 | bool operator<( const InetAddress& other ) const; 75 | 76 | private: 77 | union 78 | { 79 | struct sockaddr_in addr_; 80 | struct sockaddr_in6 addr6_; 81 | }; 82 | }; 83 | 84 | } 85 | } 86 | 87 | #endif // MUDUO_NET_INETADDRESS_H 88 | -------------------------------------------------------------------------------- /third/muduo/net/Poller.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2010, Shuo Chen. All rights reserved. 2 | // http://code.google.com/p/muduo/ 3 | // 4 | // Use of this source code is governed by a BSD-style license 5 | // that can be found in the License file. 6 | 7 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 8 | 9 | #include 10 | 11 | #include 12 | 13 | using namespace muduo; 14 | using namespace muduo::net; 15 | 16 | Poller::Poller(EventLoop* loop) 17 | : ownerLoop_(loop) 18 | { 19 | } 20 | 21 | Poller::~Poller() 22 | { 23 | } 24 | 25 | bool Poller::hasChannel(Channel* channel) const 26 | { 27 | assertInLoopThread(); 28 | ChannelMap::const_iterator it = channels_.find(channel->fd()); 29 | return it != channels_.end() && it->second == channel; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /third/muduo/net/Poller.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010, Shuo Chen. All rights reserved. 2 | // http://code.google.com/p/muduo/ 3 | // 4 | // Use of this source code is governed by a BSD-style license 5 | // that can be found in the License file. 6 | 7 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 8 | // 9 | // This is an internal header file, you should not include this. 10 | 11 | #ifndef MUDUO_NET_POLLER_H 12 | #define MUDUO_NET_POLLER_H 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | 20 | namespace muduo 21 | { 22 | namespace net 23 | { 24 | 25 | class Channel; 26 | 27 | /// 28 | /// Base class for IO Multiplexing 29 | /// 30 | /// This class doesn't own the Channel objects. 31 | class Poller : noncopyable 32 | { 33 | public: 34 | typedef std::vector ChannelList; 35 | 36 | Poller(EventLoop* loop); 37 | virtual ~Poller(); 38 | 39 | /// Polls the I/O events. 40 | /// Must be called in the loop thread. 41 | virtual Timestamp poll(int timeoutMs, ChannelList* activeChannels) = 0; 42 | 43 | /// Changes the interested I/O events. 44 | /// Must be called in the loop thread. 45 | virtual void updateChannel(Channel* channel) = 0; 46 | 47 | /// Remove the channel, when it destructs. 48 | /// Must be called in the loop thread. 49 | virtual void removeChannel(Channel* channel) = 0; 50 | 51 | virtual bool hasChannel(Channel* channel) const; 52 | 53 | static Poller* newDefaultPoller(EventLoop* loop); 54 | 55 | void assertInLoopThread() const 56 | { 57 | ownerLoop_->assertInLoopThread(); 58 | } 59 | 60 | protected: 61 | typedef std::map ChannelMap; 62 | ChannelMap channels_; 63 | 64 | private: 65 | EventLoop* ownerLoop_; 66 | }; 67 | 68 | } 69 | } 70 | #endif // MUDUO_NET_POLLER_H 71 | -------------------------------------------------------------------------------- /third/muduo/net/Socket.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010, Shuo Chen. All rights reserved. 2 | // http://code.google.com/p/muduo/ 3 | // 4 | // Use of this source code is governed by a BSD-style license 5 | // that can be found in the License file. 6 | 7 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 8 | // 9 | // This is an internal header file, you should not include this. 10 | 11 | #ifndef MUDUO_NET_SOCKET_H 12 | #define MUDUO_NET_SOCKET_H 13 | 14 | #include 15 | 16 | // struct tcp_info is in 17 | struct tcp_info; 18 | 19 | namespace muduo 20 | { 21 | /// 22 | /// TCP networking. 23 | /// 24 | namespace net 25 | { 26 | 27 | class InetAddress; 28 | 29 | /// 30 | /// Wrapper of socket file descriptor. 31 | /// 32 | /// It closes the sockfd when desctructs. 33 | /// It's thread safe, all operations are delagated to OS. 34 | class Socket : noncopyable 35 | { 36 | public: 37 | explicit Socket(int sockfd) 38 | : sockfd_(sockfd) 39 | { } 40 | 41 | // Socket(Socket&&) // move constructor in C++11 42 | ~Socket(); 43 | 44 | int fd() const { return sockfd_; } 45 | // return true if success. 46 | bool getTcpInfo(struct tcp_info*) const; 47 | bool getTcpInfoString(char* buf, int len) const; 48 | 49 | /// abort if address in use 50 | void bindAddress(const InetAddress& localaddr); 51 | /// abort if address in use 52 | void listen(); 53 | 54 | /// On success, returns a non-negative integer that is 55 | /// a descriptor for the accepted socket, which has been 56 | /// set to non-blocking and close-on-exec. *peeraddr is assigned. 57 | /// On error, -1 is returned, and *peeraddr is untouched. 58 | int accept(InetAddress* peeraddr); 59 | 60 | void shutdownWrite(); 61 | 62 | /// 63 | /// Enable/disable TCP_NODELAY (disable/enable Nagle's algorithm). 64 | /// 65 | void setTcpNoDelay(bool on); 66 | 67 | /// 68 | /// Enable/disable SO_REUSEADDR 69 | /// 70 | void setReuseAddr(bool on); 71 | 72 | /// 73 | /// Enable/disable SO_REUSEPORT 74 | /// 75 | void setReusePort(bool on); 76 | 77 | /// 78 | /// Enable/disable SO_KEEPALIVE 79 | /// 80 | void setKeepAlive(bool on); 81 | 82 | private: 83 | const int sockfd_; 84 | }; 85 | 86 | } 87 | } 88 | #endif // MUDUO_NET_SOCKET_H 89 | -------------------------------------------------------------------------------- /third/muduo/net/SocketsOps.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010, Shuo Chen. All rights reserved. 2 | // http://code.google.com/p/muduo/ 3 | // 4 | // Use of this source code is governed by a BSD-style license 5 | // that can be found in the License file. 6 | 7 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 8 | // 9 | // This is an internal header file, you should not include this. 10 | 11 | #ifndef MUDUO_NET_SOCKETSOPS_H 12 | #define MUDUO_NET_SOCKETSOPS_H 13 | 14 | #include 15 | 16 | namespace muduo 17 | { 18 | namespace net 19 | { 20 | namespace sockets 21 | { 22 | 23 | /// 24 | /// Creates a non-blocking socket file descriptor, 25 | /// abort if any error. 26 | int createNonblockingOrDie( sa_family_t family ); 27 | 28 | int connect( int sockfd, const struct sockaddr* addr ); 29 | void bindOrDie( int sockfd, const struct sockaddr* addr ); 30 | void listenOrDie( int sockfd ); 31 | int accept( int sockfd, struct sockaddr_in6* addr ); 32 | ssize_t read( int sockfd, void *buf, size_t count ); 33 | ssize_t readv( int sockfd, const struct iovec *iov, int iovcnt ); 34 | ssize_t write( int sockfd, const void *buf, size_t count ); 35 | void close( int sockfd ); 36 | void shutdownWrite( int sockfd ); 37 | 38 | void toIpPort( char* buf, size_t size, 39 | const struct sockaddr* addr ); 40 | void toIp( char* buf, size_t size, 41 | const struct sockaddr* addr ); 42 | 43 | void fromIpPort( const char* ip, uint16_t port, 44 | struct sockaddr_in* addr ); 45 | void fromIpPort( const char* ip, uint16_t port, 46 | struct sockaddr_in6* addr ); 47 | 48 | int getSocketError( int sockfd ); 49 | 50 | const struct sockaddr* sockaddr_cast( const struct sockaddr_in* addr ); 51 | const struct sockaddr* sockaddr_cast( const struct sockaddr_in6* addr ); 52 | struct sockaddr* sockaddr_cast( struct sockaddr_in6* addr ); 53 | const struct sockaddr_in* sockaddr_in_cast( const struct sockaddr* addr ); 54 | const struct sockaddr_in6* sockaddr_in6_cast( const struct sockaddr* addr ); 55 | 56 | struct sockaddr_in6 getLocalAddr( int sockfd ); 57 | struct sockaddr_in6 getPeerAddr( int sockfd ); 58 | bool isSelfConnect( int sockfd ); 59 | 60 | } 61 | } 62 | } 63 | 64 | #endif // MUDUO_NET_SOCKETSOPS_H 65 | -------------------------------------------------------------------------------- /third/muduo/net/TcpClient.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010, Shuo Chen. All rights reserved. 2 | // http://code.google.com/p/muduo/ 3 | // 4 | // Use of this source code is governed by a BSD-style license 5 | // that can be found in the License file. 6 | 7 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 8 | // 9 | // This is a public header file, it must only include public header files. 10 | 11 | #ifndef MUDUO_NET_TCPCLIENT_H 12 | #define MUDUO_NET_TCPCLIENT_H 13 | 14 | #include 15 | #include 16 | 17 | namespace muduo 18 | { 19 | namespace net 20 | { 21 | 22 | class Connector; 23 | typedef std::shared_ptr ConnectorPtr; 24 | 25 | class TcpClient : noncopyable 26 | { 27 | public: 28 | // TcpClient(EventLoop* loop); 29 | // TcpClient(EventLoop* loop, const string& host, uint16_t port); 30 | TcpClient(EventLoop* loop, 31 | const InetAddress& serverAddr, 32 | const string& nameArg); 33 | ~TcpClient(); // force out-line dtor, for std::unique_ptr members. 34 | 35 | void connect(); 36 | void disconnect(); 37 | void stop(); 38 | 39 | TcpConnectionPtr connection() const 40 | { 41 | MutexLockGuard lock(mutex_); 42 | return connection_; 43 | } 44 | 45 | EventLoop* getLoop() const { return loop_; } 46 | bool retry() const { return retry_; } 47 | void enableRetry() { retry_ = true; } 48 | 49 | const string& name() const 50 | { return name_; } 51 | 52 | /// Set connection callback. 53 | /// Not thread safe. 54 | void setConnectionCallback(ConnectionCallback cb) 55 | { connectionCallback_ = std::move(cb); } 56 | 57 | /// Set message callback. 58 | /// Not thread safe. 59 | void setMessageCallback(MessageCallback cb) 60 | { messageCallback_ = std::move(cb); } 61 | 62 | /// Set write complete callback. 63 | /// Not thread safe. 64 | void setWriteCompleteCallback(WriteCompleteCallback cb) 65 | { writeCompleteCallback_ = std::move(cb); } 66 | 67 | private: 68 | /// Not thread safe, but in loop 69 | void newConnection(int sockfd); 70 | /// Not thread safe, but in loop 71 | void removeConnection(const TcpConnectionPtr& conn); 72 | 73 | EventLoop* loop_; 74 | ConnectorPtr connector_; // avoid revealing Connector 75 | const string name_; 76 | ConnectionCallback connectionCallback_; 77 | MessageCallback messageCallback_; 78 | WriteCompleteCallback writeCompleteCallback_; 79 | bool retry_; // atomic 80 | bool connect_; // atomic 81 | // always in loop thread 82 | int nextConnId_; 83 | mutable MutexLock mutex_; 84 | TcpConnectionPtr connection_; // @GuardedBy mutex_ 85 | }; 86 | 87 | } 88 | } 89 | 90 | #endif // MUDUO_NET_TCPCLIENT_H 91 | -------------------------------------------------------------------------------- /third/muduo/net/Timer.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2010, Shuo Chen. All rights reserved. 2 | // http://code.google.com/p/muduo/ 3 | // 4 | // Use of this source code is governed by a BSD-style license 5 | // that can be found in the License file. 6 | 7 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 8 | 9 | #include 10 | 11 | using namespace muduo; 12 | using namespace muduo::net; 13 | 14 | AtomicInt64 Timer::s_numCreated_; 15 | 16 | void Timer::restart(Timestamp now) 17 | { 18 | if (repeat_) 19 | { 20 | expiration_ = addTime(now, interval_); 21 | } 22 | else 23 | { 24 | expiration_ = Timestamp::invalid(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /third/muduo/net/Timer.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010, Shuo Chen. All rights reserved. 2 | // http://code.google.com/p/muduo/ 3 | // 4 | // Use of this source code is governed by a BSD-style license 5 | // that can be found in the License file. 6 | 7 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 8 | // 9 | // This is an internal header file, you should not include this. 10 | 11 | #ifndef MUDUO_NET_TIMER_H 12 | #define MUDUO_NET_TIMER_H 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | namespace muduo 19 | { 20 | namespace net 21 | { 22 | /// 23 | /// Internal class for timer event. 24 | /// 25 | class Timer : noncopyable 26 | { 27 | public: 28 | Timer(TimerCallback cb, Timestamp when, double interval) 29 | : callback_(std::move(cb)), 30 | expiration_(when), 31 | interval_(interval), 32 | repeat_(interval > 0.0), 33 | sequence_(s_numCreated_.incrementAndGet()) 34 | { } 35 | 36 | void run() const 37 | { 38 | callback_(); 39 | } 40 | 41 | Timestamp expiration() const { return expiration_; } 42 | bool repeat() const { return repeat_; } 43 | int64_t sequence() const { return sequence_; } 44 | 45 | void restart(Timestamp now); 46 | 47 | static int64_t numCreated() { return s_numCreated_.get(); } 48 | 49 | private: 50 | const TimerCallback callback_; 51 | Timestamp expiration_; 52 | const double interval_; 53 | const bool repeat_; 54 | const int64_t sequence_; 55 | 56 | static AtomicInt64 s_numCreated_; 57 | }; 58 | } 59 | } 60 | #endif // MUDUO_NET_TIMER_H 61 | -------------------------------------------------------------------------------- /third/muduo/net/TimerId.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010, Shuo Chen. All rights reserved. 2 | // http://code.google.com/p/muduo/ 3 | // 4 | // Use of this source code is governed by a BSD-style license 5 | // that can be found in the License file. 6 | 7 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 8 | // 9 | // This is a public header file, it must only include public header files. 10 | 11 | #ifndef MUDUO_NET_TIMERID_H 12 | #define MUDUO_NET_TIMERID_H 13 | 14 | #include 15 | 16 | namespace muduo 17 | { 18 | namespace net 19 | { 20 | 21 | class Timer; 22 | 23 | /// 24 | /// An opaque identifier, for canceling Timer. 25 | /// 26 | class TimerId : public muduo::copyable 27 | { 28 | public: 29 | TimerId() 30 | : timer_(NULL), 31 | sequence_(0) 32 | { 33 | } 34 | 35 | TimerId(Timer* timer, int64_t seq) 36 | : timer_(timer), 37 | sequence_(seq) 38 | { 39 | } 40 | 41 | // default copy-ctor, dtor and assignment are okay 42 | 43 | friend class TimerQueue; 44 | 45 | private: 46 | Timer* timer_; 47 | int64_t sequence_; 48 | }; 49 | 50 | } 51 | } 52 | 53 | #endif // MUDUO_NET_TIMERID_H 54 | -------------------------------------------------------------------------------- /third/muduo/net/TimerQueue.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010, Shuo Chen. All rights reserved. 2 | // http://code.google.com/p/muduo/ 3 | // 4 | // Use of this source code is governed by a BSD-style license 5 | // that can be found in the License file. 6 | 7 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 8 | // 9 | // This is an internal header file, you should not include this. 10 | 11 | #ifndef MUDUO_NET_TIMERQUEUE_H 12 | #define MUDUO_NET_TIMERQUEUE_H 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | namespace muduo 23 | { 24 | namespace net 25 | { 26 | 27 | class EventLoop; 28 | class Timer; 29 | class TimerId; 30 | 31 | /// 32 | /// A best efforts timer queue. 33 | /// No guarantee that the callback will be on time. 34 | /// 35 | class TimerQueue : noncopyable 36 | { 37 | public: 38 | explicit TimerQueue(EventLoop* loop); 39 | ~TimerQueue(); 40 | 41 | /// 42 | /// Schedules the callback to be run at given time, 43 | /// repeats if @c interval > 0.0. 44 | /// 45 | /// Must be thread safe. Usually be called from other threads. 46 | TimerId addTimer(TimerCallback cb, 47 | Timestamp when, 48 | double interval); 49 | 50 | void cancel(TimerId timerId); 51 | 52 | private: 53 | 54 | // FIXME: use unique_ptr instead of raw pointers. 55 | // This requires heterogeneous comparison lookup (N3465) from C++14 56 | // so that we can find an T* in a set>. 57 | typedef std::pair Entry; 58 | typedef std::set TimerList; 59 | typedef std::pair ActiveTimer; 60 | typedef std::set ActiveTimerSet; 61 | 62 | void addTimerInLoop(Timer* timer); 63 | void cancelInLoop(TimerId timerId); 64 | // called when timerfd alarms 65 | void handleRead(); 66 | // move out all expired timers 67 | std::vector getExpired(Timestamp now); 68 | void reset(const std::vector& expired, Timestamp now); 69 | 70 | bool insert(Timer* timer); 71 | 72 | EventLoop* loop_; 73 | const int timerfd_; 74 | Channel timerfdChannel_; 75 | // Timer list sorted by expiration 76 | TimerList timers_; 77 | 78 | // for cancel() 79 | ActiveTimerSet activeTimers_; 80 | bool callingExpiredTimers_; /* atomic */ 81 | ActiveTimerSet cancelingTimers_; 82 | }; 83 | 84 | } 85 | } 86 | #endif // MUDUO_NET_TIMERQUEUE_H 87 | -------------------------------------------------------------------------------- /third/muduo/net/poller/DefaultPoller.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2010, Shuo Chen. All rights reserved. 2 | // http://code.google.com/p/muduo/ 3 | // 4 | // Use of this source code is governed by a BSD-style license 5 | // that can be found in the License file. 6 | 7 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | using namespace muduo::net; 16 | 17 | Poller* Poller::newDefaultPoller(EventLoop* loop) 18 | { 19 | //if (::getenv("MUDUO_USE_POLL")) 20 | //{ 21 | return new PollPoller(loop); 22 | //} 23 | //else 24 | //{ 25 | //return new EPollPoller(loop); 26 | //} 27 | } 28 | -------------------------------------------------------------------------------- /third/muduo/net/poller/EPollPoller.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010, Shuo Chen. All rights reserved. 2 | // http://code.google.com/p/muduo/ 3 | // 4 | // Use of this source code is governed by a BSD-style license 5 | // that can be found in the License file. 6 | 7 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 8 | // 9 | // This is an internal header file, you should not include this. 10 | 11 | #ifndef MUDUO_NET_POLLER_EPOLLPOLLER_H 12 | #define MUDUO_NET_POLLER_EPOLLPOLLER_H 13 | 14 | #include 15 | 16 | #include 17 | 18 | struct epoll_event; 19 | 20 | namespace muduo 21 | { 22 | namespace net 23 | { 24 | 25 | /// 26 | /// IO Multiplexing with epoll(4). 27 | /// 28 | class EPollPoller : public Poller 29 | { 30 | public: 31 | EPollPoller(EventLoop* loop); 32 | virtual ~EPollPoller(); 33 | 34 | virtual Timestamp poll(int timeoutMs, ChannelList* activeChannels); 35 | virtual void updateChannel(Channel* channel); 36 | virtual void removeChannel(Channel* channel); 37 | 38 | private: 39 | static const int kInitEventListSize = 16; 40 | 41 | static const char* operationToString(int op); 42 | 43 | void fillActiveChannels(int numEvents, 44 | ChannelList* activeChannels) const; 45 | void update(int operation, Channel* channel); 46 | 47 | typedef std::vector EventList; 48 | 49 | int epollfd_; 50 | EventList events_; 51 | }; 52 | 53 | } 54 | } 55 | #endif // MUDUO_NET_POLLER_EPOLLPOLLER_H 56 | -------------------------------------------------------------------------------- /third/muduo/net/poller/PollPoller.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010, Shuo Chen. All rights reserved. 2 | // http://code.google.com/p/muduo/ 3 | // 4 | // Use of this source code is governed by a BSD-style license 5 | // that can be found in the License file. 6 | 7 | // Author: Shuo Chen (chenshuo at chenshuo dot com) 8 | // 9 | // This is an internal header file, you should not include this. 10 | 11 | #ifndef MUDUO_NET_POLLER_POLLPOLLER_H 12 | #define MUDUO_NET_POLLER_POLLPOLLER_H 13 | 14 | #include 15 | 16 | #include 17 | 18 | struct pollfd; 19 | 20 | namespace muduo 21 | { 22 | namespace net 23 | { 24 | 25 | /// 26 | /// IO Multiplexing with poll(2). 27 | /// 28 | class PollPoller : public Poller 29 | { 30 | public: 31 | 32 | PollPoller(EventLoop* loop); 33 | virtual ~PollPoller(); 34 | 35 | virtual Timestamp poll(int timeoutMs, ChannelList* activeChannels); 36 | virtual void updateChannel(Channel* channel); 37 | virtual void removeChannel(Channel* channel); 38 | 39 | private: 40 | void fillActiveChannels(int numEvents, 41 | ChannelList* activeChannels) const; 42 | 43 | typedef std::vector PollFdList; 44 | PollFdList pollfds_; 45 | }; 46 | 47 | } 48 | } 49 | #endif // MUDUO_NET_POLLER_POLLPOLLER_H 50 | -------------------------------------------------------------------------------- /vs2015/realtinet/realtinet.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "realtinet", "realtinet\realtinet.vcxproj", "{5CFC9111-8856-44F7-9933-A5613304EF75}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {5CFC9111-8856-44F7-9933-A5613304EF75}.Debug|x64.ActiveCfg = Debug|x64 17 | {5CFC9111-8856-44F7-9933-A5613304EF75}.Debug|x64.Build.0 = Debug|x64 18 | {5CFC9111-8856-44F7-9933-A5613304EF75}.Debug|x86.ActiveCfg = Debug|Win32 19 | {5CFC9111-8856-44F7-9933-A5613304EF75}.Debug|x86.Build.0 = Debug|Win32 20 | {5CFC9111-8856-44F7-9933-A5613304EF75}.Release|x64.ActiveCfg = Release|x64 21 | {5CFC9111-8856-44F7-9933-A5613304EF75}.Release|x64.Build.0 = Release|x64 22 | {5CFC9111-8856-44F7-9933-A5613304EF75}.Release|x86.ActiveCfg = Release|Win32 23 | {5CFC9111-8856-44F7-9933-A5613304EF75}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | --------------------------------------------------------------------------------