├── .gitignore ├── CMakeLists.txt ├── README.md ├── net_test ├── CMakeLists.txt ├── dotest.cpp ├── echoclient.cpp ├── echoserver.cpp └── httpserver.cpp ├── sys_test ├── CMakeLists.txt ├── testBase.cpp ├── testBase.h ├── testCommon.h ├── testService.cpp ├── testThreadPool.cpp ├── testTimer.cpp ├── testconfig.conf ├── testconfig.cpp ├── testfilequeue.cpp ├── testfileutil.cpp ├── testlog.cpp ├── testnetutil.cpp ├── testqueuethread.cpp ├── teststringutil.cpp ├── testthread.cpp ├── testtimeutil.cpp └── testwarningbuffer.cpp ├── tbnet ├── CMakeLists.txt ├── channel.cpp ├── channel.h ├── channelpool.cpp ├── channelpool.h ├── connection.cpp ├── connection.h ├── connectionmanager.cpp ├── connectionmanager.h ├── controlpacket.cpp ├── controlpacket.h ├── databuffer.h ├── defaultpacketstreamer.cpp ├── defaultpacketstreamer.h ├── epollsocketevent.cpp ├── epollsocketevent.h ├── httppacketstreamer.cpp ├── httppacketstreamer.h ├── httprequestpacket.cpp ├── httprequestpacket.h ├── httpresponsepacket.cpp ├── httpresponsepacket.h ├── iocomponent.cpp ├── iocomponent.h ├── ipacketfactory.h ├── ipackethandler.h ├── ipacketstreamer.h ├── iserveradapter.h ├── packet.cpp ├── packet.h ├── packetqueue.cpp ├── packetqueue.h ├── packetqueuethread.cpp ├── packetqueuethread.h ├── serversocket.cpp ├── serversocket.h ├── socket.cpp ├── socket.h ├── socketevent.cpp ├── socketevent.h ├── stats.cpp ├── stats.h ├── tbnet.h ├── tcpacceptor.cpp ├── tcpacceptor.h ├── tcpcomponent.cpp ├── tcpcomponent.h ├── tcpconnection.cpp ├── tcpconnection.h ├── transport.cpp ├── transport.h ├── udpacceptor.h ├── udpcomponent.cpp ├── udpcomponent.h ├── udpconnection.cpp └── udpconnection.h └── tbsys ├── CMakeLists.txt ├── Cond.cpp ├── Cond.h ├── CtrlCHandler.cpp ├── CtrlCHandler.h ├── EventHandler.h ├── Exception.cpp ├── Exception.h ├── Functional.h ├── Handle.h ├── Lock.h ├── Memory.hpp ├── Monitor.h ├── Mutex.cpp ├── Mutex.h ├── Network.cpp ├── Network.h ├── PublicDefine.h ├── RecMutex.cpp ├── RecMutex.h ├── Service.cpp ├── Service.h ├── Shared.cpp ├── Shared.h ├── StaticMutex.cpp ├── StaticMutex.h ├── TbThread.cpp ├── TbThread.h ├── ThreadException.cpp ├── ThreadException.h ├── ThreadPool.cpp ├── ThreadPool.h ├── Time.cpp ├── Time.h ├── Timer.cpp ├── Timer.h ├── Utility.cpp ├── Utility.h ├── WarningBuffer.cpp ├── WarningBuffer.h ├── atomic.h ├── bytebuffer.cpp ├── bytebuffer.h ├── config.cpp ├── config.h ├── defaultrunnable.cpp ├── defaultrunnable.h ├── filequeue.cpp ├── filequeue.h ├── filequeuethread.cpp ├── filequeuethread.h ├── fileutil.cpp ├── fileutil.h ├── iqueuehandler.h ├── linklist.h ├── process.cpp ├── process.h ├── profiler.cpp ├── profiler.h ├── queuethread.cpp ├── queuethread.h ├── runnable.h ├── stringutil.cpp ├── stringutil.h ├── tblockguard.h ├── tblog.cpp ├── tblog.h ├── tbnetutil.cpp ├── tbnetutil.h ├── tbrwlock.cpp ├── tbrwlock.h ├── tbsys.h ├── tbtimeutil.cpp ├── tbtimeutil.h ├── thread.h ├── threadcond.h └── threadmutex.h /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### C++ template 3 | # Compiled Object files 4 | *.slo 5 | *.lo 6 | *.o 7 | *.obj 8 | 9 | # Precompiled Headers 10 | *.gch 11 | *.pch 12 | 13 | # Compiled Dynamic libraries 14 | *.so 15 | *.dylib 16 | *.dll 17 | 18 | # Fortran module files 19 | *.mod 20 | *.smod 21 | 22 | # Compiled Static libraries 23 | *.lai 24 | *.la 25 | *.a 26 | *.lib 27 | 28 | # Executables 29 | *.exe 30 | *.out 31 | *.app 32 | 33 | cmake-build-debug/ 34 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(tbnet) 2 | cmake_minimum_required(VERSION 2.8) 3 | add_definitions(-D_NO_EXCEPTION) 4 | add_definitions(-O0 -Wall -ggdb -std=c++0x) 5 | add_subdirectory(tbnet) 6 | add_subdirectory(tbsys) 7 | add_subdirectory(sys_test) 8 | add_subdirectory(net_test) 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## tbnet 2 | 3 | * tbnet cmake version 4 | * support CLion 5 | * generate almost all test case from original code 6 | * fix some compile bugs 7 | 8 | ## dependency 9 | 10 | I don't test the code except for Ubuntu 14.04 x64, the only dependency I need to install is CPPUNIT, and I run the command ```sudo apt-get install libcppunit-dev``` before compile the project. 11 | 12 | -------------------------------------------------------------------------------- /net_test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories(../tbnet/) 2 | include_directories(../tbsys/) 3 | 4 | add_executable(dotest dotest.cpp) 5 | target_link_libraries(dotest tbnet cppunit) 6 | 7 | add_executable(echoclient echoclient.cpp) 8 | target_link_libraries(echoclient tbnet) 9 | 10 | add_executable(echoserver echoserver.cpp) 11 | target_link_libraries(echoserver tbnet) 12 | 13 | add_executable(httpserver httpserver.cpp) 14 | target_link_libraries(httpserver tbnet) 15 | 16 | -------------------------------------------------------------------------------- /net_test/dotest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | /** 17 | * @author Zhang Li 18 | * @date 2008-06-25 17:09:40 19 | * @version $Id: dotest.cpp 6126 2008-06-26 05:10:20Z james.zhang $ 20 | * 21 | * @Descriptions: 22 | * Testing Suite for ANet library 23 | */ 24 | 25 | ///please install cppunit first, which in ubuntu you should run the command: sudo apt-get install libcppunit-dev 26 | 27 | #include 28 | #include 29 | 30 | using namespace CppUnit; 31 | using namespace std; 32 | 33 | int main(int argc, char **argv) 34 | { 35 | TextUi::TestRunner runner; 36 | TestFactoryRegistry ®istry = TestFactoryRegistry::getRegistry(); 37 | runner.addTest(registry.makeTest()); 38 | bool ok = runner.run("", false); 39 | return ok ? 0 : 1; 40 | } 41 | -------------------------------------------------------------------------------- /net_test/httpserver.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include "tbnet.h" 17 | 18 | using namespace tbnet; 19 | 20 | /** 21 | * packetµÄserverAdapter 22 | */ 23 | class HttpServerAdapter : public IServerAdapter 24 | { 25 | public: 26 | HttpServerAdapter(IPacketFactory *factory) 27 | { 28 | _factory = factory; 29 | } 30 | IPacketHandler::HPRetCode handlePacket(Connection *connection, Packet *packet) 31 | { 32 | HttpRequestPacket *request = (HttpRequestPacket *) packet; 33 | HttpResponsePacket *reply = (HttpResponsePacket *) _factory->createPacket(0); 34 | reply->setStatus(true); 35 | reply->setKeepAlive(request->isKeepAlive()); 36 | if (!request->isKeepAlive()) 37 | { 38 | connection->setWriteFinishClose(true); 39 | } 40 | char *query = request->getQuery(); 41 | if (query) 42 | { 43 | reply->setBody(query, strlen(query)); 44 | } 45 | request->free(); 46 | connection->postPacket(reply); 47 | return IPacketHandler::FREE_CHANNEL; 48 | } 49 | private: 50 | IPacketFactory *_factory; 51 | }; 52 | 53 | /* 54 | * server ·þÎñÆ÷ 55 | */ 56 | class HttpServer 57 | { 58 | public: 59 | HttpServer(char *spec); 60 | ~HttpServer(); 61 | void start(); 62 | void stop(); 63 | private: 64 | Transport _transport; 65 | char *_spec; 66 | }; 67 | 68 | HttpServer::HttpServer(char *spec) 69 | { 70 | _spec = strdup(spec); 71 | } 72 | 73 | HttpServer::~HttpServer() 74 | { 75 | if (_spec) 76 | { 77 | free(_spec); 78 | } 79 | } 80 | 81 | void HttpServer::start() 82 | { 83 | DefaultHttpPacketFactory factory; 84 | HttpPacketStreamer streamer(&factory); 85 | HttpServerAdapter serverAdapter(&factory); 86 | 87 | IOComponent *ioc = _transport.listen(_spec, &streamer, &serverAdapter); 88 | if (ioc == NULL) 89 | { 90 | TBSYS_LOG(ERROR, "listen error."); 91 | return; 92 | } 93 | _transport.start(); 94 | _transport.wait(); 95 | } 96 | 97 | void HttpServer::stop() 98 | { 99 | _transport.stop(); 100 | } 101 | 102 | HttpServer *_httpServer; 103 | void singalHandler(int seg) 104 | { 105 | _httpServer->stop(); 106 | } 107 | 108 | int main(int argc, char *argv[]) 109 | { 110 | if (argc != 2) 111 | { 112 | printf("%s [tcp|udp]:ip:port\n", argv[0]); 113 | return EXIT_FAILURE; 114 | } 115 | HttpServer httpServer(argv[1]); 116 | _httpServer = &httpServer; 117 | signal(SIGTERM, singalHandler); 118 | httpServer.start(); 119 | TBSYS_LOG(INFO, "exit."); 120 | return EXIT_SUCCESS; 121 | } 122 | 123 | 124 | -------------------------------------------------------------------------------- /sys_test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories(../tbsys) 2 | 3 | add_executable(testthread testthread.cpp testBase.cpp) 4 | target_link_libraries(testthread tbsys) 5 | 6 | add_executable(testconfig testconfig.cpp) 7 | target_link_libraries(testconfig tbsys) 8 | 9 | add_executable(testfilequeue testfilequeue.cpp) 10 | target_link_libraries(testfilequeue tbsys) 11 | 12 | add_executable(testlog testlog.cpp) 13 | target_link_libraries(testlog tbsys) 14 | 15 | add_executable(testnetutil testnetutil.cpp) 16 | target_link_libraries(testnetutil tbsys) 17 | 18 | add_executable(testThreadPool testThreadPool.cpp) 19 | target_link_libraries(testThreadPool tbsys) 20 | 21 | add_executable(testTimer testTimer.cpp) 22 | target_link_libraries(testTimer tbsys) 23 | 24 | add_executable(testtimeutil testtimeutil.cpp) 25 | target_link_libraries(testtimeutil tbsys) 26 | 27 | add_executable(testwarningbuffer testwarningbuffer.cpp) 28 | target_link_libraries(testwarningbuffer tbsys) 29 | 30 | add_executable(testService testService.cpp) 31 | target_link_libraries(testService tbsys) 32 | 33 | add_executable(teststringutil teststringutil.cpp) 34 | target_link_libraries(teststringutil tbsys) 35 | 36 | add_executable(testqueuethread testqueuethread.cpp) 37 | target_link_libraries(testqueuethread tbsys) 38 | 39 | add_executable(testfileutil testfileutil.cpp) 40 | target_link_libraries(testfileutil tbsys) -------------------------------------------------------------------------------- /sys_test/testBase.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include "testBase.h" 17 | #include 18 | using namespace std; 19 | using namespace tbutil; 20 | 21 | testFailed::testFailed(const std::string &name) : 22 | _name(name) 23 | { 24 | 25 | } 26 | 27 | testBase::testBase(const string &name) : 28 | _name(name) 29 | { 30 | 31 | } 32 | 33 | std::string testBase::name() const 34 | { 35 | return _name; 36 | } 37 | 38 | void testBase::start() 39 | { 40 | cout << "running " << _name << endl; 41 | try 42 | { 43 | run(); 44 | } 45 | catch (const Exception &e) 46 | { 47 | cout << e << " failed" << endl; 48 | throw testFailed(_name); 49 | } 50 | cout << " ok " << endl; 51 | } 52 | -------------------------------------------------------------------------------- /sys_test/testBase.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TNET_TEST_TESTBASE_H 17 | #define TNET_TEST_TESTBASE_H 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | using namespace tbutil; 24 | 25 | class testFailed 26 | { 27 | public: 28 | testFailed(const std::string &); 29 | 30 | const std::string _name; 31 | }; 32 | 33 | class testBase : public Shared 34 | { 35 | public: 36 | testBase(const std::string &); 37 | std::string name() const; 38 | void start(); 39 | protected: 40 | virtual void run()=0; 41 | const std::string _name; 42 | }; 43 | 44 | typedef tbutil::Handle testBasePtr; 45 | #endif 46 | -------------------------------------------------------------------------------- /sys_test/testCommon.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TEST_COMMON_H 17 | #define TEST_COMMON_H 18 | #include 19 | 20 | void inline testFailed(const char *expr, const char *file, unsigned int line) 21 | { 22 | std::cout << "failed!" << std::endl; 23 | std::cout << file << ':' << line << ": assertion `" << expr << "' failed" << std::endl; 24 | abort(); 25 | } 26 | 27 | #define test(ex) ((ex) ? ((void)0) : testFailed(#ex, __FILE__, __LINE__)) 28 | #endif 29 | -------------------------------------------------------------------------------- /sys_test/testService.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include "testCommon.h" 22 | #include 23 | 24 | using namespace tbutil; 25 | using namespace std; 26 | 27 | class testService : public Service 28 | { 29 | public: 30 | testService() {} 31 | ~testService() {} 32 | public: 33 | virtual int run(int argc, char *argv[], const std::string &config, std::string &errMsg) 34 | { 35 | //errMsg += "[ERROR]: this is test\r\n"; 36 | return 0; 37 | } 38 | virtual int interruptCallback(int signal) 39 | { 40 | switch (signal) 41 | { 42 | case SIGUSR1:printf("SIGUSR1\n"); 43 | break; 44 | case SIGPIPE:printf("SIGPIPE\n"); 45 | break; 46 | case SIGTERM:printf("SIGTERM\n"); 47 | break; 48 | case SIGINT:printf("SIGINT\n"); 49 | break; 50 | case SIGSEGV:printf("SIGSEGV\n"); 51 | break; 52 | case SIGABRT:printf("SIGABRT\n"); 53 | break; 54 | case 40:printf("40\n"); 55 | case SIGHUP:printf("SIGHUP\n"); 56 | break; 57 | } 58 | return 0; 59 | } 60 | virtual bool destroy() 61 | { 62 | return true; 63 | } 64 | }; 65 | 66 | int main(int argc, char *argv[]) 67 | { 68 | testService app; 69 | app.main(argc, argv); 70 | return 0; 71 | } 72 | 73 | -------------------------------------------------------------------------------- /sys_test/testThreadPool.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #include "testCommon.h" 21 | #include 22 | 23 | using namespace tbutil; 24 | using namespace std; 25 | 26 | static int64_t gCount; 27 | Monitor _monitor; 28 | 29 | static ThreadPool *pool = NULL; 30 | tbutil::Time gNow; 31 | tbutil::Time gStart; 32 | 33 | class TestWorkItems : public ThreadPoolWorkItem 34 | { 35 | public: 36 | TestWorkItems() 37 | { 38 | 39 | } 40 | virtual void execute(const ThreadPool *) 41 | { 42 | Monitor::Lock lock(_monitor); 43 | ++gCount; 44 | tbutil::Time now2 = tbutil::Time::now(); 45 | if ((now2 - gNow) >= tbutil::Time::seconds(10)) 46 | { 47 | gNow = now2; 48 | cout << "gCount: " << gCount << " , " << "Time: " << (now2 - gStart).toSeconds() << endl; 49 | } 50 | } 51 | 52 | virtual void destroy() 53 | { 54 | 55 | } 56 | 57 | }; 58 | 59 | class ScheduleTask : public TimerTask 60 | { 61 | public: 62 | 63 | ScheduleTask() 64 | { 65 | } 66 | 67 | virtual void 68 | runTimerTask() 69 | { 70 | for (register int i = 0; i < 0x100000; ++i) 71 | //for ( register int i = 0; i < 0x01; ++i ) 72 | { 73 | assert(pool != NULL); 74 | pool->execute(new TestWorkItems()); 75 | } 76 | } 77 | }; 78 | typedef Handle ScheduleTaskPtr; 79 | 80 | int main(int argc, char *argv[]) 81 | { 82 | gStart = tbutil::Time::now(); 83 | pool = new ThreadPool(2, 4, 3); 84 | TimerPtr timer = new tbutil::Timer(); 85 | 86 | cout << "testing threadpool... " << flush; 87 | { 88 | { 89 | ScheduleTaskPtr task = new ScheduleTask(); 90 | timer->scheduleRepeated(task, tbutil::Time::seconds(10)); 91 | ScheduleTaskPtr task1 = new ScheduleTask(); 92 | /*timer->scheduleRepeated(task1, tbutil::Time::seconds(1)); 93 | ScheduleTaskPtr task2 = new ScheduleTask(); 94 | timer->scheduleRepeated(task2, tbutil::Time::seconds(100)); 95 | ScheduleTaskPtr task3 = new ScheduleTask(); 96 | timer->scheduleRepeated(task3, tbutil::Time::seconds(130)); 97 | ScheduleTaskPtr task4 = new ScheduleTask(); 98 | timer->scheduleRepeated(task4, tbutil::Time::seconds(180)); 99 | ScheduleTaskPtr task5 = new ScheduleTask(); 100 | timer->scheduleRepeated(task5, tbutil::Time::seconds(220)); 101 | ScheduleTaskPtr task6 = new ScheduleTask(); 102 | timer->scheduleRepeated(task6, tbutil::Time::seconds(270));*/ 103 | } 104 | } 105 | 106 | sleep(0xfffff); 107 | timer->destroy(); 108 | pool->destroy(); 109 | pool->joinWithAllThreads(); 110 | delete pool; 111 | cout << "ok" << endl; 112 | return EXIT_SUCCESS; 113 | } 114 | 115 | -------------------------------------------------------------------------------- /sys_test/testconfig.conf: -------------------------------------------------------------------------------- 1 | [group_info] 2 | 3 | [test_section] 4 | string=hello 5 | int=123 6 | 7 | stringlist=hello1,hello5 8 | stringlist=hello2 9 | stringlist=hello3 10 | stringlist=hello4 11 | 12 | intlist=1 13 | intlist=2 14 | intlist=3 15 | -------------------------------------------------------------------------------- /sys_test/testconfig.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | #include 16 | #include 17 | 18 | using namespace tbsys; 19 | using namespace std; 20 | 21 | int main(int argc, char *argv[]) 22 | { 23 | if (argc < 2) 24 | { 25 | fprintf(stderr, "%s filename\n", argv[0]); 26 | return 1; 27 | } 28 | 29 | if (TBSYS_CONFIG.load(argv[1])) 30 | { 31 | fprintf(stderr, "load config failure: %s\n", argv[1]); 32 | } 33 | 34 | fprintf(stderr, "string=%s\n", TBSYS_CONFIG.getString("test_section", "string")); 35 | fprintf(stderr, "int=%d\n", TBSYS_CONFIG.getInt("test_section", "int")); 36 | 37 | vector strList = TBSYS_CONFIG.getStringList("test_section", "stringlist"); 38 | for (int i = 0; i < (int) strList.size(); i++) 39 | { 40 | fprintf(stderr, "string%d=%s\n", i + 1, strList[i]); 41 | } 42 | 43 | vector intList = TBSYS_CONFIG.getIntList("test_section", "intlist"); 44 | for (int i = 0; i < (int) intList.size(); i++) 45 | { 46 | fprintf(stderr, "int%d=%d\n", i + 1, intList[i]); 47 | } 48 | 49 | // getSectionKey(char *section, vector &keys) 50 | vector keys; 51 | TBSYS_CONFIG.getSectionKey("test_section", keys); 52 | for (uint32_t i = 0; i < keys.size(); i++) 53 | { 54 | fprintf(stderr, "key_%d=%s\n", i + 1, keys[i].c_str()); 55 | } 56 | 57 | fprintf(stderr, "\n%s\n", TBSYS_CONFIG.toString().c_str()); 58 | 59 | return 0; 60 | } 61 | 62 | -------------------------------------------------------------------------------- /sys_test/testfilequeue.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include 17 | 18 | using namespace tbsys; 19 | 20 | int mWriteCount = 1000; 21 | atomic_t mReadCount; 22 | CFileQueueThread *mQueueThread = NULL; 23 | 24 | class CMyHandler : public IQueueHandler 25 | { 26 | public: 27 | bool handleQueue(void *data, int len, int threadIndex, void *arg) 28 | { 29 | //printf("TEST==> read_thread: %lu(%d) %d (%s)\n", pthread_self(), threadIndex, len, (char*)data); 30 | fflush(stdout); 31 | if (mWriteCount == atomic_add_return(1, &mReadCount) && mQueueThread) 32 | { 33 | mQueueThread->stop(); 34 | mQueueThread = NULL; 35 | } 36 | return 0; 37 | } 38 | }; 39 | 40 | int main(int argc, char *argv[]) 41 | { 42 | atomic_set(&mReadCount, 0); 43 | char testqueue[64]; 44 | 45 | if (argc > 1) 46 | { 47 | mWriteCount = atoi(argv[1]); 48 | } 49 | sprintf(testqueue, "q_%d_%d", getpid(), rand()); 50 | CFileQueue queue("/tmp/queue", testqueue); 51 | CMyHandler handler; 52 | CFileQueueThread queueThread(&queue, 3, &handler, NULL); 53 | mQueueThread = &queueThread; 54 | queueThread.start(); 55 | char data[1024]; 56 | for (int i = 1; i <= mWriteCount; i++) 57 | { 58 | int len = sprintf(data, "data_%05d", i); 59 | queueThread.writeData(data, len + 1); 60 | //printf("TEST==> writeData: %d, (%s)\n", i, data); 61 | fflush(stdout); 62 | //if (rand() % 111 == 0) { 63 | //usleep(100000); 64 | //} 65 | } 66 | queueThread.wait(); 67 | printf("mReadCount: %d\n", atomic_read(&mReadCount)); 68 | printf("OK\n"); 69 | return 0; 70 | } 71 | 72 | -------------------------------------------------------------------------------- /sys_test/testfileutil.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include 17 | 18 | using namespace tbsys; 19 | 20 | int main(int argc, char *argv[]) 21 | { 22 | char str[1024]; 23 | strcpy(str, "/tmp/src/lcp/.svn/text-base"); 24 | printf("ret: %d\n", tbsys::CFileUtil::mkdirs(str)); 25 | 26 | strcpy(str, "/tmp/lcp/ltmain.sh"); 27 | printf("is sym: ret: %d\n", tbsys::CFileUtil::isSymLink(str)); 28 | return 0; 29 | } 30 | 31 | -------------------------------------------------------------------------------- /sys_test/testlog.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include 17 | #include 18 | 19 | using namespace tbsys; 20 | 21 | int main(int argc, char *argv[]) 22 | { 23 | TBSYS_LOG(INFO, "xxx: %s:%d", "xxxx", 1); 24 | TBSYS_LOG(ERROR, "xxx: %s:%d", "xxxx", 1); 25 | 26 | TBSYS_LOGGER.setFileName("/tmp/test.txt"); 27 | 28 | for (int i = 0; i < 50; i++) 29 | { 30 | TBSYS_LOG(ERROR, "xxx: %s:%d", "xxxx", i); 31 | TBSYS_LOG(WARN, "xxx: %s:%d", "xxxx", i); 32 | TBSYS_LOG(INFO, "xxx: %s:%d", "xxxx", i); 33 | TBSYS_LOG(DEBUG, "xxx: %s:%d", "xxxx", i); 34 | //getchar(); 35 | } 36 | //test rotateLog() 37 | CLogger logger; 38 | logger.setFileName("/tmp/test.log", false, true); 39 | logger.setLogLevel("INFO"); 40 | logger.setMaxFileIndex(100); 41 | for (int i = 0; i < 10; i++) 42 | { 43 | for (int j = 0; j < 50; j++) 44 | { 45 | logger.logMessage(TBSYS_LOG_LEVEL_ERROR, __FILE__, __LINE__, __FUNCTION__, 46 | pthread_self(), "test rotateLog(): %d", j); 47 | } 48 | logger.rotateLog(NULL); 49 | sleep(2); 50 | } 51 | 52 | return 0; 53 | } 54 | 55 | -------------------------------------------------------------------------------- /sys_test/testnetutil.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | using namespace __gnu_cxx; 23 | using namespace std; 24 | 25 | using namespace tbsys; 26 | 27 | int _UUID_Count = time(NULL); 28 | int _UUID_HostIp = 0; 29 | 30 | uint64_t newUUID() 31 | { 32 | uint64_t id = (_UUID_HostIp & 0xFFFFFF00); 33 | id <<= 8; 34 | id |= getpid(); 35 | id <<= 24; 36 | id |= (++_UUID_Count & 0xFFFFFF); 37 | return id; 38 | } 39 | 40 | void test1() 41 | { 42 | set m; 43 | uint64_t x; 44 | int port = 1234; 45 | x = CNetUtil::strToAddr("192.168.207.11", port); 46 | m.insert(x); 47 | x = CNetUtil::strToAddr("192.168.207.12", port); 48 | m.insert(x); 49 | x = CNetUtil::strToAddr("192.168.207.12", port + 1); 50 | m.insert(x); 51 | x = CNetUtil::strToAddr("192.168.207.12", port - 1); 52 | m.insert(x); 53 | x = CNetUtil::strToAddr("92.168.207.191", port); 54 | m.insert(x); 55 | x = CNetUtil::strToAddr("172.168.207.192", port); 56 | m.insert(x); 57 | x = CNetUtil::strToAddr("172.168.207.12", port); 58 | m.insert(x); 59 | x = CNetUtil::strToAddr("172.169.207.12", port); 60 | m.insert(x); 61 | x = CNetUtil::strToAddr("172.168.207.13", port); 62 | m.insert(x); 63 | x = CNetUtil::strToAddr("182.168.207.11", port); 64 | m.insert(x); 65 | x = CNetUtil::strToAddr("182.168.207.12", port); 66 | m.insert(x); 67 | x = CNetUtil::strToAddr("182.169.207.12", port); 68 | m.insert(x); 69 | x = CNetUtil::strToAddr("182.168.207.13", port); 70 | m.insert(x); 71 | set::iterator it; 72 | for (it = m.begin(); it != m.end(); ++it) 73 | { 74 | fprintf(stderr, "%s\n", CNetUtil::addrToString(*it).c_str()); 75 | } 76 | } 77 | 78 | int main(int argc, char *argv[]) 79 | { 80 | //test1(); 81 | char *ip = "192.168.207.158:2089"; 82 | int port = 2071; 83 | uint32_t ipx = CNetUtil::getLocalAddr(NULL); 84 | unsigned char *bytes = (unsigned char *) &ipx; 85 | ipx <<= 8; 86 | int index = 1; 87 | while (ipx != 0) 88 | { 89 | fprintf(stderr, "ip: "); 90 | for (int i = index; i < 4; i++) 91 | { 92 | fprintf(stderr, "%d.", bytes[i]); 93 | } 94 | fprintf(stderr, "\n"); 95 | ipx <<= 8; 96 | index++; 97 | } 98 | _UUID_HostIp = ipx; 99 | uint32_t ipx1 = CNetUtil::getAddr("192.168.207.157"); 100 | fprintf(stderr, "ipx: %X, ipx1: %X\n", ipx, ipx1); 101 | uint64_t uuid; 102 | for (int i = 0; i < 10; i++) 103 | { 104 | uuid = newUUID(); 105 | fprintf(stderr, "uuid: %llu, %llX\n", uuid, uuid); 106 | } 107 | 108 | uint64_t x = CNetUtil::strToAddr(ip, port); 109 | uint64_t x1 = CNetUtil::ipToAddr(ipx, port); 110 | 111 | fprintf(stderr, "x: %llu, %llu %s\n", x, x1, CNetUtil::addrToString(x).c_str()); 112 | 113 | return 0; 114 | } 115 | 116 | -------------------------------------------------------------------------------- /sys_test/testqueuethread.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include 17 | 18 | using namespace tbsys; 19 | 20 | int mWriteCount = 1000; 21 | atomic_t mReadCount; 22 | CQueueThread *mQueueThread = NULL; 23 | 24 | class CMyHandler : public IQueueHandler 25 | { 26 | public: 27 | bool handleQueue(void *data, int len, int threadIndex, void *arg) 28 | { 29 | // printf("TEST==> read_thread: %lu(%d) %d (%s)\n", pthread_self(), threadIndex, len, (char*)data); 30 | // fflush(stdout); 31 | if (mWriteCount == atomic_add_return(1, &mReadCount) && mQueueThread) 32 | { 33 | mQueueThread->stop(); 34 | mQueueThread = NULL; 35 | } 36 | return 0; 37 | } 38 | }; 39 | 40 | int main(int argc, char *argv[]) 41 | { 42 | if (argc > 1) 43 | { 44 | mWriteCount = atoi(argv[1]); 45 | } 46 | CMyHandler handler; 47 | CQueueThread queueThread(3, &handler, NULL); 48 | mQueueThread = &queueThread; 49 | queueThread.start(); 50 | char data[1024]; 51 | for (int i = 1; i <= mWriteCount; i++) 52 | { 53 | int len = sprintf(data, "data_%05d", i); 54 | queueThread.writeData(data, len + 1); 55 | // printf("TEST==> writeData: %d, (%s)\n", i, data); 56 | // fflush(stdout); 57 | //if (rand() % 111 == 0) { 58 | //usleep(100000); 59 | //} 60 | } 61 | queueThread.wait(); 62 | 63 | printf("mReadCount: %d\n", atomic_read(&mReadCount)); 64 | printf("OK\n"); 65 | 66 | return 0; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /sys_test/teststringutil.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | #include 16 | #include 17 | 18 | using namespace tbsys; 19 | 20 | int main(int argc, char *argv[]) 21 | { 22 | 23 | char s[100]; 24 | for (int i = 0; i < 10; i++) 25 | { 26 | int len = sprintf(s, "˛âĘÔ_test_%d", i); 27 | fprintf(stderr, "%s => %u\n", s, CStringUtil::murMurHash(s, len)); 28 | } 29 | uint64_t x = 1; 30 | for (int i = 0; i < 7; i++) 31 | { 32 | fprintf(stderr, "%ld => %s\n", x, CStringUtil::formatByteSize(x).c_str()); 33 | x *= 1022; 34 | } 35 | 36 | return 0; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /sys_test/testtimeutil.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | using namespace tbsys; 21 | 22 | int main(int argc, char *argv[]) 23 | { 24 | int i = 0; 25 | printf("i:%d\n", i); 26 | i = CTimeUtil::strToTime("20090101121212"); 27 | i = CTimeUtil::strToTime("20090101121212"); 28 | i = CTimeUtil::strToTime("20090101121212"); 29 | i = CTimeUtil::strToTime("20090101121212"); 30 | i = CTimeUtil::strToTime("20090101121212"); 31 | printf("i:%d\n", i); 32 | return 0; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /tbnet/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories(../tbsys/) 2 | 3 | set(source 4 | databuffer.h 5 | ipacketfactory.h 6 | ipackethandler.h 7 | ipacketstreamer.h 8 | iserveradapter.h 9 | udpacceptor.h 10 | tbnet.h 11 | channel.cpp 12 | channelpool.cpp 13 | connection.cpp 14 | connectionmanager.cpp 15 | controlpacket.cpp 16 | defaultpacketstreamer.cpp 17 | epollsocketevent.cpp 18 | httppacketstreamer.cpp 19 | httprequestpacket.cpp 20 | httpresponsepacket.cpp 21 | iocomponent.cpp 22 | iocomponent.cpp 23 | packet.cpp 24 | packetqueue.cpp 25 | packetqueuethread.cpp 26 | serversocket.cpp 27 | socket.cpp 28 | socketevent.cpp 29 | stats.cpp 30 | tcpacceptor.cpp 31 | tcpcomponent.cpp 32 | tcpconnection.cpp 33 | transport.cpp 34 | udpcomponent.cpp 35 | udpconnection.cpp 36 | ) 37 | 38 | add_library(tbnet ${source}) 39 | target_link_libraries(tbnet tbsys) 40 | -------------------------------------------------------------------------------- /tbnet/channel.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include "tbnet.h" 17 | 18 | namespace tbnet 19 | { 20 | 21 | /* 22 | * 构造函数 23 | */ 24 | Channel::Channel() 25 | { 26 | _prev = NULL; 27 | _next = NULL; 28 | _expireTime = 0; 29 | } 30 | 31 | /* 32 | * 设置 33 | * 34 | * @param chid ChannelId 35 | */ 36 | void Channel::setId(uint32_t id) 37 | { 38 | _id = id; 39 | } 40 | 41 | /* 42 | * 得到ID 43 | */ 44 | uint32_t Channel::getId() 45 | { 46 | return _id; 47 | } 48 | 49 | void Channel::setArgs(void *args) 50 | { 51 | _args = args; 52 | } 53 | 54 | void *Channel::getArgs() 55 | { 56 | return _args; 57 | } 58 | 59 | void Channel::setHandler(IPacketHandler *handler) 60 | { 61 | _handler = handler; 62 | } 63 | 64 | IPacketHandler *Channel::getHandler() 65 | { 66 | return _handler; 67 | } 68 | 69 | /* 70 | * 设置过期时间 71 | * 72 | * @param milliseconds 毫秒数, 0为永不过期 73 | */ 74 | void Channel::setExpireTime(int64_t expireTime) 75 | { 76 | _expireTime = expireTime; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /tbnet/channel.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBNET_CHANNEL_H_ 17 | #define TBNET_CHANNEL_H_ 18 | 19 | namespace tbnet 20 | { 21 | 22 | class Channel 23 | { 24 | friend class ChannelPool; 25 | 26 | public: 27 | /* 28 | * 构造函数 29 | */ 30 | Channel(); 31 | 32 | /* 33 | * 设置 34 | * 35 | * @param chid ChannelID 36 | */ 37 | void setId(uint32_t id); 38 | 39 | /* 40 | * 得到Channel ID 41 | */ 42 | uint32_t getId(); 43 | 44 | /* 45 | * 设置回传参数 46 | */ 47 | void setArgs(void *args); 48 | 49 | /* 50 | * 取到回传参数 51 | */ 52 | void *getArgs(); 53 | 54 | /* 55 | * 设置packethandler的句柄 56 | */ 57 | void setHandler(IPacketHandler *handler); 58 | 59 | /* 60 | * 得到句柄 61 | */ 62 | IPacketHandler *getHandler(); 63 | 64 | /* 65 | * 设置过期时间, 绝对时间 66 | * 67 | * @param expireTime 68 | */ 69 | void setExpireTime(int64_t expireTime); 70 | 71 | /* 过期时间 */ 72 | int64_t getExpireTime() 73 | { 74 | return _expireTime; 75 | } 76 | 77 | /* 78 | * 下一个 79 | */ 80 | Channel *getNext() 81 | { 82 | return _next; 83 | } 84 | 85 | private: 86 | uint32_t _id; // channel id 87 | void *_args; // 回传参数 88 | IPacketHandler *_handler; 89 | int64_t _expireTime; // 到期时间 90 | 91 | private: 92 | Channel *_prev; // 用在链表 93 | Channel *_next; 94 | }; 95 | } 96 | 97 | #endif /*CONNECTION_H_*/ 98 | -------------------------------------------------------------------------------- /tbnet/channelpool.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBNET_CHANNEL_POOL_H_ 17 | #define TBNET_CHANNEL_POOL_H_ 18 | 19 | #define CHANNEL_CLUSTER_SIZE 25 20 | namespace tbnet 21 | { 22 | 23 | class ChannelPool 24 | { 25 | 26 | public: 27 | /* 28 | * 构造函数 29 | */ 30 | ChannelPool(); 31 | 32 | /* 33 | * 析构函数 34 | */ 35 | ~ChannelPool(); 36 | 37 | /* 38 | * 得到一个新的channel 39 | * 40 | * @return 一个Channel 41 | */ 42 | Channel *allocChannel(); 43 | 44 | /* 45 | * 释放一个channel 46 | * 47 | * @param channel: 要释放的channel 48 | * @return 49 | */ 50 | bool freeChannel(Channel *channel); 51 | bool appendChannel(Channel *channel); 52 | 53 | /* 54 | * 查找一下channel 55 | * 56 | * @param id: channel id 57 | * @return Channel 58 | */ 59 | Channel *offerChannel(uint32_t id); 60 | 61 | /* 62 | * 从useList中找出超时的channel的list,并把hashmap中对应的删除 63 | * 64 | * @param now: 当前时间 65 | */ 66 | Channel *getTimeoutList(int64_t now); 67 | 68 | /* 69 | * 把addList的链表加入到freeList中 70 | * 71 | * @param addList被加的list 72 | */ 73 | bool appendFreeList(Channel *addList); 74 | 75 | /* 76 | * 被用链表的长度 77 | */ 78 | int getUseListCount() 79 | { 80 | return static_cast(_useMap.size()); 81 | } 82 | 83 | void setExpireTime(Channel *channel, int64_t now); 84 | 85 | private: 86 | __gnu_cxx::hash_map _useMap; // 使用的map 87 | std::list _clusterList; // cluster list 88 | tbsys::CThreadMutex _mutex; 89 | 90 | Channel *_freeListHead; // 空的链表 91 | Channel *_freeListTail; 92 | Channel *_useListHead; // 被使用的链表 93 | Channel *_useListTail; 94 | int _maxUseCount; // 被用链表的长度 95 | 96 | static atomic_t _globalChannelId; // 生成统一的id 97 | static atomic_t _globalTotalCount; 98 | }; 99 | 100 | } 101 | 102 | #endif /*CHANNEL_POOL_H_*/ 103 | -------------------------------------------------------------------------------- /tbnet/connectionmanager.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBNET_CONNECTION_MANAGER_H_ 17 | #define TBNET_CONNECTION_MANAGER_H_ 18 | 19 | #include 20 | //using namespace __gnu_cxx; 21 | 22 | namespace tbnet 23 | { 24 | 25 | typedef __gnu_cxx::hash_map > TBNET_CONN_MAP; 26 | 27 | class ConnectionManager 28 | { 29 | public: 30 | /* 31 | * 构造函数 32 | */ 33 | ConnectionManager(Transport *transport, IPacketStreamer *streamer, IPacketHandler *packetHandler); 34 | 35 | /* 36 | * 析构函数 37 | */ 38 | ~ConnectionManager(); 39 | 40 | /** 41 | * 打开连接 42 | */ 43 | Connection *connect(uint64_t serverId, IPacketHandler *packetHandler, int queueLimit, int queueTimeout); 44 | 45 | /** 46 | * 关闭连接 47 | */ 48 | void disconnect(uint64_t serverId); 49 | 50 | /** 51 | * 设置 _queueLimit 52 | */ 53 | void setDefaultQueueLimit(uint64_t serverId, int queueLimit); 54 | 55 | /** 56 | * 设置 _queueTimeout 57 | */ 58 | void setDefaultQueueTimeout(uint64_t serverId, int queueTimeout); 59 | 60 | /** 61 | * 设置packetHandler 62 | */ 63 | void setDefaultPacketHandler(uint64_t serverId, IPacketHandler *packetHandler); 64 | 65 | /** 66 | * 发送数据包 67 | */ 68 | bool sendPacket(uint64_t serverId, 69 | Packet *packet, 70 | IPacketHandler *packetHandler = NULL, 71 | void *args = NULL, 72 | bool noblocking = true); 73 | 74 | /** 75 | * destroy 76 | */ 77 | void cleanup(); 78 | 79 | /** 80 | * 得到一连接 81 | */ 82 | Connection *getConnection(uint64_t serverId); 83 | 84 | /** 85 | * 是否能被连接 86 | */ 87 | static bool isAlive(uint64_t serverId); 88 | 89 | private: 90 | Transport *_transport; 91 | IPacketStreamer *_streamer; 92 | IPacketHandler *_packetHandler; 93 | int _queueLimit; 94 | int _queueTimeout; 95 | int _status; 96 | 97 | TBNET_CONN_MAP _connectMap; 98 | tbsys::CThreadMutex _mutex; 99 | }; 100 | 101 | } 102 | 103 | #endif 104 | 105 | -------------------------------------------------------------------------------- /tbnet/controlpacket.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include "tbnet.h" 17 | 18 | namespace tbnet 19 | { 20 | ControlPacket ControlPacket::BadPacket(CMD_BAD_PACKET); 21 | ControlPacket ControlPacket::TimeoutPacket(CMD_TIMEOUT_PACKET); 22 | ControlPacket ControlPacket::DisconnPacket(CMD_DISCONN_PACKET); 23 | } 24 | -------------------------------------------------------------------------------- /tbnet/controlpacket.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBNET_CONTROL_PACKET_H_ 17 | #define TBNET_CONTROL_PACKET_H_ 18 | #ifndef UNUSED 19 | #define UNUSED(v) ((void)(v)) 20 | #endif 21 | 22 | namespace tbnet 23 | { 24 | 25 | class ControlPacket : public Packet 26 | { 27 | public: 28 | enum 29 | { 30 | CMD_BAD_PACKET = 1, 31 | CMD_TIMEOUT_PACKET, 32 | CMD_DISCONN_PACKET 33 | }; 34 | 35 | static ControlPacket BadPacket; 36 | static ControlPacket TimeoutPacket; 37 | static ControlPacket DisconnPacket; 38 | 39 | public: 40 | /* 41 | * 构造函数, 传包类型 42 | */ 43 | ControlPacket(int c) : _command(c) {} 44 | 45 | /* 46 | * 是否数据包 47 | */ 48 | bool isRegularPacket() 49 | { 50 | return false; 51 | } 52 | 53 | void free() {} 54 | 55 | /* 56 | * 计算出数据包的长度 57 | */ 58 | void countDataLen() {} 59 | 60 | /* 61 | * 组装 62 | */ 63 | bool encode(DataBuffer *output) 64 | { 65 | UNUSED(output); 66 | return false; 67 | } 68 | 69 | /* 70 | * 解开 71 | */ 72 | bool decode(DataBuffer *input, PacketHeader *header) 73 | { 74 | UNUSED(input); 75 | UNUSED(header); 76 | return false; 77 | } 78 | 79 | /* 80 | * 得到类型 81 | */ 82 | int getCommand() 83 | { 84 | return _command; 85 | } 86 | 87 | private: 88 | int _command; 89 | }; 90 | 91 | } 92 | 93 | #endif /*PACKET_H_*/ 94 | -------------------------------------------------------------------------------- /tbnet/defaultpacketstreamer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBNET_DEFAULT_PACKET_STREAMER_H_ 17 | #define TBNET_DEFAULT_PACKET_STREAMER_H_ 18 | 19 | namespace tbnet 20 | { 21 | 22 | class DefaultPacketStreamer : public IPacketStreamer 23 | { 24 | 25 | public: 26 | /* 27 | * 构造函数 28 | */ 29 | DefaultPacketStreamer(); 30 | 31 | /* 32 | * 构造函数 33 | */ 34 | DefaultPacketStreamer(IPacketFactory *factory); 35 | 36 | /* 37 | * 析造函数 38 | */ 39 | ~DefaultPacketStreamer(); 40 | 41 | /** 42 | * 设置IPacketFactory 43 | */ 44 | void setPacketFactory(IPacketFactory *factory); 45 | 46 | /* 47 | * 得到包头信息 48 | * 49 | * @param input 源buffer 50 | * @param header 结果header 51 | * @return 是否成功 52 | */ 53 | bool getPacketInfo(DataBuffer *input, PacketHeader *header, bool *broken); 54 | 55 | /* 56 | * 对包的解码 57 | * 58 | * @param input 59 | * @param header 60 | * @return 解码后的数据包 61 | */ 62 | Packet *decode(DataBuffer *input, PacketHeader *header); 63 | 64 | /* 65 | * 对Packet的组装 66 | * 67 | * @param packet 数据包 68 | * @param output 组装后的数据流 69 | * @return 是否成功 70 | */ 71 | bool encode(Packet *packet, DataBuffer *output); 72 | 73 | /* 74 | * 设置packet的flag 75 | */ 76 | static void setPacketFlag(int flag); 77 | 78 | public: 79 | static int _nPacketFlag; 80 | }; 81 | 82 | } 83 | 84 | #endif /*DEFAULT_PACKET_STREAMER_H_*/ 85 | -------------------------------------------------------------------------------- /tbnet/epollsocketevent.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBNET_EPOLLSOCKETEVENT_H_ 17 | #define TBNET_EPOLLSOCKETEVENT_H_ 18 | 19 | namespace tbnet 20 | { 21 | 22 | class EPollSocketEvent : public SocketEvent 23 | { 24 | 25 | public: 26 | /* 27 | * 构造函数 28 | */ 29 | EPollSocketEvent(); 30 | 31 | /* 32 | * 析造函数 33 | */ 34 | ~EPollSocketEvent(); 35 | 36 | /* 37 | * 增加Socket到事件中 38 | * 39 | * @param socket 被加的socket 40 | * @param enableRead: 设置是否可读 41 | * @param enableWrite: 设置是否可写 42 | * @return 操作是否成功, true – 成功, false – 失败 43 | */ 44 | bool addEvent(Socket *socket, bool enableRead, bool enableWrite); 45 | 46 | /* 47 | * 设置删除Socket到事件中 48 | * 49 | * @param socket 被加的socket 50 | * @param enableRead: 设置是否可读 51 | * @param enableWrite: 设置是否可写 52 | * @return 操作是否成功, true – 成功, false – 失败 53 | */ 54 | bool setEvent(Socket *socket, bool enableRead, bool enableWrite); 55 | 56 | /* 57 | * 删除Socket到事件中 58 | * 59 | * @param socket 被删除socket 60 | * @return 操作是否成功, true – 成功, false – 失败 61 | */ 62 | bool removeEvent(Socket *socket); 63 | 64 | /* 65 | * 得到读写事件。 66 | * 67 | * @param timeout 超时时间(单位:ms) 68 | * @param events 事件数组 69 | * @param cnt events的数组大小 70 | * @return 事件数, 0为超时 71 | */ 72 | int getEvents(int timeout, IOEvent *events, int cnt); 73 | 74 | private: 75 | int _iepfd; // epoll的fd 76 | // tbsys::CThreadMutex _mutex; // 对fd操作加锁 77 | }; 78 | } 79 | 80 | #endif /*EPOLLSOCKETEVENT_H_*/ 81 | 82 | -------------------------------------------------------------------------------- /tbnet/httppacketstreamer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include "tbnet.h" 17 | 18 | namespace tbnet 19 | { 20 | /* 21 | * 构造函数 22 | */ 23 | HttpPacketStreamer::HttpPacketStreamer() 24 | { 25 | _httpPacketCode = 1; 26 | _existPacketHeader = false; // 不要输出头信息 27 | } 28 | /* 29 | * 构造函数 30 | */ 31 | 32 | HttpPacketStreamer::HttpPacketStreamer(IPacketFactory *factory) : DefaultPacketStreamer(factory) 33 | { 34 | _httpPacketCode = 1; 35 | _existPacketHeader = false; // 不要输出头信息 36 | } 37 | 38 | /* 39 | * 数据包信息的设置 40 | */ 41 | bool HttpPacketStreamer::getPacketInfo(DataBuffer *input, PacketHeader *header, bool *broken) 42 | { 43 | if (input->getDataLen() == 0) 44 | { 45 | return false; 46 | } 47 | char *data = input->getData(); 48 | int cmplen = input->getDataLen(); 49 | if (cmplen > 4) 50 | { 51 | cmplen = 4; 52 | } 53 | if (memcmp(data, "GET ", cmplen)) 54 | { 55 | *broken = true; 56 | return false; 57 | } 58 | 59 | int nr = input->findBytes("\r\n\r\n", 4); 60 | if (nr < 0) 61 | { 62 | return false; 63 | } 64 | 65 | header->_pcode = _httpPacketCode; 66 | header->_chid = 0; 67 | header->_dataLen = nr + 4; 68 | return true; 69 | } 70 | 71 | } 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /tbnet/httppacketstreamer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBNET_HTTP_PACKET_STREAMER_H 17 | #define TBNET_HTTP_PACKET_STREAMER_H 18 | 19 | namespace tbnet 20 | { 21 | 22 | class HttpPacketStreamer : public DefaultPacketStreamer 23 | { 24 | public: 25 | /* 26 | * 构造函数 27 | */ 28 | HttpPacketStreamer(); 29 | /* 30 | * 构造函数 31 | */ 32 | HttpPacketStreamer(IPacketFactory *factory); 33 | /* 34 | * 数据包信息的设置 35 | */ 36 | bool getPacketInfo(DataBuffer *input, PacketHeader *header, bool *broken); 37 | /* 38 | * 设置_httpPacketCode 39 | */ 40 | void setHttpPacketCode(int code) 41 | { 42 | _httpPacketCode = code; 43 | } 44 | private: 45 | int _httpPacketCode; 46 | }; 47 | 48 | /** 49 | * packet的factory, 缺省的httpd packet factory 50 | * 51 | * pcode = 1 是请求包 52 | * pcode = 0 是响应包 53 | */ 54 | class DefaultHttpPacketFactory : public IPacketFactory 55 | { 56 | public: 57 | Packet *createPacket(int pcode) 58 | { 59 | if (pcode == 1) 60 | { 61 | return new HttpRequestPacket(); 62 | } 63 | else 64 | { 65 | return new HttpResponsePacket(); 66 | } 67 | } 68 | }; 69 | 70 | } 71 | 72 | #endif 73 | 74 | -------------------------------------------------------------------------------- /tbnet/httprequestpacket.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include "tbnet.h" 17 | 18 | namespace tbnet 19 | { 20 | 21 | /* 22 | * 构造函数 23 | */ 24 | HttpRequestPacket::HttpRequestPacket() 25 | { 26 | _strHeader = NULL; 27 | _strQuery = NULL; 28 | _isKeepAlive = false; 29 | _method = 0; 30 | } 31 | 32 | /* 33 | * 析构函数 34 | */ 35 | HttpRequestPacket::~HttpRequestPacket() 36 | { 37 | if (_strHeader) 38 | { 39 | ::free(_strHeader); 40 | } 41 | } 42 | 43 | /* 44 | * 组装 45 | */ 46 | bool HttpRequestPacket::encode(DataBuffer *output) 47 | { 48 | return true; 49 | } 50 | 51 | /* 52 | * 解开 53 | */ 54 | bool HttpRequestPacket::decode(DataBuffer *input, PacketHeader *header) 55 | { 56 | int len = header->_dataLen; 57 | _strHeader = (char *) malloc(len + 1); 58 | input->readBytes(_strHeader, len); 59 | _strHeader[len] = '\0'; 60 | int line = 0; 61 | int first = 1; 62 | 63 | char *p, *name = NULL, *value; 64 | p = value = _strHeader; 65 | while (*p) 66 | { 67 | // 找每一行 68 | if (*p == '\r' && *(p + 1) == '\n') 69 | { 70 | if (value == p && line > 0) 71 | { // header 结束了 72 | break; 73 | } 74 | *p = '\0'; 75 | // 去前空格 76 | while (*value == ' ') 77 | { 78 | value++; 79 | } 80 | if (line > 0) 81 | { 82 | if (strcmp(name, "Connection") == 0 && strcasecmp(value, "Keep-Alive") == 0) 83 | { 84 | _isKeepAlive = true; 85 | } 86 | else 87 | { 88 | _headerMap[name] = value; 89 | } 90 | } 91 | else 92 | { 93 | _strQuery = value; 94 | } 95 | value = p + 2; 96 | line++; 97 | first = 1; 98 | } 99 | else if (line == 0 && *p == ' ') 100 | { // 首行 101 | if (_method) 102 | { 103 | *p = '\0'; 104 | } 105 | else if (strncmp(value, "GET ", 4) == 0) 106 | { // 是GET 方法 107 | _method = 1; 108 | value = p + 1; 109 | } 110 | } 111 | else if (*p == ':' && first == 1) 112 | { 113 | *p = '\0'; 114 | name = value; 115 | value = p + 1; 116 | first = 0; 117 | } 118 | p++; 119 | } 120 | 121 | return true; 122 | } 123 | 124 | /* 125 | * 查询串 126 | */ 127 | char *HttpRequestPacket::getQuery() 128 | { 129 | return _strQuery; 130 | } 131 | 132 | /* 133 | * 是否keepalive 134 | */ 135 | bool HttpRequestPacket::isKeepAlive() 136 | { 137 | return _isKeepAlive; 138 | } 139 | 140 | /* 141 | * 寻找其他头信息 142 | */ 143 | const char *HttpRequestPacket::findHeader(const char *name) 144 | { 145 | PSTR_MAP_ITER it = _headerMap.find(name); 146 | if (it != _headerMap.end()) 147 | { 148 | return it->second; 149 | } 150 | return NULL; 151 | } 152 | 153 | // Connection 154 | Connection *HttpRequestPacket::getConnection() 155 | { 156 | return _connection; 157 | } 158 | 159 | // connection 160 | void HttpRequestPacket::setConnection(Connection *connection) 161 | { 162 | _connection = connection; 163 | } 164 | 165 | } 166 | 167 | 168 | -------------------------------------------------------------------------------- /tbnet/httprequestpacket.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBNET_HTTP_REQUEST_PACKET_H 17 | #define TBNET_HTTP_REQUEST_PACKET_H 18 | 19 | namespace tbnet 20 | { 21 | 22 | struct eqstr 23 | { 24 | bool operator()(const char *s1, const char *s2) const 25 | { 26 | return strcmp(s1, s2) == 0; 27 | } 28 | }; 29 | typedef __gnu_cxx::hash_map, eqstr> PSTR_MAP; 30 | typedef PSTR_MAP::iterator PSTR_MAP_ITER; 31 | 32 | class HttpRequestPacket : public Packet 33 | { 34 | public: 35 | /* 36 | * 构造函数 37 | */ 38 | HttpRequestPacket(); 39 | 40 | /* 41 | * 析构函数 42 | */ 43 | ~HttpRequestPacket(); 44 | 45 | /* 46 | * 计算出数据包的长度 47 | */ 48 | void countDataLen(); 49 | /* 50 | * 组装 51 | */ 52 | bool encode(DataBuffer *output); 53 | 54 | /* 55 | * 解开 56 | */ 57 | bool decode(DataBuffer *input, PacketHeader *header); 58 | 59 | /* 60 | * 查询串 61 | */ 62 | char *getQuery(); 63 | 64 | /* 65 | * 是否keepalive 66 | */ 67 | bool isKeepAlive(); 68 | 69 | /* 70 | * 寻找其他头信息 71 | */ 72 | const char *findHeader(const char *name); 73 | 74 | /* 75 | * 取回Connection 76 | */ 77 | Connection *getConnection(); 78 | 79 | /* 80 | * 设置connection 81 | */ 82 | void setConnection(Connection *connection); 83 | 84 | private: 85 | char *_strHeader; // 保存头内容的buffer 86 | char *_strQuery; // 查询串 87 | bool _isKeepAlive; // 是否支持keepalive 88 | int _method; // get - 1 89 | PSTR_MAP _headerMap; // 其他头信息的map 90 | 91 | tbnet::Connection *_connection; // 存connection 92 | }; 93 | 94 | } 95 | 96 | #endif 97 | 98 | -------------------------------------------------------------------------------- /tbnet/httpresponsepacket.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include "tbnet.h" 17 | 18 | namespace tbnet 19 | { 20 | 21 | /* 22 | * 构造函数 23 | */ 24 | HttpResponsePacket::HttpResponsePacket() 25 | { 26 | _status = true; 27 | _body = NULL; 28 | _bodyLen = 0; 29 | _isKeepAlive = false; 30 | _statusMessage = NULL; 31 | } 32 | 33 | /* 34 | * 析构函数 35 | */ 36 | HttpResponsePacket::~HttpResponsePacket() 37 | { 38 | if (_body) 39 | { 40 | ::free(_body); 41 | } 42 | if (_statusMessage) 43 | { 44 | ::free(_statusMessage); 45 | _statusMessage = NULL; 46 | } 47 | } 48 | 49 | /* 50 | * 组装 51 | */ 52 | bool HttpResponsePacket::encode(DataBuffer *output) 53 | { 54 | if (_statusMessage) 55 | { 56 | output->writeBytes(_statusMessage, strlen(_statusMessage)); 57 | output->writeBytes("\r\n", 2); 58 | } 59 | else if (_status) 60 | { //HTTP/1.1 200 OK 61 | output->writeBytes(TBNET_HTTP_STATUS_OK, strlen(TBNET_HTTP_STATUS_OK)); 62 | } 63 | else 64 | { // HTTP/1.1 404 Not Found 65 | output->writeBytes(TBNET_HTTP_STATUS_NOTFOUND, strlen(TBNET_HTTP_STATUS_NOTFOUND)); 66 | } 67 | //固定字段 68 | if (_isKeepAlive) 69 | { 70 | output->writeBytes(TBNET_HTTP_KEEP_ALIVE, strlen(TBNET_HTTP_KEEP_ALIVE)); 71 | } 72 | else 73 | { 74 | output->writeBytes(TBNET_HTTP_CONN_CLOSE, strlen(TBNET_HTTP_CONN_CLOSE)); 75 | } 76 | if (_headerMap.find("Content-Type") == _headerMap.end()) 77 | { 78 | output->writeBytes(TBNET_HTTP_CONTENT_TYPE, strlen(TBNET_HTTP_CONTENT_TYPE)); 79 | } 80 | char tmp[64]; 81 | int len = sprintf(tmp, TBNET_HTTP_CONTENT_LENGTH, _bodyLen); 82 | output->writeBytes(tmp, len); 83 | 84 | // 用户自定义长度 85 | for (STRING_MAP_ITER it = _headerMap.begin(); it != _headerMap.end(); it++) 86 | { 87 | output->writeBytes(it->first.c_str(), strlen(it->first.c_str())); 88 | output->writeBytes(": ", 2); 89 | output->writeBytes(it->second.c_str(), strlen(it->second.c_str())); 90 | output->writeBytes("\r\n", 2); 91 | } 92 | 93 | // 空行 94 | output->writeBytes("\r\n", 2); 95 | // bodyLen 96 | output->writeBytes(_body, _bodyLen); 97 | //assert(_packetHeader._dataLen == output->getDataLen()); 98 | 99 | return true; 100 | } 101 | 102 | /* 103 | * 解开 104 | */ 105 | bool HttpResponsePacket::decode(DataBuffer *input, PacketHeader *header) 106 | { 107 | return true; 108 | } 109 | 110 | /* 111 | * 设置header 112 | */ 113 | void HttpResponsePacket::setHeader(const char *name, const char *value) 114 | { 115 | if (name[0] == 'C') 116 | { 117 | if (strcmp(name, "Connection") == 0 || strcmp(name, "Content-Length") == 0) 118 | { 119 | return; 120 | } 121 | } 122 | _headerMap[name] = value; 123 | } 124 | 125 | /* 126 | * 设置状态 127 | */ 128 | void HttpResponsePacket::setStatus(bool status, const char *statusMessage) 129 | { 130 | _status = status; 131 | if (_statusMessage) 132 | { 133 | ::free(_statusMessage); 134 | _statusMessage = NULL; 135 | } 136 | if (statusMessage) 137 | { 138 | _statusMessage = strdup(statusMessage); 139 | } 140 | } 141 | 142 | /* 143 | * 设置内容 144 | */ 145 | void HttpResponsePacket::setBody(const char *body, int len) 146 | { 147 | if (body) 148 | { 149 | _body = (char *) malloc(len); 150 | memcpy(_body, body, len); 151 | _bodyLen = len; 152 | } 153 | } 154 | 155 | /* 156 | * 是否keepalive 157 | */ 158 | void HttpResponsePacket::setKeepAlive(bool keepAlive) 159 | { 160 | _isKeepAlive = keepAlive; 161 | } 162 | 163 | } 164 | 165 | -------------------------------------------------------------------------------- /tbnet/httpresponsepacket.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBNET_HTTP_RESPONSE_PACKET_H 17 | #define TBNET_HTTP_RESPONSE_PACKET_H 18 | 19 | namespace tbnet 20 | { 21 | 22 | struct str_hash 23 | { 24 | size_t operator()(const std::string &str) const 25 | { 26 | return __gnu_cxx::__stl_hash_string(str.c_str()); 27 | } 28 | }; 29 | typedef __gnu_cxx::hash_map STRING_MAP; 30 | typedef STRING_MAP::iterator STRING_MAP_ITER; 31 | 32 | #define TBNET_HTTP_STATUS_OK "HTTP/1.1 200 OK\r\n" 33 | #define TBNET_HTTP_STATUS_NOTFOUND "HTTP/1.1 404 Not Found\r\n" 34 | #define TBNET_HTTP_KEEP_ALIVE "Connection: Keep-Alive\r\nKeep-Alive: timeout=10, max=10\r\n" 35 | #define TBNET_HTTP_CONN_CLOSE "Connection: close\r\n" 36 | #define TBNET_HTTP_CONTENT_TYPE "Content-Type: text/html\r\n" 37 | #define TBNET_HTTP_CONTENT_LENGTH "Content-Length: %d\r\n" 38 | 39 | class HttpResponsePacket : public Packet 40 | { 41 | public: 42 | /* 43 | * 构造函数 44 | */ 45 | HttpResponsePacket(); 46 | 47 | /* 48 | * 析构函数 49 | */ 50 | ~HttpResponsePacket(); 51 | 52 | /* 53 | * 计算出数据包的长度 54 | */ 55 | void countDataLen(); 56 | 57 | /* 58 | * 组装 59 | */ 60 | bool encode(DataBuffer *output); 61 | 62 | /* 63 | * 解开 64 | */ 65 | bool decode(DataBuffer *input, PacketHeader *header); 66 | 67 | /* 68 | * 设置header 69 | */ 70 | void setHeader(const char *name, const char *value); 71 | 72 | /* 73 | * 设置状态 74 | */ 75 | void setStatus(bool status, const char *statusMessage = NULL); 76 | 77 | /* 78 | * 设置内容 79 | */ 80 | void setBody(const char *body, int len); 81 | 82 | /* 83 | * 是否keepalive 84 | */ 85 | void setKeepAlive(bool keepAlive); 86 | 87 | private: 88 | bool _status; // 返回的状态, true => 200, false => 404 89 | char *_statusMessage; // 状态 90 | char *_body; // 返回的内容 91 | int _bodyLen; // 返回内容找长度 92 | STRING_MAP _headerMap; // 返回其他头信息 93 | bool _isKeepAlive; // 是否keepalive 94 | }; 95 | 96 | } 97 | 98 | #endif 99 | 100 | -------------------------------------------------------------------------------- /tbnet/iocomponent.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include "tbnet.h" 17 | 18 | namespace tbnet 19 | { 20 | 21 | /* 22 | * 构造函数 23 | */ 24 | IOComponent::IOComponent(Transport *owner, Socket *socket) 25 | { 26 | assert(socket); 27 | _owner = owner; 28 | _socket = socket; 29 | _socket->setIOComponent(this); 30 | _socketEvent = NULL; 31 | atomic_set(&_refcount, 0); 32 | _state = TBNET_UNCONNECTED; // 正在连接 33 | _autoReconn = false; // 不要自动重连 34 | _prev = _next = NULL; 35 | _lastUseTime = tbsys::CTimeUtil::getTime(); 36 | _inUsed = false; 37 | } 38 | 39 | /* 40 | * 析构函数 41 | */ 42 | IOComponent::~IOComponent() 43 | { 44 | if (_socket) 45 | { 46 | _socket->close(); 47 | delete _socket; 48 | _socket = NULL; 49 | } 50 | } 51 | 52 | /** 53 | * owner 54 | */ 55 | Transport *IOComponent::getOwner() 56 | { 57 | return _owner; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /tbnet/ipacketfactory.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBNET_IPACKET_FACTORY_H_ 17 | #define TBNET_IPACKET_FACTORY_H_ 18 | 19 | namespace tbnet 20 | { 21 | 22 | class IPacketFactory 23 | { 24 | public: 25 | virtual ~IPacketFactory() {}; 26 | virtual Packet *createPacket(int pcode) = 0; 27 | }; 28 | } 29 | 30 | #endif /*IPACKET_FACTORY_H_*/ 31 | -------------------------------------------------------------------------------- /tbnet/ipackethandler.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBNET_IPACKETHANDLER_H_ 17 | #define TBNET_IPACKETHANDLER_H_ 18 | 19 | namespace tbnet 20 | { 21 | 22 | class IPacketHandler 23 | { 24 | public: 25 | enum HPRetCode 26 | { 27 | KEEP_CHANNEL = 0, 28 | CLOSE_CHANNEL = 1, 29 | FREE_CHANNEL = 2 30 | }; 31 | 32 | virtual ~IPacketHandler() {} 33 | virtual HPRetCode handlePacket(Packet *packet, void *args) = 0; 34 | }; 35 | } 36 | 37 | #endif /*IPACHETHANDLER_H_*/ 38 | -------------------------------------------------------------------------------- /tbnet/ipacketstreamer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBNET_IPACKETSTREAMER_H_ 17 | #define TBNET_IPACKETSTREAMER_H_ 18 | 19 | namespace tbnet 20 | { 21 | 22 | class IPacketStreamer 23 | { 24 | 25 | public: 26 | /* 27 | * 构造函数 28 | */ 29 | IPacketStreamer() 30 | { 31 | _factory = NULL; 32 | _existPacketHeader = true; 33 | } 34 | 35 | /* 36 | * 构造函数 37 | */ 38 | IPacketStreamer(IPacketFactory *factory) 39 | { 40 | _factory = factory; 41 | _existPacketHeader = true; 42 | } 43 | 44 | /* 45 | * 析构函数 46 | */ 47 | virtual ~IPacketStreamer() {} 48 | 49 | /* 50 | * 得到包头信息 51 | * 52 | * @param input 源buffer 53 | * @param header 结果header 54 | * @return 是否成功 55 | */ 56 | virtual bool getPacketInfo(DataBuffer *input, PacketHeader *header, bool *broken) = 0; 57 | 58 | /* 59 | * 对包的解码 60 | * 61 | * @param input 62 | * @param header 63 | * @return 解码后的数据包 64 | */ 65 | virtual Packet *decode(DataBuffer *input, PacketHeader *header) = 0; 66 | 67 | /* 68 | * 对Packet的组装 69 | * 70 | * @param packet 数据包 71 | * @param output 组装后的数据流 72 | * @return 是否成功 73 | */ 74 | virtual bool encode(Packet *packet, DataBuffer *output) = 0; 75 | 76 | /* 77 | * 是否有数据包头 78 | */ 79 | bool existPacketHeader() 80 | { 81 | return _existPacketHeader; 82 | } 83 | 84 | protected: 85 | IPacketFactory *_factory; // 产生packet 86 | bool _existPacketHeader; // 是否有packet header, 如http有自己协议就不需要输出头信息 87 | }; 88 | } 89 | 90 | #endif /*RUNNABLE_H_*/ 91 | -------------------------------------------------------------------------------- /tbnet/iserveradapter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBNET_ISERVERADAPTER_H 17 | #define TBNET_ISERVERADAPTER_H 18 | 19 | #ifndef UNUSED 20 | #define UNUSED(v) ((void)(v)) 21 | #endif 22 | 23 | namespace tbnet 24 | { 25 | 26 | class IServerAdapter 27 | { 28 | friend class Connection; 29 | friend class TCPConnection; 30 | public: 31 | // 单个packet回调 32 | virtual IPacketHandler::HPRetCode handlePacket(Connection *connection, Packet *packet) = 0; 33 | // 批量packet回调 34 | virtual bool handleBatchPacket(Connection *connection, PacketQueue &packetQueue) 35 | { 36 | UNUSED(packetQueue); 37 | UNUSED(connection); 38 | return false; 39 | } 40 | // 构造函数 41 | IServerAdapter() 42 | { 43 | _batchPushPacket = false; 44 | } 45 | // 析构函数 46 | virtual ~IServerAdapter() {} 47 | // setBatch() 48 | void setBatchPushPacket(bool value) 49 | { 50 | _batchPushPacket = value; 51 | } 52 | private: 53 | bool _batchPushPacket; // 批量post packet 54 | }; 55 | } 56 | 57 | #endif /*ISERVERADAPTER_H*/ 58 | -------------------------------------------------------------------------------- /tbnet/packet.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include "tbnet.h" 17 | 18 | namespace tbnet 19 | { 20 | 21 | /* 22 | * 构造函数, 传包类型 23 | */ 24 | Packet::Packet() 25 | { 26 | _next = NULL; 27 | _channel = NULL; 28 | _expireTime = 0; 29 | memset(&_packetHeader, 0, sizeof(PacketHeader)); 30 | } 31 | 32 | /* 33 | * 析构函数 34 | */ 35 | Packet::~Packet() 36 | { 37 | } 38 | 39 | /* 40 | * 设置Channel 41 | */ 42 | void Packet::setChannel(Channel *channel) 43 | { 44 | if (channel) 45 | { 46 | _channel = channel; 47 | _packetHeader._chid = channel->getId(); 48 | } 49 | } 50 | 51 | /* 52 | * 设置过期时间 53 | * 54 | * @param milliseconds 毫秒数, 0为一天时间 55 | */ 56 | void Packet::setExpireTime(int milliseconds) 57 | { 58 | if (milliseconds == 0) 59 | { 60 | milliseconds = 1000 * 86400; 61 | } 62 | _expireTime = tbsys::CTimeUtil::getTime() + static_cast(milliseconds) * static_cast(1000); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /tbnet/packet.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBNET_PACKET_H_ 17 | #define TBNET_PACKET_H_ 18 | 19 | namespace tbnet 20 | { 21 | 22 | #define TBNET_PACKET_FLAG 0x416e4574 // AnEt 23 | 24 | class PacketHeader 25 | { 26 | public: 27 | uint32_t _chid; // 通道ID 28 | int _pcode; // 数据包类型 29 | int _dataLen; // 数据包body长度(除头信息外) 30 | }; 31 | 32 | class Packet 33 | { 34 | friend class PacketQueue; 35 | 36 | public: 37 | /* 38 | * 构造函数, 传包类型 39 | */ 40 | Packet(); 41 | 42 | /* 43 | * 析构函数 44 | */ 45 | virtual ~Packet(); 46 | 47 | /* 48 | * 设置ChannelID 49 | */ 50 | void setChannelId(uint32_t chid) 51 | { 52 | _packetHeader._chid = chid; 53 | } 54 | 55 | /* 56 | * 得到Channel ID 57 | */ 58 | uint32_t getChannelId() const 59 | { 60 | return _packetHeader._chid; 61 | } 62 | 63 | /* 64 | * 设置PCode 65 | */ 66 | void setPCode(int pcode) 67 | { 68 | _packetHeader._pcode = pcode; 69 | } 70 | 71 | /* 72 | * 得到PCode 73 | */ 74 | int getPCode() const 75 | { 76 | return _packetHeader._pcode; 77 | } 78 | 79 | /* 80 | * 得到数据包header info 81 | */ 82 | PacketHeader *getPacketHeader() 83 | { 84 | return &_packetHeader; 85 | } 86 | 87 | /* 88 | * 设置数据包header info 89 | */ 90 | void setPacketHeader(PacketHeader *header) 91 | { 92 | if (header) 93 | { 94 | memcpy(&_packetHeader, header, sizeof(PacketHeader)); 95 | } 96 | } 97 | 98 | /* 99 | * 释放自己 100 | */ 101 | virtual void free() 102 | { 103 | delete this; 104 | } 105 | 106 | /* 107 | * 是否数据包 108 | */ 109 | virtual bool isRegularPacket() 110 | { 111 | return true; 112 | } 113 | 114 | /* 115 | * 组装 116 | * 117 | * @param output: 目标buffer 118 | * @return 是否成功 119 | */ 120 | virtual bool encode(DataBuffer *output) = 0; 121 | 122 | /* 123 | * 解开 124 | * 125 | * @param input: 源buffer 126 | * @param header: 数据包header 127 | * @return 是否成功 128 | */ 129 | virtual bool decode(DataBuffer *input, PacketHeader *header) = 0; 130 | 131 | /* 132 | * 超时时间 133 | */ 134 | int64_t getExpireTime() const 135 | { 136 | return _expireTime; 137 | } 138 | 139 | /* 140 | * 设置过期时间 141 | * 142 | * @param milliseconds 毫秒数, 0为永不过期 143 | */ 144 | void setExpireTime(int milliseconds); 145 | 146 | /* 147 | * 设置Channel 148 | */ 149 | void setChannel(Channel *channel); 150 | 151 | /* 152 | * 得到Channel 153 | */ 154 | Channel *getChannel() const 155 | { 156 | return _channel; 157 | } 158 | 159 | /* 160 | * 得到next 161 | */ 162 | Packet *getNext() const 163 | { 164 | return _next; 165 | } 166 | 167 | protected: 168 | PacketHeader _packetHeader; // 数据包的头信息 169 | int64_t _expireTime; // 到期时间 170 | Channel *_channel; 171 | 172 | Packet *_next; // 用在packetqueue链表 173 | }; 174 | 175 | } 176 | 177 | #endif /*PACKET_H_*/ 178 | -------------------------------------------------------------------------------- /tbnet/packetqueue.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include "tbnet.h" 17 | 18 | namespace tbnet 19 | { 20 | 21 | /* 22 | * 构造函数 23 | */ 24 | PacketQueue::PacketQueue() 25 | { 26 | _head = NULL; 27 | _tail = NULL; 28 | _size = 0; 29 | } 30 | /* 31 | * 析构函数 32 | */ 33 | PacketQueue::~PacketQueue() 34 | { 35 | clear(); 36 | } 37 | 38 | /* 39 | * 出链表 40 | */ 41 | Packet *PacketQueue::pop() 42 | { 43 | if (_head == NULL) 44 | { 45 | return NULL; 46 | } 47 | Packet *packet = _head; 48 | _head = _head->_next; 49 | if (_head == NULL) 50 | { 51 | _tail = NULL; 52 | } 53 | _size--; 54 | return packet; 55 | } 56 | 57 | /* 58 | * 清空 59 | */ 60 | void PacketQueue::clear() 61 | { 62 | if (_head == NULL) 63 | { 64 | return; 65 | } 66 | while (_head != NULL) 67 | { 68 | Packet *packet = _head; 69 | _head = packet->_next; 70 | packet->free(); 71 | } 72 | _head = _tail = NULL; 73 | _size = 0; 74 | } 75 | 76 | /* 77 | * 入链表 78 | */ 79 | void PacketQueue::push(Packet *packet) 80 | { 81 | if (packet == NULL) 82 | { 83 | TBSYS_LOG(INFO, "packet is null."); 84 | return; 85 | } 86 | packet->_next = NULL; 87 | if (_tail == NULL) 88 | { 89 | _head = packet; 90 | } 91 | else 92 | { 93 | _tail->_next = packet; 94 | } 95 | _tail = packet; 96 | _size++; 97 | } 98 | 99 | /* 100 | * 长度 101 | */ 102 | int PacketQueue::size() 103 | { 104 | return _size; 105 | } 106 | 107 | /* 108 | * 是否为空 109 | */ 110 | bool PacketQueue::empty() 111 | { 112 | return (_size == 0); 113 | } 114 | 115 | /* 116 | * 移动到其他队列上 117 | */ 118 | void PacketQueue::moveTo(PacketQueue *destQueue) 119 | { 120 | if (_head == NULL) 121 | { // 是空链 122 | return; 123 | } 124 | if (destQueue->_tail == NULL) 125 | { 126 | destQueue->_head = _head; 127 | } 128 | else 129 | { 130 | destQueue->_tail->_next = _head; 131 | } 132 | destQueue->_tail = _tail; 133 | destQueue->_size += _size; 134 | _head = _tail = NULL; 135 | _size = 0; 136 | } 137 | 138 | /* 139 | * 得到超时的packet 140 | */ 141 | Packet *PacketQueue::getTimeoutList(int64_t now) 142 | { 143 | Packet *list, *tail; 144 | list = tail = NULL; 145 | while (_head != NULL) 146 | { 147 | int64_t t = _head->getExpireTime(); 148 | if (t == 0 || t >= now) 149 | { 150 | break; 151 | } 152 | if (tail == NULL) 153 | { 154 | list = _head; 155 | } 156 | else 157 | { 158 | tail->_next = _head; 159 | } 160 | tail = _head; 161 | 162 | _head = _head->_next; 163 | if (_head == NULL) 164 | { 165 | _tail = NULL; 166 | } 167 | _size--; 168 | } 169 | if (tail) 170 | { 171 | tail->_next = NULL; 172 | } 173 | return list; 174 | } 175 | 176 | /* 177 | * 取到packet list 178 | */ 179 | Packet *PacketQueue::getPacketList() 180 | { 181 | return _head; 182 | } 183 | } 184 | 185 | -------------------------------------------------------------------------------- /tbnet/packetqueue.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBNET_PACKET_QUEUE_H_ 17 | #define TBNET_PACKET_QUEUE_H_ 18 | 19 | namespace tbnet 20 | { 21 | 22 | class PacketQueue 23 | { 24 | friend class PacketQueueThread; 25 | public: 26 | /* 27 | * 构造函数 28 | */ 29 | PacketQueue(); 30 | 31 | /* 32 | * 析构函数 33 | */ 34 | ~PacketQueue(); 35 | 36 | /* 37 | * 出链 38 | */ 39 | Packet *pop(); 40 | 41 | /* 42 | * 清空 43 | */ 44 | void clear(); 45 | 46 | /* 47 | * 入链 48 | */ 49 | void push(Packet *packet); 50 | 51 | /* 52 | * 长度 53 | */ 54 | int size(); 55 | 56 | /* 57 | * 是否为空 58 | */ 59 | bool empty(); 60 | 61 | /* 62 | * 移动到其他队列上 63 | */ 64 | void moveTo(PacketQueue *destQueue); 65 | 66 | /* 67 | * 得到超时的packet 68 | */ 69 | Packet *getTimeoutList(int64_t now); 70 | 71 | /* 72 | * 取到packet list 73 | */ 74 | Packet *getPacketList(); 75 | 76 | /* 77 | *取得队列头指针 78 | */ 79 | Packet *head() 80 | { 81 | return _head; 82 | } 83 | /* 84 | *取得队列尾指针 85 | */ 86 | Packet *tail() 87 | { 88 | return _tail; 89 | } 90 | protected: 91 | Packet *_head; // 链头 92 | Packet *_tail; // 链尾 93 | int _size; // 元素数量 94 | }; 95 | 96 | } 97 | 98 | #endif 99 | 100 | -------------------------------------------------------------------------------- /tbnet/packetqueuethread.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBNET_PACKET_QUEUE_THREAD_H 17 | #define TBNET_PACKET_QUEUE_THREAD_H 18 | 19 | namespace tbnet 20 | { 21 | 22 | // packet queue的处理线程 23 | class IPacketQueueHandler 24 | { 25 | public: 26 | virtual ~IPacketQueueHandler() {} 27 | virtual bool handlePacketQueue(Packet *packet, void *args) = 0; 28 | }; 29 | 30 | class PacketQueueThread : public tbsys::CDefaultRunnable 31 | { 32 | public: 33 | // 构造 34 | PacketQueueThread(); 35 | 36 | // 构造 37 | PacketQueueThread(int threadCount, IPacketQueueHandler *handler, void *args); 38 | 39 | // 析构 40 | ~PacketQueueThread(); 41 | 42 | // 参数设置 43 | void setThreadParameter(int threadCount, IPacketQueueHandler *handler, void *args); 44 | 45 | // stop 46 | void stop(bool waitFinish = false); 47 | 48 | // push 49 | bool push(Packet *packet, int maxQueueLen = 0, bool block = true); 50 | 51 | // pushQueue 52 | void pushQueue(PacketQueue &packetQueue, int maxQueueLen = 0); 53 | 54 | // Runnable 接口 55 | void run(tbsys::CThread *thread, void *arg); 56 | 57 | // 是否计算处理速度 58 | void setStatSpeed(); 59 | 60 | // 设置限速 61 | void setWaitTime(int t); 62 | 63 | Packet *head() 64 | { 65 | return _queue.head(); 66 | } 67 | Packet *tail() 68 | { 69 | return _queue.tail(); 70 | } 71 | size_t size() 72 | { 73 | return _queue.size(); 74 | } 75 | private: 76 | //void PacketQueueThread::checkSendSpeed() 77 | void checkSendSpeed(); 78 | 79 | private: 80 | PacketQueue _queue; 81 | IPacketQueueHandler *_handler; 82 | tbsys::CThreadCond _cond; 83 | tbsys::CThreadCond _pushcond; 84 | void *_args; 85 | bool _waitFinish; // 等待完成 86 | 87 | // 限制发送速度 88 | int _waitTime; 89 | int64_t _speed_t1; 90 | int64_t _speed_t2; 91 | int64_t _overage; 92 | 93 | // 是否正在等待 94 | bool _waiting; 95 | }; 96 | } 97 | 98 | #endif 99 | 100 | -------------------------------------------------------------------------------- /tbnet/serversocket.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include "tbnet.h" 17 | 18 | namespace tbnet 19 | { 20 | 21 | /* 22 | * 构造函数 23 | */ 24 | ServerSocket::ServerSocket() 25 | { 26 | _backLog = 256; 27 | } 28 | 29 | /* 30 | * accept一个新的连接 31 | * 32 | * @return 一个Socket 33 | */ 34 | Socket *ServerSocket::accept() 35 | { 36 | Socket *handleSocket = NULL; 37 | 38 | struct sockaddr_in addr; 39 | int len = sizeof(addr); 40 | 41 | int fd = ::accept(_socketHandle, (struct sockaddr *) &addr, (socklen_t *) &len); 42 | 43 | if (fd >= 0) 44 | { 45 | handleSocket = new Socket(); 46 | handleSocket->setUp(fd, (struct sockaddr *) &addr); 47 | } 48 | else 49 | { 50 | int error = getLastError(); 51 | if (error != EAGAIN) 52 | { 53 | TBSYS_LOG(ERROR, "%s(%d)", strerror(error), error); 54 | } 55 | } 56 | 57 | return handleSocket; 58 | } 59 | 60 | /* 61 | * 打开监听 62 | * 63 | * @return 是否成功 64 | */ 65 | bool ServerSocket::listen() 66 | { 67 | if (!checkSocketHandle()) 68 | { 69 | return false; 70 | } 71 | 72 | // 地址可重用 73 | setSoLinger(false, 0); 74 | setReuseAddress(true); 75 | setIntOption(SO_KEEPALIVE, 1); 76 | setIntOption(SO_SNDBUF, 640000); 77 | setIntOption(SO_RCVBUF, 640000); 78 | setTcpNoDelay(true); 79 | 80 | if (::bind(_socketHandle, (struct sockaddr *) &_address, 81 | sizeof(_address)) < 0) 82 | { 83 | return false; 84 | } 85 | 86 | if (::listen(_socketHandle, _backLog) < 0) 87 | { 88 | return false; 89 | } 90 | 91 | return true; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /tbnet/serversocket.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBNET_SERVERSOCKET_H_ 17 | #define TBNET_SERVERSOCKET_H_ 18 | 19 | namespace tbnet 20 | { 21 | 22 | class ServerSocket : public Socket 23 | { 24 | 25 | public: 26 | /* 27 | * 构造函数 28 | */ 29 | ServerSocket(); 30 | /* 31 | * accept一个新的连接 32 | * 33 | * @return 一个Socket 34 | */ 35 | Socket *accept(); 36 | 37 | /* 38 | * 打开监听 39 | * 40 | * @return 是否成功 41 | */ 42 | bool listen(); 43 | 44 | private: 45 | int _backLog; // backlog 46 | }; 47 | 48 | } 49 | 50 | #endif /*SERVERSOCKET_H_*/ 51 | -------------------------------------------------------------------------------- /tbnet/socket.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBNET_SOCKET_H_ 17 | #define TBNET_SOCKET_H_ 18 | #include 19 | 20 | namespace tbnet 21 | { 22 | 23 | class Socket 24 | { 25 | 26 | public: 27 | /* 28 | * 构造函数 29 | */ 30 | Socket(); 31 | 32 | /* 33 | * 析构函数 34 | */ 35 | ~Socket(); 36 | 37 | /* 38 | * 设置地址 39 | * 40 | * @param address host或ip地址 41 | * @param port 端口号 42 | * @return 是否成功 43 | */ 44 | 45 | bool setAddress(const char *address, const int port); 46 | 47 | /* 48 | * 连接到_address上 49 | * 50 | * @return 是否成功 51 | */ 52 | bool connect(); 53 | 54 | /** 55 | * 关闭连接 56 | */ 57 | void close(); 58 | 59 | /* 60 | * 关闭读写 61 | */ 62 | void shutdown(); 63 | 64 | /** 65 | * 使用UDP的socket 66 | * 67 | * @return 是否成功 68 | */ 69 | bool createUDP(); 70 | 71 | /* 72 | * 把socketHandle,及ipaddress设置到此socket中 73 | * 74 | * @param socketHandle: socket的文件句柄 75 | * @param hostAddress: 服务器地址 76 | */ 77 | 78 | void setUp(int socketHandle, struct sockaddr *hostAddress); 79 | 80 | /* 81 | * 返回文件句柄 82 | * 83 | * @return 文件句柄 84 | */ 85 | int getSocketHandle(); 86 | 87 | /* 88 | * 返回IOComponent 89 | * 90 | * @return IOComponent 91 | */ 92 | IOComponent *getIOComponent(); 93 | 94 | /* 95 | * 设置IOComponent 96 | * 97 | * @param IOComponent 98 | */ 99 | void setIOComponent(IOComponent *ioc); 100 | 101 | /* 102 | * 写数据 103 | */ 104 | int write(const void *data, int len); 105 | 106 | /* 107 | * 读数据 108 | */ 109 | int read(void *data, int len); 110 | 111 | /* 112 | * SetSoKeepAlive 113 | */ 114 | bool setKeepAlive(bool on) 115 | { 116 | return setIntOption(SO_KEEPALIVE, on ? 1 : 0); 117 | } 118 | 119 | /* 120 | * setReuseAddress 121 | */ 122 | bool setReuseAddress(bool on) 123 | { 124 | return setIntOption(SO_REUSEADDR, on ? 1 : 0); 125 | } 126 | 127 | /* 128 | * setSoLinger 129 | */ 130 | bool setSoLinger(bool doLinger, int seconds); 131 | 132 | /* 133 | * setTcpNoDelay 134 | */ 135 | bool setTcpNoDelay(bool noDelay); 136 | 137 | /* 138 | * setTcpQuickAck 139 | */ 140 | bool setTcpQuickAck(bool quickAck); 141 | 142 | /* 143 | * setIntOption 144 | */ 145 | bool setIntOption(int option, int value); 146 | 147 | /* 148 | * setTimeOption 149 | */ 150 | bool setTimeOption(int option, int milliseconds); 151 | 152 | /* 153 | * 是否阻塞 154 | */ 155 | bool setSoBlocking(bool on); 156 | 157 | /* 158 | * 检查Socket句柄是否创建 159 | */ 160 | bool checkSocketHandle(); 161 | 162 | /* 163 | * 得到Socket错误 164 | */ 165 | int getSoError(); 166 | 167 | /* 168 | * 得到ip地址, 写到tmp上 169 | */ 170 | std::string getAddr(); 171 | 172 | /* 173 | * 得到64位数字的ip地址 174 | */ 175 | uint64_t getId(); 176 | uint64_t getPeerId(); 177 | 178 | /** 179 | * 得到本地端口 180 | */ 181 | int getLocalPort(); 182 | 183 | /* 184 | * 得到最后的错误 185 | */ 186 | static int getLastError() 187 | { 188 | return errno; 189 | } 190 | 191 | protected: 192 | struct sockaddr_in _address; // 地址 193 | int _socketHandle; // socket文件句柄 194 | IOComponent *_iocomponent; 195 | static tbsys::CThreadMutex _dnsMutex; // 多实例用一个dnsMutex 196 | }; 197 | } 198 | 199 | #endif /*SOCKET_H_*/ 200 | -------------------------------------------------------------------------------- /tbnet/socketevent.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include "tbnet.h" 17 | 18 | namespace tbnet 19 | { 20 | 21 | /* 22 | * 构造函数 23 | */ 24 | SocketEvent::SocketEvent() 25 | { 26 | } 27 | /* 28 | * 析构函数 29 | */ 30 | SocketEvent::~SocketEvent() {} 31 | } 32 | -------------------------------------------------------------------------------- /tbnet/socketevent.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBNET_SOCKETEVENT_H_ 17 | #define TBNET_SOCKETEVENT_H_ 18 | 19 | namespace tbnet 20 | { 21 | 22 | #define MAX_SOCKET_EVENTS 256 23 | 24 | class IOEvent 25 | { 26 | 27 | public: 28 | bool _readOccurred; // 读发生 29 | bool _writeOccurred; // 写发生 30 | bool _errorOccurred; // 错误发生 31 | IOComponent *_ioc; // 回传参数 32 | }; 33 | 34 | class SocketEvent 35 | { 36 | 37 | public: 38 | /* 39 | * 构造函数 40 | */ 41 | SocketEvent(); 42 | /* 43 | * 析构函数 44 | */ 45 | virtual ~SocketEvent(); 46 | /* 47 | * 增加Socket到事件中 48 | * 49 | * @param socket 被加的socket 50 | * @param enableRead: 设置是否可读 51 | * @param enableWrite: 设置是否可写 52 | * @return 操作是否成功, true – 成功, false – 失败 53 | */ 54 | virtual bool addEvent(Socket *socket, bool enableRead, bool enableWrite) = 0; 55 | 56 | /* 57 | * 设置删除Socket到事件中 58 | * 59 | * @param socket 被加的socket 60 | * @param enableRead: 设置是否可读 61 | * @param enableWrite: 设置是否可写 62 | * @return 操作是否成功, true – 成功, false – 失败 63 | */ 64 | virtual bool setEvent(Socket *socket, bool enableRead, bool enableWrite) = 0; 65 | 66 | /* 67 | * 删除Socket到事件中 68 | * 69 | * @param socket 被删除socket 70 | * @return 操作是否成功, true – 成功, false – 失败 71 | */ 72 | virtual bool removeEvent(Socket *socket) = 0; 73 | 74 | /* 75 | * 得到读写事件。 76 | * 77 | * @param timeout 超时时间(单位:ms) 78 | * @param events 事件数组 79 | * @param cnt events的数组大小 80 | * @return 事件数, 0为超时 81 | */ 82 | virtual int getEvents(int timeout, IOEvent *events, int cnt) = 0; 83 | }; 84 | } 85 | 86 | #endif /*SOCKETEVENT_H_*/ 87 | 88 | -------------------------------------------------------------------------------- /tbnet/stats.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include "tbnet.h" 17 | 18 | namespace tbnet 19 | { 20 | 21 | StatCounter StatCounter::_gStatCounter; 22 | 23 | /* 24 | * 构造函数 25 | */ 26 | StatCounter::StatCounter() 27 | { 28 | clear(); 29 | } 30 | 31 | /* 32 | * 析构函数 33 | */ 34 | StatCounter::~StatCounter() 35 | { 36 | } 37 | 38 | /* 39 | * 把stat写到log中 40 | */ 41 | void StatCounter::log() 42 | { 43 | TBSYS_LOG(INFO, "_packetReadCnt: %u, _packetWriteCnt: %u, _dataReadCnt: %u, _dataWriteCnt: %u", 44 | _packetReadCnt, _packetWriteCnt, _dataReadCnt, _dataWriteCnt); 45 | } 46 | 47 | /* 48 | * 清空 49 | */ 50 | void StatCounter::clear() 51 | { 52 | _packetReadCnt = 0; 53 | _packetWriteCnt = 0; 54 | _dataReadCnt = 0; 55 | _dataWriteCnt = 0; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /tbnet/stats.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBNET_STATS_H_ 17 | #define TBNET_STATS_H_ 18 | 19 | namespace tbnet 20 | { 21 | 22 | class StatCounter 23 | { 24 | public: 25 | StatCounter(); 26 | ~StatCounter(); 27 | void log(); 28 | void clear(); 29 | 30 | public: 31 | uint64_t _packetReadCnt; // # packets read 32 | uint64_t _packetWriteCnt; // # packets written 33 | uint64_t _dataReadCnt; // # bytes read 34 | uint64_t _dataWriteCnt; // # bytes written 35 | 36 | public: 37 | static StatCounter _gStatCounter; // È«¾Ö 38 | 39 | }; 40 | 41 | #define TBNET_GLOBAL_STAT tbnet::StatCounter::_gStatCounter 42 | #define TBNET_COUNT_PACKET_READ(i) {TBNET_GLOBAL_STAT._packetReadCnt += (i);} 43 | #define TBNET_COUNT_PACKET_WRITE(i) {TBNET_GLOBAL_STAT._packetWriteCnt += (i);} 44 | #define TBNET_COUNT_DATA_READ(i) {TBNET_GLOBAL_STAT._dataReadCnt += (i);} 45 | #define TBNET_COUNT_DATA_WRITE(i) {TBNET_GLOBAL_STAT._dataWriteCnt += (i);} 46 | 47 | } 48 | 49 | #endif 50 | 51 | -------------------------------------------------------------------------------- /tbnet/tbnet.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBNET_H 17 | #define TBNET_H 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include "tbsys.h" 40 | 41 | namespace tbnet 42 | { 43 | 44 | class TimeUtil; 45 | class Thread; 46 | class Runnable; 47 | class DataBuffer; 48 | 49 | class Packet; 50 | class ControlPacket; 51 | class IPacketFactory; 52 | class IPacketHandler; 53 | class IPacketStreamer; 54 | class IServerAdapter; 55 | class DefaultPacketStreamer; 56 | class PacketQueue; 57 | 58 | class Socket; 59 | class ServerSocket; 60 | class IOEvent; 61 | class SocketEvent; 62 | class EPollSocketEvent; 63 | class Channel; 64 | class ChannelPool; 65 | class Connection; 66 | class IOComponent; 67 | class TCPAcceptor; 68 | class TCPComponent; 69 | class TCPConnection; 70 | class Transport; 71 | class UDPAcceptor; 72 | class UDPComponent; 73 | class UDPConnection; 74 | 75 | class HttpRequestPacket; 76 | class HttpResponsePacket; 77 | class HttpPacketStreamer; 78 | class DefaultHttpPacketFactory; 79 | class PacketQueueThread; 80 | class ConnectionManager; 81 | } 82 | 83 | #include "stats.h" 84 | 85 | #include "packet.h" 86 | #include "controlpacket.h" 87 | #include "ipacketfactory.h" 88 | #include "databuffer.h" 89 | #include "ipackethandler.h" 90 | #include "ipacketstreamer.h" 91 | #include "iserveradapter.h" 92 | #include "defaultpacketstreamer.h" 93 | #include "packetqueue.h" 94 | 95 | #include "socket.h" 96 | #include "serversocket.h" 97 | #include "socketevent.h" 98 | #include "epollsocketevent.h" 99 | 100 | #include "channel.h" 101 | #include "channelpool.h" 102 | #include "connection.h" 103 | #include "tcpconnection.h" 104 | #include "udpconnection.h" 105 | 106 | #include "iocomponent.h" 107 | #include "tcpacceptor.h" 108 | #include "tcpcomponent.h" 109 | #include "udpacceptor.h" 110 | #include "udpcomponent.h" 111 | #include "transport.h" 112 | 113 | #include "httprequestpacket.h" 114 | #include "httpresponsepacket.h" 115 | #include "httppacketstreamer.h" 116 | #include "packetqueuethread.h" 117 | #include "connectionmanager.h" 118 | 119 | #endif 120 | 121 | -------------------------------------------------------------------------------- /tbnet/tcpacceptor.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include "tbnet.h" 17 | 18 | namespace tbnet 19 | { 20 | /** 21 | * 构造函数,由Transport调用。 22 | * 23 | * @param owner: 运输层对象 24 | * @param host: 监听ip地址或hostname 25 | * @param port: 监听端口 26 | * @param streamer: 数据包的双向流,用packet创建,解包,组包。 27 | * @param serverAdapter: 用在服务器端,当Connection初始化及Channel创建时回调时用 28 | */ 29 | TCPAcceptor::TCPAcceptor(Transport *owner, Socket *socket, 30 | IPacketStreamer *streamer, IServerAdapter *serverAdapter) : IOComponent(owner, socket) 31 | { 32 | _streamer = streamer; 33 | _serverAdapter = serverAdapter; 34 | } 35 | 36 | /* 37 | * 初始化, 开始监听 38 | */ 39 | bool TCPAcceptor::init(bool isServer) 40 | { 41 | _socket->setSoBlocking(false); 42 | return ((ServerSocket *) _socket)->listen(); 43 | } 44 | 45 | /** 46 | * 当有数据可读时被Transport调用 47 | * 48 | * @return 是否成功 49 | */ 50 | bool TCPAcceptor::handleReadEvent() 51 | { 52 | Socket *socket; 53 | while ((socket = ((ServerSocket *) _socket)->accept()) != NULL) 54 | { 55 | //TBSYS_LOG(INFO, "有新连接进来, fd: %d", socket->getSocketHandle()); 56 | // TCPComponent, 在服务器端 57 | TCPComponent *component = new TCPComponent(_owner, socket, _streamer, _serverAdapter); 58 | 59 | if (!component->init(true)) 60 | { 61 | delete component; 62 | return true; 63 | } 64 | 65 | // 加入到iocomponents中,及注册可读到socketevent中 66 | _owner->addComponent(component, true, false); 67 | } 68 | 69 | return true; 70 | } 71 | 72 | /* 73 | * 超时检查 74 | * 75 | * @param now 当前时间(单位us) 76 | */ 77 | void TCPAcceptor::checkTimeout(int64_t now) {} 78 | } 79 | -------------------------------------------------------------------------------- /tbnet/tcpacceptor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBNET_TCPACCEPTOR_H_ 17 | #define TBNET_TCPACCEPTOR_H_ 18 | 19 | namespace tbnet 20 | { 21 | 22 | class TCPAcceptor : public IOComponent 23 | { 24 | 25 | public: 26 | /** 27 | * 构造函数,由Transport调用。 28 | * 29 | * @param owner: 运输层对象 30 | * @param socket: Socket对象 31 | * @param streamer: 数据包的双向流,用packet创建,解包,组包。 32 | * @param serverAdapter: 用在服务器端,当Connection初始化及Channel创建时回调时用 33 | */ 34 | TCPAcceptor(Transport *owner, Socket *socket, 35 | IPacketStreamer *streamer, IServerAdapter *serverAdapter); 36 | 37 | /* 38 | * 初始化 39 | * 40 | * @return 是否成功 41 | */ 42 | bool init(bool isServer = false); 43 | 44 | /** 45 | * 当有数据可读时被Transport调用 46 | * 47 | * @return 是否成功, true - 成功, false - 失败。 48 | */ 49 | bool handleReadEvent(); 50 | 51 | /** 52 | * 在accept中没有写事件 53 | */ 54 | bool handleWriteEvent() 55 | { 56 | return true; 57 | } 58 | 59 | /* 60 | * 超时检查 61 | * 62 | * @param now 当前时间(单位us) 63 | */ 64 | void checkTimeout(int64_t now); 65 | 66 | private: 67 | IPacketStreamer *_streamer; // 数据包解析器 68 | IServerAdapter *_serverAdapter; // 服务器适配器 69 | }; 70 | } 71 | 72 | #endif /*TCPACCEPTOR_H_*/ 73 | -------------------------------------------------------------------------------- /tbnet/tcpcomponent.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBNET_TCPCOMPONENT_H_ 17 | #define TBNET_TCPCOMPONENT_H_ 18 | 19 | namespace tbnet 20 | { 21 | 22 | class TCPComponent : public IOComponent 23 | { 24 | public: 25 | /** 26 | * 构造函数,由Transport调用。 27 | * 28 | * @param owner: 运输层对象 29 | * @param host: 监听ip地址或hostname 30 | * @param port: 监听端口 31 | * @param streamer: 数据包的双向流,用packet创建,解包,组包。 32 | * @param serverAdapter: 用在服务器端,当Connection初始化及Channel创建时回调时用 33 | */ 34 | TCPComponent(Transport *owner, Socket *socket, 35 | IPacketStreamer *streamer, IServerAdapter *serverAdapter); 36 | 37 | /* 38 | * 析构函数 39 | */ 40 | ~TCPComponent(); 41 | 42 | /* 43 | * 初始化 44 | * 45 | * @return 是否成功 46 | */ 47 | bool init(bool isServer = false); 48 | 49 | /* 50 | * 关闭 51 | */ 52 | void close(); 53 | 54 | /* 55 | * 当有数据可写到时被Transport调用 56 | * 57 | * @return 是否成功, true - 成功, false - 失败。 58 | */ 59 | bool handleWriteEvent(); 60 | 61 | /* 62 | * 当有数据可读时被Transport调用 63 | * 64 | * @return 是否成功, true - 成功, false - 失败。 65 | */ 66 | bool handleReadEvent(); 67 | 68 | /* 69 | * 得到connection 70 | * 71 | * @return TCPConnection 72 | */ 73 | TCPConnection *getConnection() 74 | { 75 | return _connection; 76 | } 77 | 78 | /* 79 | * 超时检查 80 | * 81 | * @param now 当前时间(单位us) 82 | */ 83 | void checkTimeout(int64_t now); 84 | 85 | /* 86 | * 连接到socket 87 | */ 88 | bool socketConnect(); 89 | 90 | private: 91 | // TCP连接 92 | TCPConnection *_connection; 93 | int64_t _startConnectTime; 94 | }; 95 | } 96 | 97 | #endif /*TCPCOMPONENT_H_*/ 98 | -------------------------------------------------------------------------------- /tbnet/tcpconnection.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBNET_TCPCONNECTION_H_ 17 | #define TBNET_TCPCONNECTION_H_ 18 | 19 | namespace tbnet 20 | { 21 | 22 | class TCPConnection : public Connection 23 | { 24 | 25 | public: 26 | /* 27 | * 构造函数 28 | */ 29 | TCPConnection(Socket *socket, IPacketStreamer *streamer, IServerAdapter *serverAdapter); 30 | 31 | /* 32 | * 析构函数 33 | */ 34 | ~TCPConnection(); 35 | 36 | /* 37 | * 写出数据 38 | * 39 | * @return 是否成功 40 | */ 41 | bool writeData(); 42 | 43 | /* 44 | * 读入数据 45 | * 46 | * @return 读入数据 47 | */ 48 | bool readData(); 49 | 50 | /* 51 | * 设置写完是否主动关闭 52 | */ 53 | void setWriteFinishClose(bool v) 54 | { 55 | _writeFinishClose = v; 56 | } 57 | 58 | /* 59 | * 清空output的buffer 60 | */ 61 | void clearOutputBuffer() 62 | { 63 | _output.clear(); 64 | } 65 | 66 | /* 67 | * clear input buffer 68 | */ 69 | void clearInputBuffer() 70 | { 71 | _input.clear(); 72 | } 73 | 74 | /** 75 | * 发送setDisconnState 76 | */ 77 | void setDisconnState(); 78 | 79 | private: 80 | DataBuffer _output; // 输出的buffer 81 | DataBuffer _input; // 读入的buffer 82 | PacketHeader _packetHeader; // 读入的packet header 83 | bool _gotHeader; // packet header已经取过 84 | bool _writeFinishClose; // 写完断开 85 | }; 86 | 87 | } 88 | 89 | #endif /*TCPCONNECTION_H_*/ 90 | -------------------------------------------------------------------------------- /tbnet/transport.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBNET_TRANSPORT_H_ 17 | #define TBNET_TRANSPORT_H_ 18 | 19 | #include 20 | 21 | namespace tbnet 22 | { 23 | 24 | class Transport : public tbsys::Runnable 25 | { 26 | 27 | public: 28 | /* 29 | * 构造函数 30 | */ 31 | Transport(); 32 | 33 | /* 34 | * 析造函数 35 | */ 36 | ~Transport(); 37 | 38 | /* 39 | * 起动运输层,创建两个线程,一个用于读,一个用写。 40 | * 41 | * @return 是否成功, true - 成功, false - 失败。 42 | */ 43 | bool start(); 44 | 45 | /* 46 | * 停止,停掉读写线程,及销毁。 47 | * 48 | * @return 是否成功, true - 成功, false - 失败。 49 | */ 50 | bool stop(); 51 | 52 | /* 53 | * 等待线程完全退出。 54 | * 55 | * @return 是否成功, true - 成功, false - 失败。 56 | */ 57 | bool wait(); 58 | 59 | /* 60 | * 线程的运行函数,实现Runnable接口中的函数 61 | * 62 | * @param arg: 运行时传入参数 63 | */ 64 | void run(tbsys::CThread *thread, void *arg); 65 | 66 | /* 67 | * 起一个监听端口。 68 | * 69 | * @param spec: 格式 [upd|tcp]:ip:port 70 | * @param streamer: 数据包的双向流,用packet创建,解包,组包。 71 | * @param serverAdapter: 用在服务器端,当Connection初始化及Channel创建时回调时用 72 | * @return IO组件一个对象的指针 73 | */ 74 | IOComponent *listen(const char *spec, IPacketStreamer *streamer, IServerAdapter *serverAdapter); 75 | 76 | /* 77 | * 创建一个Connection,连接到指定的地址,并加入到Socket的监听事件中。 78 | * 79 | * @param spec: 格式 [upd|tcp]:ip:port 80 | * @param streamer: 数据包的双向流,用packet创建,解包,组包。 81 | * @param autoReconn: 是否重连 82 | * @return 返回一个Connectoion对象指针 83 | */ 84 | Connection *connect(const char *spec, IPacketStreamer *streamer, bool autoReconn = false); 85 | 86 | /* 87 | * 主动断开 88 | */ 89 | bool disconnect(Connection *conn); 90 | 91 | /* 92 | * 加入到iocomponents中 93 | * 94 | * @param ioc: IO组件 95 | * @param readOn: 初始化把读事件打开 96 | * @param writeOn: 初始化把写事件打开 97 | */ 98 | void addComponent(IOComponent *ioc, bool readOn, bool writeOn); 99 | 100 | /* 101 | * 从iocomponents中删除掉 102 | * 103 | * @param ioc: IO组件 104 | */ 105 | void removeComponent(IOComponent *ioc); 106 | 107 | /** 108 | * 是否为stop 109 | */ 110 | bool *getStop(); 111 | 112 | private: 113 | /* 114 | * 把[upd|tcp]:ip:port分开放在args中 115 | * 116 | * @param src: 源格式 117 | * @param args: 目标数组 118 | * @param cnt: 数组中最大个数 119 | * @return 返回的数组中个数 120 | */ 121 | int parseAddr(char *src, char **args, int cnt); 122 | 123 | /* 124 | * socket event 的检测 125 | */ 126 | void eventLoop(SocketEvent *socketEvent); 127 | 128 | /* 129 | * 超时检查 130 | */ 131 | void timeoutLoop(); 132 | 133 | /* 134 | * 释放变量 135 | */ 136 | void destroy(); 137 | 138 | private: 139 | 140 | EPollSocketEvent _socketEvent; // 读写socket事件 141 | tbsys::CThread _readWriteThread; // 读写处理线程 142 | tbsys::CThread _timeoutThread; // 超时检查线程 143 | bool _stop; // 是否被停止 144 | 145 | IOComponent *_delListHead, *_delListTail; // 等待删除的IOComponent集合 146 | IOComponent *_iocListHead, *_iocListTail; // IOComponent集合 147 | bool _iocListChanged; // IOComponent集合被改过 148 | int _iocListCount; 149 | tbsys::CThreadMutex _iocsMutex; 150 | }; 151 | } 152 | 153 | #endif /*TRANSPORT_H_*/ 154 | -------------------------------------------------------------------------------- /tbnet/udpacceptor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBNET_TCPACCEPTOR_H_ 17 | #define TBNET_TCPACCEPTOR_H_ 18 | 19 | namespace tbnet 20 | { 21 | 22 | class UDPAcceptor : public UDPComponent 23 | { 24 | 25 | public: 26 | /** 27 | * 构造函数,由Transport调用。 28 | * 输入: 29 | * transport: 运输层对象:::spec: 格式 [upd|tcp]:ip:port 30 | * streamer: 数据包的双向流,用packet创建,解包,组包。 31 | * serverAdapter: 用在服务器端,当Connection初始化及Channel创建时回调时用 32 | */ 33 | UDPAcceptor(Transport *owner, char *spec, IPacketStreamer *streamer, IServerAdapter *serverAdapter); 34 | 35 | /** 36 | * 当有数据可读时被Transport调用 37 | * 返回 38 | * 是否成功, true - 成功, false - 失败。 39 | */ 40 | bool handleReadEvent(); 41 | 42 | /** 43 | * 不用 44 | */ 45 | bool handleWriteEvent() 46 | { 47 | return false; 48 | } 49 | }; 50 | } 51 | 52 | #endif /*TCPACCEPTOR_H_*/ 53 | -------------------------------------------------------------------------------- /tbnet/udpcomponent.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include "tbnet.h" 17 | 18 | namespace tbnet 19 | { 20 | /** 21 | * 构造函数,由Transport调用。 22 | * 23 | * @param owner: Transport 24 | * @param socket: Socket 25 | * @param streamer: 数据包的双向流,用packet创建,解包,组包。 26 | * @param serverAdapter: 用在服务器端,当Connection初始化及Channel创建时回调时用 27 | */ 28 | UDPComponent::UDPComponent(Transport *owner, Socket *socket, IPacketStreamer *streamer, 29 | IServerAdapter *serverAdapter) : IOComponent(owner, socket) 30 | { 31 | _streamer = streamer; 32 | _serverAdapter = serverAdapter; 33 | } 34 | 35 | /* 36 | * 析构函数 37 | */ 38 | UDPComponent::~UDPComponent() {} 39 | 40 | /* 41 | * 连接到指定的机器 42 | * 43 | * @param isServer: 是否初始化一个服务器的Connection 44 | * @return 是否成功 45 | */ 46 | bool UDPComponent::init(bool isServer) 47 | { 48 | if (!isServer) 49 | { // 不要connect, 是accept产生的 50 | 51 | if (!_socket->connect()) 52 | { 53 | return false; 54 | } 55 | } 56 | _isServer = isServer; 57 | return true; 58 | } 59 | 60 | /* 61 | * 关闭 62 | */ 63 | void UDPComponent::close() {} 64 | 65 | /** 66 | * 当有数据可写到时被Transport调用 67 | * 68 | * @return 是否成功, true - 成功, false - 失败。 69 | */ 70 | bool UDPComponent::handleWriteEvent() 71 | { 72 | return true; 73 | } 74 | 75 | /** 76 | * 当有数据可读时被Transport调用 77 | * 78 | * @return 是否成功, true - 成功, false - 失败。 79 | */ 80 | bool UDPComponent::handleReadEvent() 81 | { 82 | return true; 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /tbnet/udpcomponent.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBNET_UDPCOMPONENT_H_ 17 | #define TBNET_UDPCOMPONENT_H_ 18 | 19 | namespace tbnet 20 | { 21 | 22 | class UDPComponent : public IOComponent 23 | { 24 | 25 | public: 26 | /** 27 | * 构造函数,由Transport调用。 28 | * 29 | * @param owner: Transport 30 | * @param socket: Socket 31 | * @param streamer: 数据包的双向流,用packet创建,解包,组包。 32 | * @param serverAdapter: 用在服务器端,当Connection初始化及Channel创建时回调时用 33 | */ 34 | UDPComponent(Transport *owner, Socket *socket, IPacketStreamer *streamer, IServerAdapter *serverAdapter); 35 | 36 | /* 37 | * 析构函数 38 | */ 39 | ~UDPComponent(); 40 | 41 | /* 42 | * 初始化 43 | * 44 | * @return 是否成功 45 | */ 46 | bool init(bool isServer = false); 47 | 48 | /* 49 | * 关闭 50 | */ 51 | void close(); 52 | 53 | /* 54 | * 当有数据可写到时被Transport调用 55 | * 56 | * @return 是否成功, true - 成功, false - 失败。 57 | */ 58 | bool handleWriteEvent(); 59 | 60 | /* 61 | * 当有数据可读时被Transport调用 62 | * 63 | * @return 是否成功, true - 成功, false - 失败。 64 | */ 65 | bool handleReadEvent(); 66 | 67 | private: 68 | __gnu_cxx::hash_map _connections; // UDP连接集合 69 | IPacketStreamer *_streamer; // streamer 70 | IServerAdapter *_serverAdapter; // serveradapter 71 | }; 72 | } 73 | 74 | #endif /*UDPCOMPONENT_H_*/ 75 | -------------------------------------------------------------------------------- /tbnet/udpconnection.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include "tbnet.h" 17 | 18 | namespace tbnet 19 | { 20 | 21 | /* 22 | * 构造函数 23 | */ 24 | UDPConnection::UDPConnection(Socket *socket, IPacketStreamer *streamer, 25 | IServerAdapter *serverAdapter) : Connection(socket, streamer, serverAdapter) {} 26 | 27 | /* 28 | * 析造函数 29 | */ 30 | UDPConnection::~UDPConnection() {} 31 | 32 | /* 33 | * 写出数据 34 | * 35 | * @return 是否成功 36 | */ 37 | bool UDPConnection::writeData() 38 | { 39 | return true; 40 | } 41 | 42 | /* 43 | * 读入数据 44 | * 45 | * @return 读入数据 46 | */ 47 | bool UDPConnection::readData() 48 | { 49 | return true; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /tbnet/udpconnection.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBNET_UDPCONNECTION_H_ 17 | #define TBNET_UDPCONNECTION_H_ 18 | 19 | namespace tbnet 20 | { 21 | 22 | class UDPConnection : public Connection 23 | { 24 | /* 25 | * 构造函数 26 | */ 27 | UDPConnection(Socket *socket, IPacketStreamer *streamer, IServerAdapter *serverAdapter); 28 | 29 | /* 30 | * 析造函数 31 | */ 32 | ~UDPConnection(); 33 | 34 | /* 35 | * 写出数据 36 | * 37 | * @return 是否成功 38 | */ 39 | bool writeData(); 40 | 41 | /* 42 | * 读入数据 43 | * 44 | * @return 读入数据 45 | */ 46 | bool readData(); 47 | 48 | }; 49 | 50 | } 51 | 52 | #endif /*UDPCONNECTION_H_*/ 53 | -------------------------------------------------------------------------------- /tbsys/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | find_package(Threads) 2 | set(source 3 | atomic.h 4 | tblog.cpp 5 | EventHandler.h 6 | Functional.h 7 | Handle.h 8 | iqueuehandler.h 9 | linklist.h 10 | Lock.h 11 | PublicDefine.h 12 | runnable.h 13 | tblockguard.h 14 | tbnetutil.cpp 15 | tbsys.h 16 | thread.h 17 | threadcond.h 18 | Time.cpp 19 | Monitor.h 20 | bytebuffer.cpp 21 | Cond.cpp 22 | threadmutex.h 23 | config.cpp 24 | CtrlCHandler.cpp 25 | defaultrunnable.cpp 26 | Exception.cpp 27 | filequeue.cpp 28 | filequeuethread.cpp 29 | fileutil.cpp 30 | Memory.hpp 31 | Mutex.cpp 32 | Network.cpp 33 | process.cpp 34 | profiler.cpp 35 | queuethread.cpp 36 | RecMutex.cpp 37 | Service.cpp 38 | Shared.cpp 39 | StaticMutex.cpp 40 | stringutil.cpp 41 | tbrwlock.cpp 42 | TbThread.cpp 43 | tbtimeutil.cpp 44 | ThreadException.cpp 45 | ThreadPool.cpp 46 | Timer.cpp 47 | Timer.cpp 48 | Utility.cpp 49 | WarningBuffer.cpp 50 | ) 51 | 52 | add_library(tbsys ${source}) 53 | target_link_libraries(tbsys ${CMAKE_THREAD_LIBS_INIT}) -------------------------------------------------------------------------------- /tbsys/Cond.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include 17 | #include "Cond.h" 18 | 19 | namespace tbutil 20 | { 21 | Cond::Cond() 22 | { 23 | pthread_condattr_t attr; 24 | int rt = pthread_condattr_init(&attr); 25 | #ifdef _NO_EXCEPTION 26 | assert(0 == rt); 27 | #else 28 | if( 0 != rt ) 29 | { 30 | throw ThreadSyscallException(__FILE__, __LINE__, rt); 31 | } 32 | #endif 33 | 34 | rt = pthread_cond_init(&_cond, &attr); 35 | #ifdef _NO_EXCEPTION 36 | assert(0 == rt); 37 | #else 38 | if( 0 != rt ) 39 | { 40 | throw ThreadSyscallException(__FILE__, __LINE__, rt); 41 | } 42 | #endif 43 | 44 | rt = pthread_condattr_destroy(&attr); 45 | #ifdef _NO_EXCEPTION 46 | assert(0 == rt); 47 | #else 48 | if( 0 != rt ) 49 | { 50 | throw ThreadSyscallException(__FILE__, __LINE__, rt); 51 | } 52 | #endif 53 | } 54 | 55 | Cond::~Cond() 56 | { 57 | pthread_cond_destroy(&_cond); 58 | } 59 | 60 | void Cond::signal() 61 | { 62 | const int rt = pthread_cond_signal(&_cond); 63 | #ifdef _NO_EXCEPTION 64 | assert(0 == rt); 65 | #else 66 | if ( 0 != rt ) 67 | { 68 | throw ThreadSyscallException(__FILE__, __LINE__, rt); 69 | } 70 | #endif 71 | } 72 | 73 | void Cond::broadcast() 74 | { 75 | const int rt = pthread_cond_broadcast(&_cond); 76 | #ifdef _NO_EXCEPTION 77 | assert(0 == rt); 78 | #else 79 | if( 0 != rt ) 80 | { 81 | throw ThreadSyscallException(__FILE__, __LINE__, rt); 82 | } 83 | #endif 84 | } 85 | }//end namespace tbutil 86 | -------------------------------------------------------------------------------- /tbsys/CtrlCHandler.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include 17 | #include "CtrlCHandler.h" 18 | #include "StaticMutex.h" 19 | 20 | using namespace std; 21 | 22 | namespace tbutil 23 | { 24 | static CtrlCHandlerCallback _callback = 0; 25 | static const CtrlCHandler *_handler = 0; 26 | 27 | CtrlCHandlerException::CtrlCHandlerException(const char *file, int line) : 28 | Exception(file, line) 29 | { 30 | } 31 | 32 | static const char *ctrlCHandlerName = "tbutil::CtrlCHandlerException"; 33 | 34 | string CtrlCHandlerException::_name() const 35 | { 36 | return ctrlCHandlerName; 37 | } 38 | 39 | Exception *CtrlCHandlerException::_clone() const 40 | { 41 | return new CtrlCHandlerException(*this); 42 | } 43 | 44 | void CtrlCHandlerException::_throw() const 45 | { 46 | throw *this; 47 | } 48 | 49 | void CtrlCHandler::setCallback(CtrlCHandlerCallback callback) 50 | { 51 | StaticMutex::Lock lock(globalMutex); 52 | _callback = callback; 53 | } 54 | 55 | CtrlCHandlerCallback 56 | CtrlCHandler::getCallback() const 57 | { 58 | StaticMutex::Lock lock(globalMutex); 59 | return _callback; 60 | } 61 | 62 | extern "C" 63 | { 64 | 65 | static void *sigwaitThread(void *) 66 | { 67 | sigset_t ctrlCLikeSignals; 68 | sigemptyset(&ctrlCLikeSignals); 69 | sigaddset(&ctrlCLikeSignals, SIGHUP); 70 | sigaddset(&ctrlCLikeSignals, SIGINT); 71 | sigaddset(&ctrlCLikeSignals, SIGTERM); 72 | sigaddset(&ctrlCLikeSignals, SIGUSR1); 73 | 74 | for (;;) 75 | { 76 | int signal = 0; 77 | int rc = sigwait(&ctrlCLikeSignals, &signal); 78 | if (rc == EINTR) 79 | { 80 | continue; 81 | } 82 | assert(rc == 0); 83 | 84 | rc = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0); 85 | assert(rc == 0); 86 | 87 | CtrlCHandlerCallback callback = _handler->getCallback(); 88 | 89 | if (callback != 0) 90 | { 91 | callback(signal); 92 | } 93 | 94 | rc = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0); 95 | assert(rc == 0); 96 | } 97 | return 0; 98 | } 99 | } 100 | 101 | static pthread_t _tid; 102 | 103 | CtrlCHandler::CtrlCHandler(CtrlCHandlerCallback callback) 104 | { 105 | StaticMutex::Lock lock(globalMutex); 106 | if (_handler != 0) 107 | { 108 | #ifdef _NO_EXCEPTION 109 | assert(0 == _handler); 110 | if (0 != _handler) 111 | { 112 | TBSYS_LOG(ERROR, "%s", "CtrlCHandlerException"); 113 | } 114 | #else 115 | throw CtrlCHandlerException(__FILE__, __LINE__); 116 | #endif 117 | } 118 | else 119 | { 120 | _callback = callback; 121 | _handler = this; 122 | lock.release(); 123 | 124 | sigset_t ctrlCLikeSignals; 125 | sigemptyset(&ctrlCLikeSignals); 126 | sigaddset(&ctrlCLikeSignals, SIGHUP); 127 | sigaddset(&ctrlCLikeSignals, SIGINT); 128 | sigaddset(&ctrlCLikeSignals, SIGTERM); 129 | sigaddset(&ctrlCLikeSignals, SIGUSR1); 130 | int rc = pthread_sigmask(SIG_BLOCK, &ctrlCLikeSignals, 0); 131 | assert(rc == 0); 132 | 133 | // Joinable thread 134 | rc = pthread_create(&_tid, 0, sigwaitThread, 0); 135 | assert(rc == 0); 136 | } 137 | } 138 | 139 | CtrlCHandler::~CtrlCHandler() 140 | { 141 | int rc = pthread_cancel(_tid); 142 | assert(rc == 0); 143 | void *status = 0; 144 | rc = pthread_join(_tid, &status); 145 | assert(rc == 0); 146 | { 147 | StaticMutex::Lock lock(globalMutex); 148 | _handler = 0; 149 | } 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /tbsys/CtrlCHandler.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYS_CTRL_C_HANDLER_H 17 | #define TBSYS_CTRL_C_HANDLER_H 18 | 19 | #include "Exception.h" 20 | 21 | namespace tbutil 22 | { 23 | typedef void (*CtrlCHandlerCallback)(int); 24 | 25 | /** 26 | * @brief CtrlCHanler 用于处理Ctrl+C 及其他类似的发给C++ 进程的信号 27 | * 在任一时刻,在一个进程中只能有 一个CtrlCHandler 实例 28 | */ 29 | class CtrlCHandler 30 | { 31 | public: 32 | 33 | /** 34 | * @brief 用一个回调函数构造一个实例 35 | * 36 | * @param CtrlCHandlerCallback 37 | */ 38 | CtrlCHandler(CtrlCHandlerCallback = 0); 39 | ~CtrlCHandler(); 40 | 41 | /** 42 | * @brief 设置新的回调函数 43 | * 44 | * @param callback 45 | */ 46 | void setCallback(CtrlCHandlerCallback callback); 47 | /** 48 | * @brief 获得当前回调函数 49 | * 50 | * @return 51 | */ 52 | CtrlCHandlerCallback getCallback() const; 53 | }; 54 | 55 | /** 56 | * @brief CtrlCHandler实例如果已经存在就会抛出异常 57 | */ 58 | class CtrlCHandlerException : public Exception 59 | { 60 | public: 61 | 62 | CtrlCHandlerException(const char *, int); 63 | virtual std::string _name() const; 64 | virtual Exception *_clone() const; 65 | virtual void _throw() const; 66 | }; 67 | }//end namespace 68 | #endif 69 | -------------------------------------------------------------------------------- /tbsys/EventHandler.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYS_EVENTHANDLER_H 17 | #define TBSYS_EVENTHANDLER_H 18 | 19 | namespace tbutil 20 | { 21 | class ThreadPool; 22 | /** 23 | * @brief ThreadPoolWorkItem 线程任务队列Item基类,它拥有execute纯虚方法 24 | * 要实例化ThreadPoolWorkItem类,必须继承并实现execute方法 25 | */ 26 | class ThreadPoolWorkItem 27 | { 28 | public: 29 | virtual ~ThreadPoolWorkItem() {} 30 | virtual void destroy()=0; 31 | virtual void execute(const ThreadPool *) = 0; 32 | }; 33 | } 34 | #endif 35 | -------------------------------------------------------------------------------- /tbsys/Exception.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYS_EXCEPTION_H 17 | #define TBSYS_EXCEPTION_H 18 | #include 19 | #include 20 | #include 21 | 22 | #include "tbsys.h" 23 | 24 | //using namespace std; 25 | 26 | namespace tbutil 27 | { 28 | /** 29 | * @brief Exception是对std::exception的卦装 30 | */ 31 | class Exception : public std::exception 32 | { 33 | public: 34 | Exception(); 35 | Exception(const char *, int); 36 | virtual ~Exception() throw(); 37 | virtual std::string name() const; 38 | virtual void print(std::ostream &) const; 39 | virtual const char *what() const throw(); 40 | virtual Exception *clone() const; 41 | virtual void _throw() const; 42 | const char *file() const; 43 | int line() const; 44 | 45 | private: 46 | 47 | const char *_file; 48 | int _line; 49 | static const char *_name; 50 | mutable ::std::string _str; 51 | }; 52 | 53 | std::ostream &operator<<(std::ostream &out, const Exception &ex); 54 | 55 | /** 56 | * @brief Handle为空异常类 57 | */ 58 | class NullHandleException : public Exception 59 | { 60 | public: 61 | 62 | NullHandleException(const char *, int); 63 | virtual ~NullHandleException() throw(); 64 | virtual std::string name() const; 65 | virtual Exception *clone() const; 66 | virtual void _throw() const; 67 | 68 | private: 69 | static const char *_name; 70 | }; 71 | 72 | /** 73 | * @brief 不合法参数异常类 74 | */ 75 | class IllegalArgumentException : public Exception 76 | { 77 | public: 78 | 79 | IllegalArgumentException(const char *, int); 80 | IllegalArgumentException(const char *, int, const std::string &); 81 | virtual ~IllegalArgumentException() throw(); 82 | virtual std::string name() const; 83 | virtual void print(std::ostream &) const; 84 | virtual Exception *clone() const; 85 | virtual void _throw() const; 86 | 87 | std::string reason() const; 88 | 89 | private: 90 | 91 | static const char *_name; 92 | std::string _reason; 93 | }; 94 | 95 | /** 96 | * @brief 系统调用异常类 97 | */ 98 | class SyscallException : public Exception 99 | { 100 | public: 101 | SyscallException(const char *, int); 102 | SyscallException(const char *, int, int); 103 | virtual std::string name() const; 104 | virtual void print(std::ostream &) const; 105 | virtual Exception *clone() const; 106 | virtual void _throw() const; 107 | 108 | int error(); 109 | 110 | int _error; 111 | static const char *_name; 112 | }; 113 | }//end namespace 114 | #endif 115 | -------------------------------------------------------------------------------- /tbsys/Functional.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYS_FUNCTIONAL_H 17 | #define TBSYS_FUNCTIONAL_H 18 | 19 | #include "Handle.h" 20 | #include 21 | 22 | namespace tbutil 23 | { 24 | template 25 | class ConstMemFun : public std::unary_function 26 | { 27 | typedef R (T::*MemberFN)(void) const; 28 | MemberFN _mfn; 29 | 30 | public: 31 | 32 | explicit ConstMemFun(MemberFN p) : _mfn(p) {} 33 | R operator()(H handle) const 34 | { 35 | return (handle.get()->*_mfn)(); 36 | } 37 | }; 38 | 39 | template 40 | inline ConstMemFun > 41 | constMemFun(R(T::* 42 | p)(void) const) 43 | { 44 | return ConstMemFun >(p); 45 | } 46 | }//end namespace 47 | #endif 48 | -------------------------------------------------------------------------------- /tbsys/Lock.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYS_LOCK_H 17 | #define TBSYS_LOCK_H 18 | 19 | #include "ThreadException.h" 20 | 21 | namespace tbutil 22 | { 23 | /** 24 | * @brief LockT是简单的模板类,由构造器和析构器构成 25 | * 构造器针对它的参数调用lock,析构器调用unlock, 26 | * 通过实例化类型为Lock的局部变量,可以完全解决死锁问题 27 | */ 28 | template 29 | class LockT 30 | { 31 | public: 32 | 33 | LockT(const T &mutex) : 34 | _mutex(mutex) 35 | { 36 | _mutex.lock(); 37 | _acquired = true; 38 | } 39 | 40 | ~LockT() 41 | { 42 | if (_acquired) 43 | { 44 | _mutex.unlock(); 45 | } 46 | } 47 | 48 | // 显示上锁 49 | void acquire() const 50 | { 51 | if (_acquired) 52 | { 53 | #ifdef _NO_EXCEPTION 54 | assert(!"ThreadLockedException"); 55 | #else 56 | throw ThreadLockedException(__FILE__, __LINE__); 57 | #endif 58 | } 59 | _mutex.lock(); 60 | _acquired = true; 61 | } 62 | 63 | bool tryAcquire() const 64 | { 65 | if (_acquired) 66 | { 67 | #ifdef _NO_EXCEPTION 68 | assert(!"ThreadLockedException"); 69 | #else 70 | throw ThreadLockedException(__FILE__, __LINE__); 71 | #endif 72 | } 73 | _acquired = _mutex.tryLock(); 74 | return _acquired; 75 | } 76 | 77 | void release() const 78 | { 79 | if (!_acquired) 80 | { 81 | #ifdef _NO_EXCEPTION 82 | assert(!"ThreadLockedException"); 83 | #else 84 | throw ThreadLockedException(__FILE__, __LINE__); 85 | #endif 86 | } 87 | _mutex.unlock(); 88 | _acquired = false; 89 | } 90 | 91 | bool acquired() const 92 | { 93 | return _acquired; 94 | } 95 | 96 | protected: 97 | 98 | LockT(const T &mutex, bool) : 99 | _mutex(mutex) 100 | { 101 | _acquired = _mutex.tryLock(); 102 | } 103 | 104 | private: 105 | 106 | LockT(const LockT &); 107 | LockT &operator=(const LockT &); 108 | 109 | const T &_mutex; 110 | mutable bool _acquired; // 是否已经上锁 111 | 112 | friend class Cond; 113 | }; 114 | 115 | // 在构造函数中尝试上锁,若上锁成功,则在析构函数之中解锁 116 | /** 117 | * @brief TryLockT是简单的模板类,由构造器和析构器构成 118 | * 构造器针对它的参数调用lock,析构器调用unlock, 119 | * 通过实例化类型为TryLock的局部变量,可以完全解决死锁问题 120 | */ 121 | template 122 | class TryLockT : public LockT 123 | { 124 | public: 125 | 126 | TryLockT(const T &mutex) : 127 | LockT(mutex, true) {} 128 | }; 129 | } 130 | 131 | #endif 132 | -------------------------------------------------------------------------------- /tbsys/Mutex.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include "Mutex.h" 17 | 18 | namespace tbutil 19 | { 20 | Mutex::Mutex() 21 | { 22 | const int rt = pthread_mutex_init(&_mutex, NULL); 23 | #ifdef _NO_EXCEPTION 24 | assert(rt == 0); 25 | if (rt != 0) 26 | { 27 | TBSYS_LOG(ERROR, "%s", "ThreadSyscallException"); 28 | } 29 | #else 30 | if ( rt != 0 ) 31 | { 32 | throw ThreadSyscallException(__FILE__, __LINE__, rt); 33 | } 34 | #endif 35 | } 36 | 37 | Mutex::~Mutex() 38 | { 39 | const int rt = pthread_mutex_destroy(&_mutex); 40 | assert(rt == 0); 41 | if (rt != 0) 42 | { 43 | TBSYS_LOG(ERROR, "%s", "ThreadSyscallException"); 44 | } 45 | } 46 | 47 | void Mutex::lock() const 48 | { 49 | const int rt = pthread_mutex_lock(&_mutex); 50 | #ifdef _NO_EXCEPTION 51 | assert(rt == 0); 52 | if (rt != 0) 53 | { 54 | if (rt == EDEADLK) 55 | { 56 | TBSYS_LOG(ERROR, "%s", "ThreadLockedException "); 57 | } 58 | else 59 | { 60 | TBSYS_LOG(ERROR, "%s", "ThreadSyscallException"); 61 | } 62 | } 63 | #else 64 | if( rt != 0 ) 65 | { 66 | if(rt == EDEADLK) 67 | { 68 | throw ThreadLockedException(__FILE__, __LINE__); 69 | } 70 | else 71 | { 72 | throw ThreadSyscallException(__FILE__, __LINE__, rt); 73 | } 74 | } 75 | #endif 76 | } 77 | 78 | bool Mutex::tryLock() const 79 | { 80 | const int rt = pthread_mutex_trylock(&_mutex); 81 | #ifdef _NO_EXCEPTION 82 | if (rt != 0 && rt != EBUSY) 83 | { 84 | if (rt == EDEADLK) 85 | { 86 | TBSYS_LOG(ERROR, "%s", "ThreadLockedException "); 87 | } 88 | else 89 | { 90 | TBSYS_LOG(ERROR, "%s", "ThreadSyscallException"); 91 | } 92 | return false; 93 | } 94 | #else 95 | if(rt != 0 && rt != EBUSY) 96 | { 97 | if(rt == EDEADLK) 98 | { 99 | throw ThreadLockedException(__FILE__, __LINE__); 100 | } 101 | else 102 | { 103 | throw ThreadSyscallException(__FILE__, __LINE__, rt); 104 | } 105 | } 106 | #endif 107 | return (rt == 0); 108 | } 109 | 110 | void Mutex::unlock() const 111 | { 112 | const int rt = pthread_mutex_unlock(&_mutex); 113 | #ifdef _NO_EXCEPTION 114 | assert(rt == 0); 115 | if (rt != 0) 116 | { 117 | TBSYS_LOG(ERROR, "%s", "ThreadSyscallException"); 118 | } 119 | #else 120 | if ( rt != 0 ) 121 | { 122 | throw ThreadSyscallException(__FILE__, __LINE__, rt); 123 | } 124 | #endif 125 | } 126 | 127 | void Mutex::unlock(LockState &state) const 128 | { 129 | state.mutex = &_mutex; 130 | } 131 | 132 | void Mutex::lock(LockState &) const 133 | { 134 | } 135 | 136 | bool Mutex::willUnlock() const 137 | { 138 | return true; 139 | } 140 | }//end namespace tbutil 141 | -------------------------------------------------------------------------------- /tbsys/Mutex.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYS_MUTEX_H 17 | #define TBSYS_MUTEX_H 18 | 19 | #include 20 | #include "Lock.h" 21 | #include "ThreadException.h" 22 | 23 | namespace tbutil 24 | { 25 | /** 26 | * @brief 互斥体,被实现为简单的数据结构 27 | * Mutex非递归锁,使用时需要注意以下几点: 28 | * 1.不要在同一线程中第二次调用lock 29 | * 2.除非发出调用的线程持有某个互斥体,否则不要针对该互斥体调用unlock 30 | */ 31 | class Mutex 32 | { 33 | public: 34 | 35 | typedef LockT Lock; 36 | typedef TryLockT TryLock; 37 | 38 | Mutex(); 39 | ~Mutex(); 40 | 41 | /** 42 | * @brief lock 函数尝试获取互斥体。如果互斥体已经锁住,它就会挂起发出 43 | * 调用的线程(calling thread),直到互斥体变得可用为止。一旦发出调 44 | * 用的线程获得了互斥体,调用就会立即返回 45 | */ 46 | void lock() const; 47 | 48 | /** 49 | * @brief tryLock 函数尝试获取互斥体。如果互斥体可用,互斥体就会锁 50 | * 住,而调用就会返回true。如果其他线程锁住了互斥体,调用返回false 51 | * 52 | * @return 53 | */ 54 | bool tryLock() const; 55 | 56 | /** 57 | * @brief unlock 函数解除互斥体的加锁 58 | */ 59 | void unlock() const; 60 | 61 | /** 62 | * @brief 是否已经加锁标记 63 | * 64 | * @return 65 | */ 66 | bool willUnlock() const; 67 | 68 | private: 69 | // no copying 70 | Mutex(const Mutex &); 71 | Mutex &operator=(const Mutex &); 72 | 73 | struct LockState 74 | { 75 | pthread_mutex_t *mutex; 76 | }; 77 | 78 | void unlock(LockState &) const; 79 | void lock(LockState &) const; 80 | mutable pthread_mutex_t _mutex; 81 | 82 | friend class Cond; 83 | }; 84 | }//end namespace 85 | #endif 86 | -------------------------------------------------------------------------------- /tbsys/Network.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include "tbsys.h" 17 | #include "Network.h" 18 | #include "Exception.h" 19 | namespace tbutilInternal 20 | { 21 | 22 | bool interrupted() 23 | { 24 | return errno == EINTR; 25 | } 26 | 27 | int setBlock(SOCKET fd, bool block) 28 | { 29 | if (block) 30 | { 31 | int flags = fcntl(fd, F_GETFL); 32 | flags &= ~O_NONBLOCK; 33 | if (fcntl(fd, F_SETFL, flags) == SOCKET_ERROR) 34 | { 35 | #ifdef _NO_EXCEPTION 36 | closeSocketNoThrow(fd); 37 | return errno; 38 | #else 39 | closeSocketNoThrow( fd ); 40 | //SocketException ex(__FILE__,__LINE__); 41 | //ex.error = errno; 42 | //throw ex; 43 | #endif 44 | } 45 | } 46 | else 47 | { 48 | int flags = fcntl(fd, F_GETFL); 49 | flags |= O_NONBLOCK; 50 | if (fcntl(fd, F_SETFL, flags) == SOCKET_ERROR) 51 | { 52 | #ifdef _NO_EXCEPTION 53 | closeSocketNoThrow(fd); 54 | return errno; 55 | #else 56 | closeSocketNoThrow( fd ); 57 | /*SocketException ex(__FILE__,__LINE__); 58 | ex.error = errno; 59 | throw ex;*/ 60 | #endif 61 | } 62 | } 63 | return EXIT_SUCCESS; 64 | } 65 | 66 | int createPipe(SOCKET fds[2]) 67 | { 68 | if (::pipe(fds) != 0) 69 | { 70 | #ifdef _NO_EXCEPTION 71 | return -1; 72 | #else 73 | tbutil::SyscallException ex(__FILE__,__LINE__); 74 | ex._error = tbutil::getSystemErrno(); 75 | throw ex; 76 | #endif 77 | } 78 | #ifdef _NO_EXCEPTION 79 | const int iRet = setBlock(fds[0], true); 80 | if (iRet != 0) 81 | { 82 | return iRet; 83 | } 84 | const int iRet2 = setBlock(fds[1], true); 85 | if (iRet2 != 0) 86 | { 87 | return iRet2; 88 | } 89 | #else 90 | try 91 | { 92 | setBlock(fds[0] , true ); 93 | } 94 | catch(...) 95 | { 96 | closeSocketNoThrow( fds[0] ); 97 | throw; 98 | } 99 | 100 | try 101 | { 102 | setBlock(fds[1] , true ); 103 | } 104 | catch(...) 105 | { 106 | closeSocketNoThrow( fds[1] ); 107 | throw; 108 | } 109 | #endif 110 | return EXIT_SUCCESS; 111 | } 112 | 113 | int closeSocketNoThrow(SOCKET fd) 114 | { 115 | const int error = errno; 116 | close(fd); 117 | errno = error; 118 | return errno; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /tbsys/Network.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYS_NETWORK_H 17 | #define TBSYS_NETWORK_H 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #define SOCKET int 29 | #define SOCKET_ERROR -1 30 | #define INVALID_SOCKET -1 31 | 32 | #ifndef SHUT_RD 33 | #define SHUT_RD 0 34 | #endif 35 | 36 | #ifndef SHUT_WR 37 | #define SHUT_WR 1 38 | #endif 39 | 40 | #ifndef SHUT_RDWR 41 | #define SHUT_RDWR 2 42 | #endif 43 | 44 | namespace tbutilInternal 45 | { 46 | 47 | bool interrupted(); 48 | 49 | int setBlock(SOCKET fd, bool block); 50 | 51 | int createPipe(SOCKET fds[2]); 52 | 53 | int closeSocketNoThrow(SOCKET fd); 54 | } 55 | #endif 56 | -------------------------------------------------------------------------------- /tbsys/RecMutex.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include "RecMutex.h" 17 | #include "Exception.h" 18 | 19 | namespace tbutil 20 | { 21 | RecMutex::RecMutex() : 22 | _count(0) 23 | { 24 | pthread_mutexattr_t attr; 25 | int rt = pthread_mutexattr_init(&attr); 26 | #ifdef _NO_EXCEPTION 27 | assert(0 == rt); 28 | if (rt != 0) 29 | { 30 | TBSYS_LOG(ERROR, "%s", "ThreadSyscallException"); 31 | } 32 | #else 33 | if ( 0 != rt ) 34 | { 35 | throw ThreadSyscallException(__FILE__, __LINE__, rt); 36 | } 37 | #endif 38 | rt = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); 39 | #ifdef _NO_EXCEPTION 40 | assert(0 == rt); 41 | if (rt != 0) 42 | { 43 | TBSYS_LOG(ERROR, "%s", "ThreadSyscallException"); 44 | } 45 | #else 46 | if ( 0 != rt ) 47 | { 48 | throw ThreadSyscallException(__FILE__, __LINE__, rt); 49 | } 50 | #endif 51 | rt = pthread_mutex_init(&_mutex, &attr); 52 | #ifdef _NO_EXCEPTION 53 | assert(0 == rt); 54 | if (rt != 0) 55 | { 56 | TBSYS_LOG(ERROR, "%s", "ThreadSyscallException"); 57 | } 58 | #else 59 | if ( 0 != rt ) 60 | { 61 | throw ThreadSyscallException(__FILE__, __LINE__, rt); 62 | } 63 | #endif 64 | 65 | rt = pthread_mutexattr_destroy(&attr); 66 | #ifdef _NO_EXCEPTION 67 | assert(0 == rt); 68 | if (rt != 0) 69 | { 70 | TBSYS_LOG(ERROR, "%s", "ThreadSyscallException"); 71 | } 72 | #else 73 | if ( 0 != rt ) 74 | { 75 | throw ThreadSyscallException(__FILE__, __LINE__, rt); 76 | } 77 | #endif 78 | } 79 | 80 | RecMutex::~RecMutex() 81 | { 82 | assert(_count == 0); 83 | const int rc = pthread_mutex_destroy(&_mutex); 84 | assert(rc == 0); 85 | if (rc != 0) 86 | { 87 | TBSYS_LOG(ERROR, "%s", "ThreadSyscallException"); 88 | } 89 | } 90 | 91 | void RecMutex::lock() const 92 | { 93 | const int rt = pthread_mutex_lock(&_mutex); 94 | #ifdef _NO_EXCEPTION 95 | assert(0 == rt); 96 | if (rt != 0) 97 | { 98 | TBSYS_LOG(ERROR, "%s", "ThreadSyscallException"); 99 | } 100 | #else 101 | if(0 != rt) 102 | { 103 | throw ThreadSyscallException(__FILE__, __LINE__, rt); 104 | } 105 | #endif 106 | if (++_count > 1) 107 | { 108 | const int rc = pthread_mutex_unlock(&_mutex); 109 | assert(rc == 0); 110 | } 111 | } 112 | 113 | bool RecMutex::tryLock() const 114 | { 115 | const int rc = pthread_mutex_trylock(&_mutex); 116 | const bool result = (rc == 0); 117 | if (!result) 118 | { 119 | #ifdef _NO_EXCEPTION 120 | assert(EBUSY == rc); 121 | #else 122 | if(rc != EBUSY) 123 | { 124 | throw ThreadSyscallException(__FILE__, __LINE__, rc); 125 | } 126 | #endif 127 | } 128 | else if (++_count > 1) 129 | { 130 | const int rt = pthread_mutex_unlock(&_mutex); 131 | #ifdef _NO_EXCEPTION 132 | assert(0 == rt); 133 | if (rt != 0) 134 | { 135 | TBSYS_LOG(ERROR, "%s", "ThreadSyscallException"); 136 | } 137 | #else 138 | if( 0 != rt) 139 | { 140 | throw ThreadSyscallException(__FILE__, __LINE__, rc); 141 | } 142 | #endif 143 | } 144 | return result; 145 | } 146 | 147 | void RecMutex::unlock() const 148 | { 149 | if (--_count == 0) 150 | { 151 | const int rc = pthread_mutex_unlock(&_mutex); 152 | assert(rc == 0); 153 | } 154 | } 155 | 156 | void RecMutex::unlock(LockState &state) const 157 | { 158 | state.mutex = &_mutex; 159 | state.count = _count; 160 | _count = 0; 161 | } 162 | 163 | void RecMutex::lock(LockState &state) const 164 | { 165 | _count = state.count; 166 | } 167 | 168 | bool RecMutex::willUnlock() const 169 | { 170 | return _count == 1; 171 | } 172 | }//end namespace 173 | -------------------------------------------------------------------------------- /tbsys/RecMutex.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYS_RMUTEX_H 17 | #define TBSYS_RMUTEX_H 18 | #include "Lock.h" 19 | #include "ThreadException.h" 20 | 21 | namespace tbutil 22 | { 23 | class Cond; 24 | /** 25 | * @brief RecMutex 实现的是递归互斥体 26 | * 非递归互斥体的使用一样,在使用递归互斥体时,你必须遵守一些简 27 | * 单的规则: 28 | * 1.除非发出调用的线程持有锁,否则不要针对某个互斥体调用unlock 29 | * 2.要让互斥体能够被其他线程获取,你调用unlock 的次数必须和你调用 30 | * lock 的次数相同(在递归互斥体的内部实现中,有一个初始化成零的 31 | * 计数器。每次调用lock,计数器就会加一,每次调用unlock,计数 32 | * 器就会减一; 当计数器回到零时,另外的线程就可以获取互斥体了) 33 | */ 34 | class RecMutex 35 | { 36 | public: 37 | 38 | typedef LockT Lock; 39 | typedef TryLockT TryLock; 40 | 41 | RecMutex(); 42 | ~RecMutex(); 43 | 44 | /** 45 | * @brief lock 函数尝试获取互斥体。如果互斥体已被另一个线程锁住,它就 46 | * 会挂起发出调用的线程,直到互斥体变得可用为止。如果互斥体可用、 47 | * 或者已经被发出调用的线程锁住,这个调用就会锁住互斥体,并立即返回 48 | */ 49 | void lock() const; 50 | 51 | /** 52 | * @brief tryLock函数的功能与lock类似,但如果互斥体已被另一个线程锁住, 53 | * 它不会阻塞调用者,而会返回false。否则返回值是true 54 | * @return 55 | */ 56 | bool tryLock() const; 57 | 58 | /** 59 | * @brief unlock 函数解除互斥体的加锁 60 | */ 61 | void unlock() const; 62 | 63 | bool willUnlock() const; 64 | 65 | private: 66 | 67 | // noncopyable 68 | RecMutex(const RecMutex &); 69 | RecMutex &operator=(const RecMutex &); 70 | 71 | struct LockState 72 | { 73 | pthread_mutex_t *mutex; 74 | int count; 75 | }; 76 | 77 | void unlock(LockState &) const; 78 | void lock(LockState &) const; 79 | 80 | friend class Cond; 81 | 82 | mutable pthread_mutex_t _mutex; 83 | 84 | mutable int _count; 85 | }; 86 | }//end namespace 87 | #endif 88 | -------------------------------------------------------------------------------- /tbsys/Shared.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include 17 | #include "Shared.h" 18 | 19 | namespace tbutil 20 | { 21 | SimpleShared::SimpleShared() : 22 | _ref(0), 23 | _noDelete(false) 24 | { 25 | } 26 | 27 | SimpleShared::SimpleShared(const SimpleShared &) : 28 | _ref(0), 29 | _noDelete(false) 30 | { 31 | } 32 | 33 | Shared::Shared() : 34 | _ref(0), 35 | _noDelete(false) 36 | { 37 | } 38 | 39 | Shared::Shared(const Shared &) : 40 | _ref(0), 41 | _noDelete(false) 42 | { 43 | } 44 | 45 | void Shared::__incRef() 46 | { 47 | _mutex.lock(); 48 | ++_ref; 49 | _mutex.unlock(); 50 | } 51 | 52 | void Shared::__decRef() 53 | { 54 | _mutex.lock(); 55 | bool doDelete = false; 56 | assert(_ref > 0); 57 | if (--_ref == 0) 58 | { 59 | doDelete = !_noDelete; 60 | _noDelete = true; 61 | } 62 | _mutex.unlock(); 63 | if (doDelete) 64 | { 65 | delete this; 66 | } 67 | } 68 | 69 | int Shared::__getRef() const 70 | { 71 | _mutex.lock(); 72 | const int ref = _ref; 73 | _mutex.unlock(); 74 | return ref; 75 | } 76 | 77 | void Shared::__setNoDelete(bool b) 78 | { 79 | _noDelete = b; 80 | } 81 | }//end namespace tbutil 82 | -------------------------------------------------------------------------------- /tbsys/Shared.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYS_SHARED_H 17 | #define TBSYS_SHARED_H 18 | #include "Mutex.h" 19 | namespace tbutil 20 | { 21 | /** 22 | * @brief SimpleShared类提供简单的引用计数 23 | */ 24 | class SimpleShared 25 | { 26 | public: 27 | 28 | SimpleShared(); 29 | SimpleShared(const SimpleShared &); 30 | 31 | virtual ~SimpleShared() 32 | { 33 | } 34 | 35 | SimpleShared &operator=(const SimpleShared &) 36 | { 37 | return *this; 38 | } 39 | 40 | void __incRef() 41 | { 42 | assert(_ref >= 0); 43 | ++_ref; 44 | } 45 | 46 | void __decRef() 47 | { 48 | assert(_ref > 0); 49 | if (--_ref == 0) 50 | { 51 | if (!_noDelete) 52 | { 53 | _noDelete = true; 54 | delete this; 55 | } 56 | } 57 | } 58 | 59 | int __getRef() const 60 | { 61 | return _ref; 62 | } 63 | 64 | void __setNoDelete(bool b) 65 | { 66 | _noDelete = b; 67 | } 68 | 69 | private: 70 | 71 | int _ref; 72 | bool _noDelete; 73 | }; 74 | 75 | /** 76 | * @brief Shared 提供简单的引用计数,主要用于智能指针 77 | * 如果要用于智能指针,用户的类需要继承此类 78 | */ 79 | class Shared 80 | { 81 | public: 82 | 83 | Shared(); 84 | Shared(const Shared &); 85 | 86 | virtual ~Shared() 87 | { 88 | } 89 | 90 | Shared &operator=(const Shared &) 91 | { 92 | return *this; 93 | } 94 | 95 | /** 96 | * @brief 增加引用计数 97 | */ 98 | virtual void __incRef(); 99 | /** 100 | * @brief 减少引用计数 101 | */ 102 | virtual void __decRef(); 103 | /** 104 | * @brief 获取当前引用计数 105 | * 106 | * @return 107 | */ 108 | virtual int __getRef() const; 109 | /** 110 | * @brief 设置__noDelete标志 111 | * true: 当引用计数为0时不删除它管理的对象 112 | * false: 当引用计数为0时删除它管理的对象 113 | * @param bool 114 | */ 115 | virtual void __setNoDelete(bool); 116 | 117 | protected: 118 | int _ref; 119 | bool _noDelete; 120 | Mutex _mutex; 121 | }; 122 | }//end namespace 123 | #endif 124 | -------------------------------------------------------------------------------- /tbsys/StaticMutex.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include "StaticMutex.h" 17 | tbutil::StaticMutex tbutil::globalMutex = TNET_STATIC_MUTEX_INITIALIZER; 18 | -------------------------------------------------------------------------------- /tbsys/StaticMutex.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYS_STATIC_MUTEX_H 17 | #define TBSYS_STATIC_MUTEX_H 18 | #include "Lock.h" 19 | #include "ThreadException.h" 20 | namespace tbutil 21 | { 22 | class Cond; 23 | /** 24 | * @brief 互斥体,被实现为简单的数据结构 25 | * 所以其实例可以静态声明,并在编译过程中初始化 26 | * StaticMutex是非递归锁,使用时需要注意以下几点: 27 | * 1.不要在同一线程中第二次调用lock 28 | * 2.除非发出调用的线程持有某个互斥体,否则不要针对该互斥体调用unlock 29 | */ 30 | class StaticMutex 31 | { 32 | public: 33 | 34 | typedef LockT Lock; 35 | typedef TryLockT TryLock; 36 | 37 | /** 38 | * @brief lock 函数尝试获取互斥体。如果互斥体已经锁住,它就会挂起发出 39 | * 调用的线程(calling thread),直到互斥体变得可用为止。一旦发出调 40 | * 用的线程获得了互斥体,调用就会立即返回 41 | */ 42 | void lock() const; 43 | 44 | /** 45 | * @brief tryLock 函数尝试获取互斥体。如果互斥体可用,互斥体就会锁 46 | 住,而调用就会返回true。如果其他线程锁住了互斥体,调用返回false 47 | * 48 | * @return 49 | */ 50 | bool tryLock() const; 51 | 52 | /** 53 | * @brief unlock 函数解除互斥体的加锁 54 | */ 55 | void unlock() const; 56 | 57 | mutable pthread_mutex_t _mutex; 58 | 59 | friend class Cond; 60 | private: 61 | struct LockState 62 | { 63 | pthread_mutex_t *mutex; 64 | }; 65 | 66 | void unlock(LockState &) const; 67 | void lock(LockState &) const; 68 | }; 69 | 70 | #define TNET_STATIC_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER } 71 | 72 | extern StaticMutex globalMutex; 73 | 74 | inline void StaticMutex::lock() const 75 | { 76 | const int rt = pthread_mutex_lock(&_mutex); 77 | if (0 != rt) 78 | { 79 | if (rt == EDEADLK) 80 | { 81 | #ifdef _NO_EXCEPTION 82 | if (rt != 0) 83 | { 84 | assert(!"ThreadLockedException"); 85 | TBSYS_LOG(ERROR, "%s", "ThreadLockedException"); 86 | } 87 | #else 88 | throw ThreadLockedException(__FILE__, __LINE__); 89 | #endif 90 | } 91 | else 92 | { 93 | #ifdef _NO_EXCEPTION 94 | if (rt != 0) 95 | { 96 | assert(!"ThreadSyscallException"); 97 | TBSYS_LOG(ERROR, "%s", "ThreadSyscallException"); 98 | } 99 | #else 100 | throw ThreadSyscallException(__FILE__, __LINE__, rt); 101 | #endif 102 | } 103 | } 104 | } 105 | 106 | inline bool StaticMutex::tryLock() const 107 | { 108 | const int rc = pthread_mutex_trylock(&_mutex); 109 | if (rc != 0 && rc != EBUSY) 110 | { 111 | if (rc == EDEADLK) 112 | { 113 | #ifdef _NO_EXCEPTION 114 | if (rc != 0) 115 | { 116 | assert(!"ThreadLockedException"); 117 | TBSYS_LOG(ERROR, "%s", "ThreadLockedException"); 118 | } 119 | #else 120 | throw ThreadLockedException(__FILE__, __LINE__); 121 | #endif 122 | } 123 | else 124 | { 125 | #ifdef _NO_EXCEPTION 126 | if (rc != 0) 127 | { 128 | assert(!"ThreadSyscallException"); 129 | TBSYS_LOG(ERROR, "%s", "ThreadSyscallException"); 130 | } 131 | #else 132 | throw ThreadSyscallException(__FILE__, __LINE__,rc); 133 | #endif 134 | } 135 | } 136 | return (rc == 0); 137 | } 138 | 139 | inline void StaticMutex::unlock() const 140 | { 141 | const int rc = pthread_mutex_unlock(&_mutex); 142 | #ifdef _NO_EXCEPTION 143 | if (rc != 0) 144 | { 145 | assert(!"ThreadSyscallException"); 146 | TBSYS_LOG(ERROR, "%s", "ThreadSyscallException"); 147 | } 148 | #else 149 | if(rc != 0) 150 | { 151 | throw ThreadSyscallException(__FILE__, __LINE__, rc); 152 | } 153 | #endif 154 | } 155 | 156 | inline void 157 | StaticMutex::unlock(LockState &state) const 158 | { 159 | state.mutex = &_mutex; 160 | } 161 | 162 | inline void 163 | StaticMutex::lock(LockState &) const 164 | { 165 | } 166 | 167 | }// end namespace tbutil 168 | #endif 169 | -------------------------------------------------------------------------------- /tbsys/TbThread.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYSEX_THREAD_H 17 | #define TBSYSEX_THREAD_H 18 | #include "Shared.h" 19 | #include "Handle.h" 20 | #include "Mutex.h" 21 | #include "Cond.h" 22 | #include "Time.h" 23 | 24 | namespace tbutil 25 | { 26 | /** 27 | * @brief Thread类是一个抽象类,它有一个run纯虚方法,如果要实例化Thread类 28 | * 用户必须继承并实现run方法 29 | */ 30 | class Thread : virtual public tbutil::Shared 31 | { 32 | public: 33 | 34 | Thread(); 35 | virtual ~Thread(); 36 | 37 | virtual void run() = 0; 38 | 39 | /** 40 | * @brief 这个成员函数启动新创建的线程 41 | * 42 | * @param stackSize: 栈的大小 43 | * 44 | * @return 45 | */ 46 | int start(size_t stackSize = 0); 47 | 48 | /** 49 | * @brief 如果底层的线程还没有退出(也就是说,还没有离开它的run 方 50 | * 法),这个方法返回真;否则返回假。如果你想要实现非阻塞式的join, isAlive 很有用 51 | * 52 | * @return 53 | */ 54 | bool isAlive() const; 55 | 56 | /** 57 | * @brief 设置线程存活标志为false 58 | */ 59 | void _done(); 60 | 61 | /** 62 | * @brief 这个方法挂起发出调用的线程,直到join 所针对的线程终止为止 63 | * 64 | * @return 65 | */ 66 | int join(); 67 | 68 | /** 69 | * @brief 这个方法分离一个线程。一旦线程分离,你不能再与它汇合 70 | * 如果你针对已经分离的线程、或是已经汇合的线程调用detach, 71 | * 会产生不确定的行为 72 | * @return 73 | */ 74 | int detach(); 75 | 76 | /** 77 | * @brief 这个函数返回每个线程的唯一标识符 78 | * 79 | * @return 80 | */ 81 | pthread_t id() const; 82 | 83 | /** 84 | * @brief 这个方法使得它所针对的线程放弃CPU,让其他线程运行 85 | */ 86 | static void yield(); 87 | /** 88 | * @brief 这个方法挂起线程,时间长度由Time 参数指定 89 | * 90 | * @param timeout : 挂起的超时时间 91 | */ 92 | static void ssleep(const tbutil::Time &timeout); 93 | 94 | protected: 95 | bool _running; //线程运行标志 96 | bool _started; //线程是否处于开始状态 97 | bool _detachable; //是否全使线程处于分离状态 98 | pthread_t _thread;//线程ID 99 | tbutil::Mutex _mutex; //线程运行标志锁 100 | private: 101 | // no copying 102 | Thread(const Thread &); 103 | Thread &operator=(const Thread &); 104 | }; 105 | typedef tbutil::Handle ThreadPtr; 106 | }//end namespace tbutil 107 | 108 | #endif 109 | 110 | -------------------------------------------------------------------------------- /tbsys/ThreadException.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYS_THREADEXCEPTION_H 17 | #define TBSYS_THREADEXCEPTION_H 18 | #include "Exception.h" 19 | #include "Time.h" 20 | 21 | namespace tbutil 22 | { 23 | /** 24 | * @brief 调用线程相关的系统调用异常类 25 | */ 26 | class ThreadSyscallException : public SyscallException 27 | { 28 | public: 29 | 30 | ThreadSyscallException(const char *, int, int); 31 | virtual std::string name() const; 32 | virtual Exception *clone() const; 33 | virtual void _throw() const; 34 | 35 | private: 36 | 37 | static const char *_name; 38 | }; 39 | 40 | /** 41 | * @brief 当前线程已经被锁住异常 42 | */ 43 | class ThreadLockedException : public Exception 44 | { 45 | public: 46 | 47 | ThreadLockedException(const char *, int); 48 | virtual std::string name() const; 49 | virtual Exception *clone() const; 50 | virtual void _throw() const; 51 | 52 | private: 53 | 54 | static const char *_name; 55 | }; 56 | 57 | /** 58 | * @brief 线程Start时的异常 59 | */ 60 | class ThreadStartedException : public Exception 61 | { 62 | public: 63 | 64 | ThreadStartedException(const char *, int); 65 | virtual std::string name() const; 66 | virtual Exception *clone() const; 67 | virtual void _throw() const; 68 | 69 | private: 70 | 71 | static const char *_name; 72 | }; 73 | 74 | /** 75 | * @brief 线程没有调用Start异常 76 | */ 77 | class ThreadNotStartedException : public Exception 78 | { 79 | public: 80 | 81 | ThreadNotStartedException(const char *, int); 82 | virtual std::string name() const; 83 | virtual Exception *clone() const; 84 | virtual void _throw() const; 85 | 86 | private: 87 | 88 | static const char *_name; 89 | }; 90 | 91 | /** 92 | * @brief 调用线程控制系统调用异常 93 | */ 94 | class BadThreadControlException : public Exception 95 | { 96 | public: 97 | 98 | BadThreadControlException(const char *, int); 99 | virtual std::string name() const; 100 | virtual Exception *clone() const; 101 | virtual void _throw() const; 102 | 103 | private: 104 | 105 | static const char *_name; 106 | }; 107 | 108 | /** 109 | * @brief 超时异常 110 | */ 111 | class InvalidTimeoutException : public Exception 112 | { 113 | public: 114 | 115 | InvalidTimeoutException(const char *, int, const Time &); 116 | virtual std::string name() const; 117 | virtual void print(std::ostream &) const; 118 | virtual Exception *clone() const; 119 | virtual void _throw() const; 120 | 121 | private: 122 | 123 | Time _timeout; 124 | static const char *_name; 125 | }; 126 | 127 | /** 128 | * @brief 创建线程异常 129 | */ 130 | class ThreadCreateException : public Exception 131 | { 132 | public: 133 | ThreadCreateException(const char *, int); 134 | virtual std::string name() const; 135 | virtual void print(std::ostream &) const; 136 | virtual Exception *clone() const; 137 | virtual void _throw() const; 138 | private: 139 | static const char *_name; 140 | }; 141 | }//end namespace 142 | #endif 143 | 144 | -------------------------------------------------------------------------------- /tbsys/ThreadPool.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYS_THREAD_POOL_H 17 | #define TBSYS_THREAD_POOL_H 18 | #include 19 | #include 20 | #include 21 | #include "Shared.h" 22 | #include "Mutex.h" 23 | #include "RecMutex.h" 24 | #include "Cond.h" 25 | #include "Monitor.h" 26 | #include "TbThread.h" 27 | #include "EventHandler.h" 28 | 29 | #define DEFAUTL_STACK_SIZE 4*1024*1024 //16M 30 | #define DEFALUT_LIST_SIZE_MAX 40960 31 | 32 | namespace tbutil 33 | { 34 | /** 35 | * @brief ThreadPool 是一个线程池类,它实现一个领导者/跟随者模型 36 | */ 37 | class ThreadPool : public Monitor 38 | { 39 | public: 40 | 41 | ThreadPool(int size = 1, int sizeMax = 1, int sizeWarn = 1, 42 | int listSizeMax = DEFALUT_LIST_SIZE_MAX, 43 | int stackSize = DEFAUTL_STACK_SIZE); 44 | virtual ~ThreadPool(); 45 | 46 | void destroy(); 47 | 48 | /** 49 | * @brief 增加一个任务 50 | * 51 | * @param workItem: 新增加的任务 52 | * 53 | * @return 54 | */ 55 | int execute(ThreadPoolWorkItem *workItem); 56 | /** 57 | * @brief 选择新的领导者 58 | * 59 | * @param thid 60 | */ 61 | inline void promoteFollower(pthread_t thid); 62 | 63 | /** 64 | * @brief 等待所有线程退出 65 | */ 66 | void joinWithAllThreads(); 67 | 68 | /** 69 | * @brief 是否达到线程队列的最大限制 70 | * 71 | * @return 72 | */ 73 | bool isMaxCapacity() const; 74 | 75 | private: 76 | 77 | bool run(pthread_t thid); // Returns true if a follower should be promoted. 78 | 79 | bool _destroyed; 80 | 81 | std::list _workItems; 82 | int _listSize; 83 | int _procSize; 84 | const int _listSizeMax; 85 | Monitor _monitor; 86 | class EventHandlerThread : public tbutil::Thread 87 | { 88 | public: 89 | 90 | EventHandlerThread(const ThreadPool *); 91 | virtual void run(); 92 | 93 | private: 94 | 95 | ThreadPool *_pool; 96 | }; 97 | friend class EventHandlerThread; 98 | 99 | const int _size; // Number of threads that are pre-created. 100 | const int _sizeMax; // Maximum number of threads. 101 | const int _sizeWarn; // If _inUse reaches _sizeWarn, a "low on threads" warning will be printed. 102 | const size_t _stackSize; 103 | 104 | std::vector _threads; // All threads, running or not. 105 | int _running; // Number of running threads. 106 | int _inUse; // Number of threads that are currently in use. 107 | double _load; // Current load in number of threads. 108 | 109 | bool _promote; 110 | volatile int _waitingNumber; 111 | }; 112 | } 113 | #endif 114 | -------------------------------------------------------------------------------- /tbsys/Time.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include 17 | #include 18 | #include "Time.h" 19 | #include "Exception.h" 20 | 21 | namespace tbutil 22 | { 23 | Time::Time() : 24 | _usec(0) 25 | { 26 | } 27 | 28 | Time Time::now(Clock clock) 29 | { 30 | if (clock == Realtime) 31 | { 32 | struct timeval tv; 33 | if (gettimeofday(&tv, 0) < 0) 34 | { 35 | #ifdef _NO_EXCEPTION 36 | TBSYS_LOG(ERROR, "%s", "SyscallException"); 37 | assert(0); 38 | #else 39 | throw SyscallException(__FILE__, __LINE__, errno); 40 | #endif 41 | } 42 | return Time(tv.tv_sec * T_INT64(1000000) + tv.tv_usec); 43 | } 44 | else // Monotonic 45 | { 46 | struct timespec ts; 47 | /// 系统启动以来流逝的时间 48 | if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) 49 | { 50 | #ifdef _NO_EXCEPTION 51 | TBSYS_LOG(ERROR, "%s", "SyscallException"); 52 | assert(0); 53 | #else 54 | throw SyscallException(__FILE__, __LINE__, errno); 55 | #endif 56 | } 57 | return Time(ts.tv_sec * T_INT64(1000000) + ts.tv_nsec / T_INT64(1000)); 58 | } 59 | } 60 | 61 | Time Time::seconds(Int64 t) 62 | { 63 | return Time(t * T_INT64(1000000)); 64 | } 65 | 66 | Time Time::milliSeconds(Int64 t) 67 | { 68 | return Time(t * T_INT64(1000)); 69 | } 70 | 71 | Time Time::microSeconds(Int64 t) 72 | { 73 | return Time(t); 74 | } 75 | 76 | Time::operator timeval() const 77 | { 78 | timeval tv; 79 | tv.tv_sec = static_cast(_usec / 1000000); 80 | tv.tv_usec = static_cast(_usec % 1000000); 81 | return tv; 82 | } 83 | 84 | Int64 Time::toSeconds() const 85 | { 86 | return _usec / 1000000; 87 | } 88 | 89 | Int64 Time::toMilliSeconds() const 90 | { 91 | return _usec / 1000; 92 | } 93 | 94 | Int64 Time::toMicroSeconds() const 95 | { 96 | return _usec; 97 | } 98 | 99 | double Time::toSecondsDouble() const 100 | { 101 | return _usec / 1000000.0; 102 | } 103 | 104 | double Time::toMilliSecondsDouble() const 105 | { 106 | return _usec / 1000.0; 107 | } 108 | 109 | double Time::toMicroSecondsDouble() const 110 | { 111 | return static_cast(_usec); 112 | } 113 | 114 | std::string Time::toDateTime() const 115 | { 116 | time_t time = static_cast(_usec / 1000000); 117 | 118 | struct tm *t; 119 | struct tm tr; 120 | localtime_r(&time, &tr); 121 | t = &tr; 122 | 123 | char buf[32]; 124 | strftime(buf, sizeof(buf), "%F %H:%M:%S", t); 125 | //strftime(buf, sizeof(buf), "%x %H:%M:%S", t); 126 | 127 | std::ostringstream os; 128 | os << buf << "."; 129 | os.fill('0'); 130 | os.width(3); 131 | /// ms 部分 132 | os << static_cast(_usec % 1000000 / 1000); 133 | return os.str(); 134 | } 135 | 136 | std::string Time::toDuration() const 137 | { 138 | Int64 usecs = _usec % 1000000; 139 | Int64 secs = _usec / 1000000 % 60; 140 | Int64 mins = _usec / 1000000 / 60 % 60; 141 | Int64 hours = _usec / 1000000 / 60 / 60 % 24; 142 | Int64 days = _usec / 1000000 / 60 / 60 / 24; 143 | 144 | using namespace std; 145 | 146 | ostringstream os; 147 | if (days != 0) 148 | { 149 | os << days << "d "; 150 | } 151 | os << setfill('0') << setw(2) << hours << ":" << setw(2) << mins << ":" << setw(2) << secs; 152 | if (usecs != 0) 153 | { 154 | os << "." << setw(3) << (usecs / 1000); 155 | } 156 | 157 | return os.str(); 158 | } 159 | 160 | Time::Time(Int64 usec) : 161 | _usec(usec) 162 | { 163 | } 164 | 165 | }//end namespace tbutil 166 | -------------------------------------------------------------------------------- /tbsys/Timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYS_TIMER_H 17 | #define TBSYS_TIMER_H 18 | #include 19 | #include 20 | #include "Shared.h" 21 | #include "TbThread.h" 22 | #include "Monitor.h" 23 | #include "Time.h" 24 | namespace tbutil 25 | { 26 | class Timer; 27 | typedef Handle TimerPtr; 28 | 29 | /** 30 | * @brief TimerTask是定时器任务队列Item的基类,它是一抽象类 31 | * 它有一个runTimerTask纯虚方法,用户如果需要生成新的定时任务 32 | * 需要继承TimerTask并实现runTimerTask方法 33 | */ 34 | class TimerTask : virtual public Shared 35 | { 36 | public: 37 | 38 | virtual ~TimerTask() {} 39 | 40 | /** 41 | * @brief 纯虚函数,具体逻辑函数 42 | */ 43 | virtual void runTimerTask() = 0; 44 | }; 45 | typedef Handle TimerTaskPtr; 46 | 47 | /** 48 | * @brief Timer类是一个定时器类,内站一条线程和一个定时任务队列组成 49 | * 在将任务放入任务队列时,会对任务队列的任务按照被调度的时间先后顺序 50 | * 排序,在第一个被调度的定时任务时间到的时候,该任务就会被调度,有些定 51 | * 时任务在间隔一段时间后都会被调度一次可以调用scheduleRepeated函数, 52 | * 其它的都调用schedule 53 | */ 54 | class Timer : public virtual Shared, private virtual tbutil::Thread 55 | { 56 | public: 57 | 58 | Timer(); 59 | 60 | /** 61 | * @brief 停止定时器 62 | */ 63 | void destroy(); 64 | 65 | /** 66 | * @brief 新增加一个定时任务,此任务只会被调度一次,执行完成以后就会删除此任务 67 | * 68 | * @param task : 新增任务 69 | * @param delay: 执行任务的间隔时间 70 | * 说明: 真正执行任务的时间=新增任务当前时间 + 间隔时间 71 | * @return 72 | */ 73 | int schedule(const TimerTaskPtr &task, const Time &delay); 74 | 75 | /** 76 | * @brief 新增加一个定时任务,此任务在间隔时间到时,都会调用一次 77 | * 78 | * @param task : 新增任务 79 | * @param delay: 执行任务的间隔时间 80 | * 说明: 真正执行任务的时间=新增任务当前时间 + 间隔时间 81 | * @return 82 | */ 83 | int scheduleRepeated(const TimerTaskPtr &task, const Time &delay); 84 | 85 | /** 86 | * @brief 取消一个定时任务 87 | * 88 | * @param task: 被取消的定时任务 89 | * 90 | * @return 91 | */ 92 | bool cancel(const TimerTaskPtr &); 93 | 94 | private: 95 | 96 | struct Token 97 | { 98 | Time scheduledTime; 99 | Time delay; 100 | TimerTaskPtr task; 101 | 102 | inline Token(const Time &, const Time &, const TimerTaskPtr &); 103 | inline bool operator<(const Token &r) const; 104 | }; 105 | 106 | virtual void run(); 107 | 108 | Monitor _monitor; 109 | bool _destroyed; 110 | std::set _tokens; 111 | 112 | class TimerTaskCompare : public std::binary_function 113 | { 114 | public: 115 | 116 | bool operator()(const TimerTaskPtr &lhs, const TimerTaskPtr &rhs) const 117 | { 118 | return lhs.get() < rhs.get(); 119 | } 120 | }; 121 | std::map _tasks; 122 | Time _wakeUpTime; 123 | }; 124 | typedef Handle TimerPtr; 125 | 126 | inline 127 | Timer::Token::Token(const Time &st, const Time &d, const TimerTaskPtr &t) : 128 | scheduledTime(st), delay(d), task(t) 129 | { 130 | } 131 | 132 | inline bool 133 | Timer::Token::operator<(const Timer::Token &r) const 134 | { 135 | if (scheduledTime < r.scheduledTime) 136 | { 137 | return true; 138 | } 139 | else if (scheduledTime > r.scheduledTime) 140 | { 141 | return false; 142 | } 143 | 144 | return task.get() < r.task.get(); 145 | } 146 | 147 | } 148 | 149 | #endif 150 | 151 | -------------------------------------------------------------------------------- /tbsys/Utility.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYS_UTILITY_H_ 17 | #define TBSYS_UTILITY_H_ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | namespace tbsys 29 | { 30 | #define MAX_STR_FIELD_NUM 32 31 | #define SEC2USEC 1000000 32 | #define USEC2NSEC 1000 33 | 34 | #ifdef __cplusplus 35 | extern "C" 36 | { 37 | #endif // __cplusplus 38 | 39 | int getAbsPath(const char *pszPath, char *pszBuf, int iBufLen); 40 | int checkCreateDir(const char *pszPath); 41 | int checkCreateLink(const char *pszPath, const char *pszLink, int iRecreate); 42 | int strJoin(char *pszDst, size_t sizeDst, char **ppszField, size_t sizeField, const char *pszSep); 43 | // 不能多线程调用 44 | int getHostIP(char *pszAddr, unsigned uiAddrLen); 45 | int getExe(char *pszExe, unsigned uiExeLen); 46 | int getExeRoot(char *pszExeRoot, unsigned uiExePathLen); 47 | 48 | /** 49 | * 获取大于某个值的最小的2的n次方的整数 50 | * @param uiValue(uint32_t): 要求的值的下限 51 | * @see 52 | * @return result 53 | */ 54 | static inline uint32_t guint32p2(uint32_t uiValue) 55 | { 56 | uiValue |= (uiValue >> 1); 57 | uiValue |= (uiValue >> 2); 58 | uiValue |= (uiValue >> 4); 59 | uiValue |= (uiValue >> 8); 60 | uiValue |= (uiValue >> 16); 61 | return uiValue + 1; 62 | } 63 | 64 | /** 65 | * 把64位主机字节序整数转换成64位网络字节序整数 66 | * @param ull(uint64_t): 64位主机字节序整数 67 | * @see 68 | * @return 64位网络字节序整数 69 | */ 70 | static inline uint64_t htonll(uint64_t ull) 71 | { 72 | if (1 != htonl(1)) 73 | { 74 | uint64_t ullRet = 0; 75 | char *pSrc = (char *) &ull; 76 | char *pDst = (char *) &ullRet; 77 | pDst[0] = pSrc[7]; 78 | pDst[1] = pSrc[6]; 79 | pDst[2] = pSrc[5]; 80 | pDst[3] = pSrc[4]; 81 | pDst[4] = pSrc[3]; 82 | pDst[5] = pSrc[2]; 83 | pDst[6] = pSrc[1]; 84 | pDst[7] = pSrc[0]; 85 | return ullRet; 86 | } 87 | return ull; 88 | } 89 | 90 | /** 91 | * 把64位网络字节序整数转换成64位主机字节序整数 92 | * @param ull(uint64_t): 64位网络字节序整数 93 | * @see 94 | * @return 64位主机字节序整数 95 | */ 96 | static inline uint64_t ntohll(uint64_t ull) 97 | { 98 | if (1 != ntohl(1)) 99 | { 100 | uint64_t ullRet = 0; 101 | char *pSrc = (char *) &ull; 102 | char *pDst = (char *) &ullRet; 103 | pDst[0] = pSrc[7]; 104 | pDst[1] = pSrc[6]; 105 | pDst[2] = pSrc[5]; 106 | pDst[3] = pSrc[4]; 107 | pDst[4] = pSrc[3]; 108 | pDst[5] = pSrc[2]; 109 | pDst[6] = pSrc[1]; 110 | pDst[7] = pSrc[0]; 111 | return ullRet; 112 | } 113 | return ull; 114 | } 115 | 116 | /** 117 | * 把相对现在的一个时间片断转换成将来的绝对时间 118 | * @param pts(struct timespec *): 输出参数,将来的绝对时间 119 | * @param uiUSec(unsigned): 相对于现在的未来的微秒数 120 | * @see 121 | * @return 0(成功) 122 | * @return -1(失败) 123 | */ 124 | static inline int getFutureAbsTS(struct timespec *pts, unsigned uiUSec) 125 | { 126 | struct timeval tv; 127 | gettimeofday(&tv, NULL); 128 | tv.tv_usec += uiUSec % SEC2USEC; 129 | if (tv.tv_usec >= SEC2USEC) 130 | { 131 | pts->tv_sec = tv.tv_sec + uiUSec / SEC2USEC + 1; 132 | pts->tv_nsec = (tv.tv_usec - SEC2USEC) * 1000; 133 | } 134 | else 135 | { 136 | pts->tv_sec = tv.tv_sec + uiUSec / SEC2USEC; 137 | pts->tv_nsec = tv.tv_usec * USEC2NSEC; 138 | } 139 | return 0; 140 | } 141 | 142 | #ifdef __cplusplus 143 | } 144 | #endif // __cplusplus 145 | 146 | }//end namespace 147 | #endif // UTILITY_H_ 148 | -------------------------------------------------------------------------------- /tbsys/WarningBuffer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2012 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: WarningBuffer.cpp, 09/27/2012 05:01:00 PM xiaochu Exp $ 10 | * 11 | * Author: 12 | * xiaochu.yh 13 | * Description: 14 | * fix length string ring buffer 15 | * 16 | */ 17 | #include "WarningBuffer.h" 18 | 19 | namespace tbsys 20 | { 21 | bool WarningBuffer::is_log_on_ = false; 22 | 23 | WarningBuffer *get_tsi_warning_buffer() 24 | { 25 | static WarningBufferFactory instance; 26 | return instance.get_buffer(); 27 | } 28 | 29 | }; 30 | 31 | -------------------------------------------------------------------------------- /tbsys/config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYS_CONFIG_H 17 | #define TBSYS_CONFIG_H 18 | 19 | #include 20 | #include 21 | #include "stringutil.h" 22 | #include "tblog.h" 23 | 24 | //using namespace std; 25 | //using namespace __gnu_cxx; 26 | 27 | namespace tbsys 28 | { 29 | /** 30 | * @brief 生成string的hash值 31 | * 使用gcc内部定义的实现 32 | */ 33 | struct str_hash 34 | { 35 | size_t operator()(const std::string &str) const 36 | { 37 | return __gnu_cxx::__stl_hash_string(str.c_str()); 38 | } 39 | }; 40 | /** 41 | * @brief 字符串比较 42 | */ 43 | struct char_equal 44 | { 45 | bool operator()(const char *s1, const char *s2) const 46 | { 47 | return strcmp(s1, s2) == 0; 48 | } 49 | }; 50 | typedef __gnu_cxx::hash_map STR_STR_MAP; 51 | typedef STR_STR_MAP::iterator STR_STR_MAP_ITER; 52 | typedef __gnu_cxx::hash_map STR_MAP; 53 | typedef STR_MAP::iterator STR_MAP_ITER; 54 | 55 | #define TBSYS_CONFIG tbsys::CConfig::getCConfig() 56 | 57 | /** 58 | * @brief 解析配置文件,并将配置项以key-value的形式存储到内存中 59 | */ 60 | class CConfig 61 | { 62 | public: 63 | CConfig(); 64 | ~CConfig(); 65 | 66 | // 加载一个文件 67 | int load(const char *filename); 68 | // 取一个字符串 69 | const char *getString(const char *section, const std::string &key, const char *d = NULL); 70 | // 取一string列表 71 | std::vector getStringList(const char *section, const std::string &key); 72 | // 取一个整型 73 | int getInt(char const *section, const std::string &key, int d = 0); 74 | // 取一整型列表 75 | std::vector getIntList(const char *section, const std::string &key); 76 | // 取一section下所有的key 77 | int getSectionKey(const char *section, std::vector &keys); 78 | // 得到所有section的名字 79 | int getSectionName(std::vector §ions); 80 | // 完整的配置文件字符串 81 | std::string toString(); 82 | // 得到静态实例 83 | static CConfig &getCConfig(); 84 | 85 | private: 86 | // 两层map 87 | STR_MAP m_configMap; 88 | 89 | private: 90 | // 解析字符串 91 | int parseValue(char *str, char *key, char *val); 92 | char *isSectionName(char *str); 93 | }; 94 | } 95 | 96 | #endif 97 | -------------------------------------------------------------------------------- /tbsys/defaultrunnable.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include "tbsys.h" 17 | 18 | namespace tbsys 19 | { 20 | 21 | /** 22 | * 构造 23 | */ 24 | CDefaultRunnable::CDefaultRunnable(int threadCount) 25 | { 26 | _stop = false; 27 | _threadCount = threadCount; 28 | _thread = NULL; 29 | } 30 | /* 31 | * 析构 32 | */ 33 | CDefaultRunnable::~CDefaultRunnable() 34 | { 35 | if (_thread) 36 | { 37 | delete[] _thread; 38 | _thread = NULL; 39 | } 40 | } 41 | 42 | /** 43 | * 设置线程数 44 | */ 45 | void CDefaultRunnable::setThreadCount(int threadCount) 46 | { 47 | if (_thread != NULL) 48 | { 49 | TBSYS_LOG(ERROR, "已经在运行了不能设置线程数"); 50 | return; 51 | } 52 | _threadCount = threadCount; 53 | } 54 | 55 | // start 56 | int CDefaultRunnable::start() 57 | { 58 | if (_thread != NULL || _threadCount < 1) 59 | { 60 | TBSYS_LOG(ERROR, "start failure, _thread: %p, threadCount: %d", _thread, _threadCount); 61 | return 0; 62 | } 63 | _thread = new CThread[_threadCount]; 64 | if (NULL == _thread) 65 | { 66 | TBSYS_LOG(ERROR, "create _thread object failed, threadCount: %d", _threadCount); 67 | return 0; 68 | } 69 | int i = 0; 70 | for (; i < _threadCount; i++) 71 | { 72 | if (!_thread[i].start(this, (void *) ((long) i))) 73 | { 74 | return i; 75 | } 76 | } 77 | return i; 78 | } 79 | 80 | // stop 81 | void CDefaultRunnable::stop() 82 | { 83 | _stop = true; 84 | } 85 | 86 | // wait 87 | void CDefaultRunnable::wait() 88 | { 89 | if (_thread != NULL) 90 | { 91 | for (int i = 0; i < _threadCount; i++) 92 | { 93 | _thread[i].join(); 94 | } 95 | } 96 | } 97 | 98 | } 99 | 100 | ////////END 101 | -------------------------------------------------------------------------------- /tbsys/defaultrunnable.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYS_DEFAULT_RUNNABLE_H_ 17 | #define TBSYS_DEFAULT_RUNNABLE_H_ 18 | 19 | namespace tbsys 20 | { 21 | 22 | /** 23 | * @brief 线程执行具体的业务的封装类,同时它维护了一个线程数据,也可以将此类 24 | * 看成一个线程池类 25 | */ 26 | class CDefaultRunnable : public Runnable 27 | { 28 | 29 | public: 30 | /** 31 | * 构造 32 | */ 33 | CDefaultRunnable(int threadCount = 1); 34 | 35 | /** 36 | * 析构 37 | */ 38 | virtual ~CDefaultRunnable(); 39 | 40 | /** 41 | * 设置线程数 42 | */ 43 | void setThreadCount(int threadCount); 44 | 45 | /** 46 | * create %_threadCount threads 47 | * @return started thread count; 48 | */ 49 | int start(); 50 | 51 | /** 52 | * stop 53 | */ 54 | void stop(); 55 | 56 | /** 57 | * wait 58 | */ 59 | void wait(); 60 | 61 | protected: 62 | CThread *_thread; 63 | int _threadCount; 64 | bool _stop; 65 | }; 66 | 67 | } 68 | 69 | #endif /*RUNNABLE_H_*/ 70 | -------------------------------------------------------------------------------- /tbsys/filequeue.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYS_FILE_QUEUE_H 17 | #define TBSYS_FILE_QUEUE_H 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include "tblog.h" 25 | #include "threadmutex.h" 26 | #include "fileutil.h" 27 | 28 | namespace tbsys 29 | { 30 | 31 | #define TBFQ_MAX_FILE_SIZE (1024*1024*16) //16M 32 | #define TBFQ_MAX_THREAD_COUNT 60 33 | #define TBFQ_FILE_QUEUE_FLAG 0x31765166 // fQv1 34 | 35 | /** 36 | * @brief 队列正在处理的位置 37 | */ 38 | typedef struct unsettle 39 | { 40 | uint32_t seqno; 41 | int offset; 42 | } unsettle; 43 | 44 | /** 45 | * @brief 队列节点 46 | */ 47 | typedef struct queue_item 48 | { 49 | unsettle pos; 50 | int flag; 51 | int len; 52 | char data[0]; 53 | } queue_item; 54 | 55 | /** 56 | * @brief 队列相关信息 57 | */ 58 | typedef struct qinfo_head 59 | { 60 | uint32_t read_seqno; // 读文件的seqno 61 | int read_offset; // 读文件的offset 62 | uint32_t write_seqno; // 写文件的seqno 63 | int write_filesize; // 写文件的大小 64 | int queue_size; // 队列长度 65 | int exit_status; // 退出状态 66 | int reserve[2]; 67 | unsettle pos[TBFQ_MAX_THREAD_COUNT]; // 正在处理的位置 68 | } qinfo_head; 69 | 70 | class CFileUtil; 71 | /** 72 | * @brief 将数据写入文件中,在文件中数据是按队列的方法存储 73 | * 并提供操作队列的方法,操作文件 74 | */ 75 | class CFileQueue 76 | { 77 | public: 78 | CFileQueue(char *rootPath, char *queueName, int maxFileSize = TBFQ_MAX_FILE_SIZE); 79 | ~CFileQueue(void); 80 | // 写入一数据 81 | int push(void *data, int len); 82 | // 取出一数据 83 | queue_item *pop(uint32_t index = 0); 84 | // 删除一数据 85 | int clear(); 86 | // 是否空了 87 | int isEmpty(); 88 | // 己处理完了 89 | void finish(uint32_t index = 0); 90 | void backup(uint32_t index = 0); 91 | 92 | private: 93 | // 数据文件句柄(读) 94 | int m_readFd; 95 | // 数据文件句柄(写) 96 | int m_writeFd; 97 | // 头文件句柄 98 | int m_infoFd; 99 | // queue的头信息 100 | qinfo_head m_head; 101 | // 保存的路径 102 | char *m_queuePath; 103 | // 最大文件多大就新写一个文件 104 | int m_maxFileSize; 105 | 106 | private: 107 | // 打开数据文件写 108 | inline int openWriteFile(); 109 | // 打开数据文件读 110 | inline int openReadFile(); 111 | //删除处理完的文件 112 | inline int deleteReadFile(); 113 | // 写header 114 | inline int writeHead(); 115 | // 恢复数据 116 | void recoverRecord(); 117 | }; 118 | } 119 | 120 | #endif 121 | 122 | //////////////////END 123 | -------------------------------------------------------------------------------- /tbsys/filequeuethread.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include "tbsys.h" 17 | 18 | namespace tbsys 19 | { 20 | 21 | /* 构造函数 */ 22 | CFileQueueThread::CFileQueueThread(CFileQueue *queue, int threadCount, IQueueHandler *handler, void *args) : 23 | CDefaultRunnable(threadCount) 24 | { 25 | assert(queue != NULL); 26 | _queue = queue; 27 | _handler = handler; 28 | _args = args; 29 | } 30 | 31 | /* 析构函数 */ 32 | CFileQueueThread::~CFileQueueThread(void) 33 | { 34 | stop(); 35 | } 36 | 37 | /* 写入数据 */ 38 | int CFileQueueThread::writeData(void *data, int len) 39 | { 40 | if (data == NULL || len <= 0) 41 | { 42 | return EXIT_FAILURE; 43 | } 44 | _mutex.lock(); 45 | _queue->push(data, len); 46 | _mutex.signal(); 47 | _mutex.unlock(); 48 | return EXIT_SUCCESS; 49 | } 50 | 51 | /* 停止 */ 52 | void CFileQueueThread::stop() 53 | { 54 | _mutex.lock(); 55 | _stop = true; 56 | _mutex.broadcast(); 57 | _mutex.unlock(); 58 | } 59 | 60 | /* 运行入口函数 */ 61 | void CFileQueueThread::run(CThread *thread, void *args) 62 | { 63 | int threadIndex = (int) ((long) (args)); 64 | int total_count = 0; 65 | int64_t end_time = 0; 66 | int64_t start_time = CTimeUtil::getTime(); 67 | bool dosuc = true; 68 | _mutex.lock(); 69 | while (!_stop) 70 | { 71 | while (_stop == 0 && _queue->isEmpty()) 72 | { 73 | _mutex.wait(); 74 | } 75 | if (_stop) 76 | { 77 | break; 78 | } 79 | queue_item *item = _queue->pop(threadIndex); 80 | int cnt = ++total_count; 81 | if (total_count >= 1000) 82 | { 83 | total_count = 0; 84 | end_time = CTimeUtil::getTime(); 85 | } 86 | _mutex.unlock(); 87 | if (item != NULL) 88 | { 89 | if (_handler != NULL) 90 | { 91 | _handler->handleQueue(&item->data[0], item->len, threadIndex, _args); 92 | } 93 | dosuc = true; 94 | free(item); 95 | } 96 | else 97 | { 98 | dosuc = false; 99 | } 100 | if (end_time > start_time) 101 | { 102 | TBSYS_LOG(INFO, "task execute speed: %d task/s", (int) ((int64_t) 1000000 * cnt / (end_time - start_time))); 103 | start_time = end_time; 104 | } 105 | _mutex.lock(); 106 | if (dosuc) 107 | { 108 | _queue->finish(threadIndex); 109 | } 110 | } 111 | _mutex.unlock(); 112 | } 113 | } 114 | 115 | //////////////////END 116 | -------------------------------------------------------------------------------- /tbsys/filequeuethread.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYS_FILE_QUEUE_THREAD_H 17 | #define TBSYS_FILE_QUEUE_THREAD_H 18 | 19 | //using namespace std; 20 | 21 | namespace tbsys 22 | { 23 | /** 24 | * @brief File Queue 运行线程池 25 | */ 26 | class CFileQueueThread : public CDefaultRunnable 27 | { 28 | public: 29 | /** 构造函数 */ 30 | CFileQueueThread(CFileQueue *queue, int threadCount, IQueueHandler *handler, void *args); 31 | /** 析构函数 */ 32 | ~CFileQueueThread(void); 33 | /** 写入数据 */ 34 | int writeData(void *data, int len); 35 | /** 停止 */ 36 | void stop(); 37 | /** 运行入口函数 */ 38 | void run(CThread *thread, void *args); 39 | 40 | private: 41 | /** 线程锁*/ 42 | CThreadCond _mutex; 43 | /** 处理函数*/ 44 | IQueueHandler *_handler; 45 | /** 函数参数*/ 46 | void *_args; 47 | /** file queue*/ 48 | CFileQueue *_queue; 49 | }; 50 | } 51 | 52 | #endif 53 | 54 | //////////////////END 55 | -------------------------------------------------------------------------------- /tbsys/fileutil.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include "fileutil.h" 17 | 18 | namespace tbsys 19 | { 20 | /** 21 | * 创建多级目录, 在父目录不存在一同创建 22 | */ 23 | bool CFileUtil::mkdirs(char *szDirPath) 24 | { 25 | struct stat stats; 26 | if (stat(szDirPath, &stats) == 0 && S_ISDIR (stats.st_mode)) 27 | { 28 | return true; 29 | } 30 | 31 | mode_t umask_value = umask(0); 32 | umask(umask_value); 33 | mode_t mode = (S_IRWXUGO & (~umask_value)) | S_IWUSR | S_IXUSR; 34 | 35 | char *slash = szDirPath; 36 | while (*slash == '/') 37 | { 38 | slash++; 39 | } 40 | 41 | while (1) 42 | { 43 | slash = strchr(slash, '/'); 44 | if (slash == NULL) 45 | { 46 | break; 47 | } 48 | 49 | *slash = '\0'; 50 | int ret = mkdir(szDirPath, mode); 51 | *slash++ = '/'; 52 | if (ret && errno != EEXIST) 53 | { 54 | return false; 55 | } 56 | 57 | while (*slash == '/') 58 | { 59 | slash++; 60 | } 61 | } 62 | if (mkdir(szDirPath, mode)) 63 | { 64 | return false; 65 | } 66 | return true; 67 | } 68 | 69 | // 是否为目录 70 | bool CFileUtil::isDirectory(const char *szDirPath) 71 | { 72 | struct stat stats; 73 | if (lstat(szDirPath, &stats) == 0 && S_ISDIR (stats.st_mode)) 74 | { 75 | return true; 76 | } 77 | return false; 78 | } 79 | 80 | // 是否为islnk 81 | bool CFileUtil::isSymLink(const char *szDirPath) 82 | { 83 | struct stat stats; 84 | if (lstat(szDirPath, &stats) == 0 && S_ISLNK (stats.st_mode)) 85 | { 86 | return true; 87 | } 88 | return false; 89 | } 90 | } 91 | 92 | //////////////////END 93 | -------------------------------------------------------------------------------- /tbsys/fileutil.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYS_FILE_UTIL_H 17 | #define TBSYS_FILE_UTIL_H 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | namespace tbsys 26 | { 27 | 28 | #ifndef S_IRWXUGO 29 | # define S_IRWXUGO (S_IRWXU | S_IRWXG | S_IRWXO) 30 | #endif 31 | 32 | /** 33 | * @brief 对文件目录的基本操作 34 | */ 35 | class CFileUtil 36 | { 37 | public: 38 | /** 创建多级目录 */ 39 | static bool mkdirs(char *szDirPath); 40 | /** 是否为目录 */ 41 | static bool isDirectory(const char *szDirPath); 42 | /** 是否为SymLink文件 */ 43 | static bool isSymLink(const char *szDirPath); 44 | }; 45 | } 46 | 47 | #endif 48 | 49 | //////////////////END 50 | -------------------------------------------------------------------------------- /tbsys/iqueuehandler.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYS_QUEUE_HANDLER_H_ 17 | #define TBSYS_QUEUE_HANDLER_H_ 18 | 19 | namespace tbsys 20 | { 21 | 22 | class IQueueHandler 23 | { 24 | public: 25 | virtual ~IQueueHandler() {} 26 | virtual bool handleQueue(void *data, int len, int threadIndex, void *args) = 0; 27 | }; 28 | 29 | } 30 | 31 | #endif /*TBSYS_QUEUE_HANDLER_H_*/ 32 | -------------------------------------------------------------------------------- /tbsys/linklist.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef __DLINK_LIST__ 17 | #define __DLINK_LIST__ 18 | 19 | namespace tbsys 20 | { 21 | 22 | /** 23 | * @brief list 24 | */ 25 | template 26 | class LinkList 27 | { 28 | public: 29 | typedef NodeT *node_pointer_type; 30 | typedef LinkList self_type; 31 | 32 | public: 33 | LinkList(); 34 | ~LinkList(); 35 | 36 | void append(NodeT *node); 37 | void remove(NodeT *node); 38 | void combine(const LinkList &al); 39 | void reset(); 40 | 41 | NodeT *head() const { return _head; } 42 | NodeT *tail() const { return _tail; } 43 | void head(NodeT *h) { _head = h; } 44 | void tail(NodeT *t) { _tail = t; } 45 | 46 | /// 判断list是否为空只需要判断head_和tail_是否为NULL 47 | bool empty() const { return !(_head && _tail); } 48 | 49 | private: 50 | NodeT *_head; 51 | NodeT *_tail; 52 | }; 53 | 54 | template 55 | LinkList::LinkList() 56 | { 57 | reset(); 58 | } 59 | 60 | template 61 | void LinkList::reset() 62 | { 63 | _head = _tail = NULL; 64 | } 65 | 66 | template 67 | LinkList::~LinkList() 68 | { 69 | } 70 | 71 | /// append a node to the list 72 | template 73 | void LinkList::append(NodeT *node) 74 | { 75 | if (!node) 76 | { 77 | return; 78 | } 79 | 80 | node->_prev = _tail; 81 | node->_next = NULL; 82 | 83 | if (!_tail) 84 | { 85 | _head = node; 86 | } 87 | else 88 | { 89 | _tail->_next = node; 90 | } 91 | _tail = node; 92 | } 93 | 94 | /// 将node从list之中删除 95 | template 96 | void LinkList::remove(NodeT *node) 97 | { 98 | if (!node) 99 | { 100 | return; 101 | } 102 | 103 | if (node == _head) 104 | { // head 105 | _head = node->_next; 106 | } 107 | if (node == _tail) 108 | { // tail 109 | _tail = node->_prev; 110 | } 111 | 112 | if (node->_prev != NULL) 113 | { 114 | node->_prev->_next = node->_next; 115 | } 116 | if (node->_next != NULL) 117 | { 118 | node->_next->_prev = node->_prev; 119 | } 120 | 121 | } 122 | 123 | /// 将list al挂接到list的末尾 124 | template 125 | void LinkList::combine(const LinkList &al) 126 | { 127 | if (al.empty()) 128 | { 129 | return; 130 | } 131 | 132 | if (!_tail) 133 | { 134 | _head = al.head(); 135 | } 136 | else 137 | { 138 | _tail->_next = al.head(); 139 | al.head()->_prev = _tail; 140 | } 141 | _tail = al.tail(); 142 | } 143 | 144 | } 145 | 146 | #endif 147 | -------------------------------------------------------------------------------- /tbsys/process.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include "process.h" 17 | 18 | namespace tbsys 19 | { 20 | 21 | /** 22 | * 起一个守护进程, 返回守护进程ID 23 | */ 24 | int CProcess::startDaemon(const char *szPidFile, const char *szLogFile) 25 | { 26 | if (getppid() == 1) 27 | { 28 | return 0; 29 | } 30 | 31 | int pid = fork(); 32 | if (pid < 0) 33 | { 34 | exit(1); 35 | } 36 | if (pid > 0) 37 | { 38 | return pid; 39 | } 40 | 41 | writePidFile(szPidFile); 42 | 43 | int fd = open("/dev/null", 0); 44 | if (fd != -1) 45 | { 46 | dup2(fd, 0); 47 | close(fd); 48 | } 49 | 50 | TBSYS_LOGGER.setFileName(szLogFile); 51 | 52 | return pid; 53 | } 54 | 55 | /** 56 | * 写pid文件 57 | */ 58 | void CProcess::writePidFile(const char *szPidFile) 59 | { 60 | char str[32]; 61 | int lfp = open(szPidFile, O_WRONLY | O_CREAT | O_TRUNC, 0600); 62 | if (lfp < 0) 63 | { 64 | exit(1); 65 | } 66 | if (lockf(lfp, F_TLOCK, 0) < 0) 67 | { 68 | fprintf(stderr, "Can't Open Pid File: %s", szPidFile); 69 | exit(0); 70 | } 71 | sprintf(str, "%d\n", getpid()); 72 | ssize_t len = strlen(str); 73 | ssize_t ret = write(lfp, str, len); 74 | if (ret != len) 75 | { 76 | fprintf(stderr, "Can't Write Pid File: %s", szPidFile); 77 | exit(0); 78 | } 79 | close(lfp); 80 | } 81 | 82 | /** 83 | * 判断进程是否还活着 84 | * 85 | * 活着: 非0 86 | * 死掉: 0 87 | */ 88 | int CProcess::existPid(const char *szPidFile) 89 | { 90 | char buffer[64], *p; 91 | int otherpid = 0, lfp; 92 | lfp = open(szPidFile, O_RDONLY, 0); 93 | if (lfp >= 0) 94 | { 95 | read(lfp, buffer, 64); 96 | close(lfp); 97 | buffer[63] = '\0'; 98 | p = strchr(buffer, '\n'); 99 | if (p != NULL) 100 | { 101 | *p = '\0'; 102 | } 103 | otherpid = atoi(buffer); 104 | } 105 | if (otherpid > 0) 106 | { 107 | if (kill(otherpid, 0) != 0) 108 | { 109 | otherpid = 0; 110 | } 111 | } 112 | return otherpid; 113 | } 114 | } 115 | 116 | /*END*/ 117 | 118 | -------------------------------------------------------------------------------- /tbsys/process.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYS_PROCESS_H 17 | #define TBSYS_PROCESS_H 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include "tblog.h" 28 | 29 | namespace tbsys 30 | { 31 | 32 | /** 33 | * @brief 进程以daemon方法启动时简单封装 34 | */ 35 | class CProcess 36 | { 37 | 38 | public: 39 | // 起一个daemon 40 | static int startDaemon(const char *szPidFile, const char *szLogFile); 41 | // 进程是不是存在 42 | static int existPid(const char *szPidFile); 43 | // 写PID文件 44 | static void writePidFile(const char *szPidFile); 45 | }; 46 | } 47 | #endif 48 | 49 | /*END*/ 50 | -------------------------------------------------------------------------------- /tbsys/profiler.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include "profiler.h" 17 | 18 | namespace tbsys 19 | { 20 | namespace util 21 | { 22 | Profiler Profiler::m_profiler; 23 | 24 | Profiler::Profiler() 25 | { 26 | threshold = 10000; // 10ms 27 | status = 1; // default enable 28 | } 29 | 30 | void Profiler::start(const string &description) 31 | { 32 | if (entry.get() != NULL) 33 | { 34 | reset(); 35 | } 36 | 37 | entry.set(new Entry(description, NULL, NULL)); 38 | } 39 | 40 | void Profiler::stop() 41 | { 42 | end(); 43 | } 44 | 45 | void Profiler::reset() 46 | { 47 | if (entry.get() != NULL) 48 | { 49 | delete entry.get(); 50 | entry.set(NULL); 51 | } 52 | } 53 | 54 | void Profiler::begin(const string &description) 55 | { 56 | Entry *ce = getCurrentEntry(); 57 | if (ce != NULL) 58 | { 59 | ce->doSubEntry(description); 60 | } 61 | } 62 | 63 | void Profiler::end() 64 | { 65 | Entry *ce = getCurrentEntry(); 66 | if (ce != NULL) 67 | { 68 | ce->release(); 69 | } 70 | } 71 | 72 | long Profiler::getDuration() 73 | { 74 | return entry.get()->getDuration(); 75 | } 76 | 77 | Entry *Profiler::getCurrentEntry() 78 | { 79 | Entry *se = entry.get(); 80 | Entry *e = NULL; 81 | 82 | if (se != NULL) 83 | { 84 | do 85 | { 86 | e = se; 87 | se = e->getUnreleasedEntry(); 88 | } while (se != NULL); 89 | } 90 | 91 | return e; 92 | } 93 | 94 | void Profiler::dump() 95 | { 96 | Profiler::end(); 97 | Entry *ent = entry.get(); 98 | if (ent != NULL && ent->getDuration() >= threshold && Profiler::status == 1) 99 | TBSYS_LOG(WARN, "%s", ent->toString().c_str()); 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /tbsys/queuethread.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include "tbsys.h" 17 | 18 | namespace tbsys 19 | { 20 | 21 | /* 构造函数 */ 22 | CQueueThread::CQueueThread(int threadCount, IQueueHandler *handler, void *args) 23 | : CDefaultRunnable(threadCount) 24 | { 25 | _handler = handler; 26 | _args = args; 27 | } 28 | 29 | /* 析构函数 */ 30 | CQueueThread::~CQueueThread(void) 31 | { 32 | stop(); 33 | } 34 | 35 | /* 写入数据 */ 36 | int CQueueThread::writeData(void *data, int len) 37 | { 38 | if (data == NULL || len <= 0) 39 | { 40 | return EXIT_FAILURE; 41 | } 42 | data_pair *item = new data_pair(); 43 | item->data = (char *) malloc(len); 44 | assert(item->data != NULL); 45 | memcpy(item->data, data, len); 46 | item->len = len; 47 | _mutex.lock(); 48 | _queue.push(item); 49 | _mutex.signal(); 50 | _mutex.unlock(); 51 | return EXIT_SUCCESS; 52 | } 53 | 54 | /* 停止 */ 55 | void CQueueThread::stop() 56 | { 57 | _mutex.lock(); 58 | _stop = true; 59 | _mutex.broadcast(); 60 | _mutex.unlock(); 61 | } 62 | 63 | /* 运行入口函数 */ 64 | void CQueueThread::run(CThread *thread, void *args) 65 | { 66 | int threadIndex = (int) ((long) (args)); 67 | _mutex.lock(); 68 | while (!_stop) 69 | { 70 | while (_stop == 0 && _queue.empty()) 71 | { 72 | _mutex.wait(); 73 | } 74 | if (_stop) 75 | { 76 | break; 77 | } 78 | data_pair *item = _queue.front(); 79 | _queue.pop(); 80 | _mutex.unlock(); 81 | if (item != NULL) 82 | { 83 | if (_handler) 84 | { 85 | _handler->handleQueue(item->data, item->len, threadIndex, _args); 86 | } 87 | if (item->data) 88 | { 89 | free(item->data); 90 | } 91 | free(item); 92 | } 93 | _mutex.lock(); 94 | } 95 | _mutex.unlock(); 96 | } 97 | } 98 | 99 | //////////////////END 100 | -------------------------------------------------------------------------------- /tbsys/queuethread.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYS_QUEUE_THREAD_H 17 | #define TBSYS_QUEUE_THREAD_H 18 | 19 | #include 20 | 21 | //using namespace std; 22 | 23 | namespace tbsys 24 | { 25 | 26 | /** 27 | * @brief Queue 运行线程池 28 | */ 29 | class CQueueThread : public CDefaultRunnable 30 | { 31 | public: 32 | /* 构造函数 */ 33 | CQueueThread(int threadCount, IQueueHandler *handler, void *args); 34 | /* 析构函数 */ 35 | ~CQueueThread(void); 36 | /* 写入数据 */ 37 | int writeData(void *data, int len); 38 | /* 停止 */ 39 | void stop(); 40 | /* 运行入口函数 */ 41 | void run(CThread *thread, void *args); 42 | 43 | private: 44 | typedef struct data_pair 45 | { 46 | char *data; 47 | int len; 48 | } data_pair; 49 | // queue 50 | std::queue _queue; 51 | 52 | protected: 53 | // 线程锁 54 | CThreadCond _mutex; 55 | // 处理函数 56 | IQueueHandler *_handler; 57 | // 函数参数 58 | void *_args; 59 | }; 60 | } 61 | 62 | #endif 63 | 64 | //////////////////END 65 | -------------------------------------------------------------------------------- /tbsys/runnable.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYS_RUNNABLE_H_ 17 | #define TBSYS_RUNNABLE_H_ 18 | 19 | namespace tbsys 20 | { 21 | 22 | /** 23 | * @brief Runnable是一个抽象类,它拥有一个run纯虚方法 24 | * 主要用于Thread类 25 | */ 26 | class Runnable 27 | { 28 | 29 | public: 30 | /* 31 | * 析构 32 | */ 33 | virtual ~Runnable() 34 | { 35 | } 36 | /** 37 | * 运行入口函数 38 | */ 39 | virtual void run(CThread *thread, void *arg) = 0; 40 | }; 41 | 42 | } 43 | 44 | #endif /*RUNNABLE_H_*/ 45 | -------------------------------------------------------------------------------- /tbsys/stringutil.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYS_STRINGUTIL_H 17 | #define TBSYS_STRINGUTIL_H 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | //using namespace std; 27 | 28 | namespace tbsys 29 | { 30 | 31 | /** 32 | * @brief 字符串操作,以及转换的封装 33 | */ 34 | class CStringUtil 35 | { 36 | public: 37 | // 把string转成int 38 | static int strToInt(const char *str, int d); 39 | // 是整数 40 | static int isInt(const char *str); 41 | // 转成小写 42 | static char *strToLower(char *str); 43 | // 转成大写 44 | static char *strToUpper(char *str); 45 | // trim 46 | static char *trim(char *str, const char *what = " ", int mode = 3); 47 | // hash_value 48 | static int hashCode(const char *str); 49 | // 得到一个str的hash值的素数 50 | static int getPrimeHash(const char *str); 51 | // 把string以delim分隔开,放到list中 52 | static void split(char *str, const char *delim, std::vector &list); 53 | // urldecode 54 | static char *urlDecode(const char *src, char *dest); 55 | // http://murmurhash.googlepages.com/ 56 | static unsigned int murMurHash(const void *key, int len); 57 | // 把bytes转成可读的, 如 10K 12M 等 58 | static std::string formatByteSize(double bytes); 59 | }; 60 | } 61 | 62 | #endif 63 | ///////////////////END 64 | -------------------------------------------------------------------------------- /tbsys/tblockguard.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYS_LOCK_GUARD_H_ 17 | #define TBSYS_LOCK_GUARD_H_ 18 | 19 | // simple lock guard, a RAII tool 20 | namespace tbsys 21 | { 22 | /** 23 | * @brief CLockGuard是一个模板类,它需要CThreadMutex作为它的模板参数 24 | * 构造函数调用传入参数的lock方法,析构函数调用unlock方法 25 | */ 26 | template 27 | class CLockGuard 28 | { 29 | public: 30 | /// block 标明是否采用阻塞式加锁方式 31 | CLockGuard(const T &lock, bool block = true) : _lock(lock) 32 | { 33 | _acquired = !(block ? _lock.lock() : _lock.tryLock()); 34 | } 35 | 36 | /// 析构函数,解锁 37 | ~CLockGuard() 38 | { 39 | _lock.unlock(); 40 | } 41 | 42 | bool acquired() const 43 | { 44 | return _acquired; 45 | } 46 | 47 | private: 48 | const T &_lock; 49 | /// 没有获取到锁? 50 | mutable bool _acquired; 51 | }; 52 | } 53 | #endif 54 | -------------------------------------------------------------------------------- /tbsys/tbnetutil.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYS_NETUTIL_H_ 17 | #define TBSYS_NETUTIL_H_ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | //using namespace std; 35 | 36 | namespace tbsys 37 | { 38 | /** 39 | * @brief 按ip地址大小比较 40 | */ 41 | struct ipaddr_less 42 | { 43 | bool operator()(const uint64_t a, const uint64_t b) const 44 | { 45 | uint64_t a1 = ((a & 0xFF) << 24) | ((a & 0xFF00) << 8) | ((a & 0xFF0000) >> 8) | ((a & 0xFF000000) >> 24); 46 | a1 <<= 32; 47 | a1 |= ((a >> 32) & 0xffff); 48 | uint64_t b1 = ((b & 0xFF) << 24) | ((b & 0xFF00) << 8) | ((b & 0xFF0000) >> 8) | ((b & 0xFF000000) >> 24); 49 | b1 <<= 32; 50 | b1 |= ((b >> 32) & 0xffff); 51 | return (a1 < b1); 52 | } 53 | }; 54 | 55 | /** 56 | * @brief IP地址转换类 57 | */ 58 | class CNetUtil 59 | { 60 | public: 61 | /** 62 | * 得到本机ip 63 | */ 64 | static uint32_t getLocalAddr(const char *dev_name); 65 | /** 66 | * ip是本机ip地址, true - 是, false - 不是 67 | */ 68 | static bool isLocalAddr(uint32_t ip, bool loopSkip = true); 69 | /** 70 | * 把字符串的ip转成int 71 | * 如 10.0.100.89 => 1499725834 72 | */ 73 | static uint32_t getAddr(const char *ip); 74 | /** 75 | * 把uint64转成字符串 76 | */ 77 | static std::string addrToString(uint64_t ipport); 78 | /** 79 | * 把ip,port转成uint64_t 80 | */ 81 | static uint64_t strToAddr(const char *ip, int port); 82 | /** 83 | * 把ip,port转成uint64_t 84 | */ 85 | static uint64_t ipToAddr(uint32_t ip, int port); 86 | }; 87 | 88 | } 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /tbsys/tbrwlock.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include "tbrwlock.h" 17 | 18 | using namespace tbsys; 19 | 20 | int CRLock::lock() const 21 | { 22 | return pthread_rwlock_rdlock(_rlock); 23 | } 24 | 25 | int CRLock::tryLock() const 26 | { 27 | return pthread_rwlock_tryrdlock(_rlock); 28 | } 29 | 30 | int CRLock::unlock() const 31 | { 32 | return pthread_rwlock_unlock(_rlock); 33 | } 34 | 35 | int CWLock::lock() const 36 | { 37 | return pthread_rwlock_wrlock(_wlock); 38 | } 39 | 40 | int CWLock::tryLock() const 41 | { 42 | return pthread_rwlock_trywrlock(_wlock); 43 | } 44 | 45 | int CWLock::unlock() const 46 | { 47 | return pthread_rwlock_unlock(_wlock); 48 | } 49 | 50 | ////////////////////////////////////////////////////////////////////////////////////// 51 | CRWLock::CRWLock(ELockMode lockMode) 52 | { 53 | pthread_rwlockattr_t attr; 54 | pthread_rwlockattr_init(&attr); 55 | if (lockMode == READ_PRIORITY) 56 | { 57 | pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_READER_NP); 58 | } 59 | else if (lockMode == WRITE_PRIORITY) 60 | { 61 | pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); 62 | } 63 | pthread_rwlock_init(&_rwlock, &attr); 64 | 65 | _rlock = new CRLock(&_rwlock); 66 | _wlock = new CWLock(&_rwlock); 67 | } 68 | 69 | CRWLock::~CRWLock() 70 | { 71 | pthread_rwlock_destroy(&_rwlock); 72 | delete _rlock; 73 | delete _wlock; 74 | } 75 | 76 | ////////////////////////////////////////////////////////////////////////////////////// 77 | CRWSimpleLock::CRWSimpleLock(ELockMode lockMode) 78 | { 79 | pthread_rwlockattr_t attr; 80 | pthread_rwlockattr_init(&attr); 81 | if (lockMode == READ_PRIORITY) 82 | { 83 | pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_READER_NP); 84 | } 85 | else if (lockMode == WRITE_PRIORITY) 86 | { 87 | pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); 88 | } 89 | pthread_rwlock_init(&_rwlock, &attr); 90 | } 91 | 92 | CRWSimpleLock::~CRWSimpleLock() 93 | { 94 | pthread_rwlock_destroy(&_rwlock); 95 | } 96 | 97 | int CRWSimpleLock::rdlock() 98 | { 99 | return pthread_rwlock_rdlock(&_rwlock); 100 | } 101 | 102 | int CRWSimpleLock::wrlock() 103 | { 104 | return pthread_rwlock_wrlock(&_rwlock); 105 | } 106 | 107 | int CRWSimpleLock::tryrdlock() 108 | { 109 | return pthread_rwlock_tryrdlock(&_rwlock); 110 | } 111 | 112 | int CRWSimpleLock::trywrlock() 113 | { 114 | return pthread_rwlock_trywrlock(&_rwlock); 115 | } 116 | 117 | int CRWSimpleLock::unlock() 118 | { 119 | return pthread_rwlock_unlock(&_rwlock); 120 | } 121 | -------------------------------------------------------------------------------- /tbsys/tbrwlock.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYS_RW_LOCK_H 17 | #define TBSYS_RW_LOCK_H 18 | 19 | #include 20 | #include "tblockguard.h" 21 | 22 | namespace tbsys 23 | { 24 | enum ELockMode 25 | { 26 | NO_PRIORITY, 27 | WRITE_PRIORITY, 28 | READ_PRIORITY 29 | }; 30 | 31 | /** 32 | * @brief linux线程 读写锁中的读锁的封装 33 | */ 34 | class CRLock 35 | { 36 | public: 37 | CRLock(pthread_rwlock_t *lock) : _rlock(lock) {} 38 | ~CRLock() {} 39 | 40 | /** 41 | * @brief 加锁 42 | * 43 | * @return 44 | */ 45 | int lock() const; 46 | /** 47 | * @brief 尝试加锁 48 | * 49 | * @return 50 | */ 51 | int tryLock() const; 52 | /** 53 | * @brief 解锁 54 | * 55 | * @return 56 | */ 57 | int unlock() const; 58 | 59 | private: 60 | mutable pthread_rwlock_t *_rlock; 61 | }; 62 | 63 | /** 64 | * @brief linux 线程读写锁中的写锁的封装 65 | */ 66 | class CWLock 67 | { 68 | public: 69 | CWLock(pthread_rwlock_t *lock) : _wlock(lock) {} 70 | ~CWLock() {} 71 | 72 | int lock() const; 73 | int tryLock() const; 74 | int unlock() const; 75 | 76 | private: 77 | mutable pthread_rwlock_t *_wlock; 78 | }; 79 | 80 | class CRWLock 81 | { 82 | public: 83 | CRWLock(ELockMode lockMode = NO_PRIORITY); 84 | ~CRWLock(); 85 | 86 | CRLock *rlock() const { return _rlock; } 87 | CWLock *wlock() const { return _wlock; } 88 | 89 | private: 90 | CRLock *_rlock; 91 | CWLock *_wlock; 92 | pthread_rwlock_t _rwlock; 93 | }; 94 | 95 | /** 96 | * @brief 对linux线程锁中的读写锁封装 97 | */ 98 | class CRWSimpleLock 99 | { 100 | public: 101 | CRWSimpleLock(ELockMode lockMode = NO_PRIORITY); 102 | ~CRWSimpleLock(); 103 | 104 | int rdlock(); 105 | int wrlock(); 106 | int tryrdlock(); 107 | int trywrlock(); 108 | int unlock(); 109 | 110 | private: 111 | pthread_rwlock_t _rwlock; 112 | }; 113 | 114 | /** 115 | * @brief linux 线程锁中读锁的助手类 116 | */ 117 | class CRLockGuard 118 | { 119 | public: 120 | CRLockGuard(const CRWLock &rwlock, bool block = true) : _guard((*rwlock.rlock()), block) {} 121 | ~CRLockGuard() {} 122 | 123 | bool acquired() 124 | { 125 | return _guard.acquired(); 126 | } 127 | 128 | private: 129 | CLockGuard _guard; 130 | }; 131 | 132 | /** 133 | * @brief linux 线程锁中写锁的助手类 134 | */ 135 | class CWLockGuard 136 | { 137 | public: 138 | CWLockGuard(const CRWLock &rwlock, bool block = true) : _guard((*rwlock.wlock()), block) {} 139 | ~CWLockGuard() {} 140 | 141 | bool acquired() 142 | { 143 | return _guard.acquired(); 144 | } 145 | 146 | private: 147 | CLockGuard _guard; 148 | }; 149 | } 150 | 151 | #endif 152 | -------------------------------------------------------------------------------- /tbsys/tbsys.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYS_H 17 | #define TBSYS_H 18 | 19 | #include 20 | #include 21 | 22 | //add by duanbing 2009-06-24-11:06 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #ifndef UNUSED 31 | #define UNUSED(v) ((void)(v)) 32 | #endif 33 | 34 | namespace tbsys 35 | { 36 | class CConfig; 37 | class CFileUtil; 38 | class CStringUtil; 39 | class CNetUtil; 40 | class CTimeUtil; 41 | class CProcess; 42 | class CLogger; 43 | class CThread; 44 | class CThreadMutex; 45 | class CThreadCond; 46 | class Runnable; 47 | class CDefaultRunnable; 48 | class CFileQueue; 49 | class IQueueHandler; 50 | class CQueueThread; 51 | class CFileQueueThread; 52 | class WarningBuffer; 53 | };//end namespace tbsys 54 | 55 | //add by duanbing 2009-06-24-11:06 56 | namespace tbutil 57 | { 58 | class noncopyable 59 | { 60 | protected: 61 | 62 | noncopyable() {} 63 | ~noncopyable() {} 64 | private: 65 | 66 | noncopyable(const noncopyable &); 67 | const noncopyable &operator=(const noncopyable &); 68 | }; 69 | 70 | #if defined(__BCPLUSPLUS__) || defined(_MSC_VER) 71 | typedef __int64 Int64; 72 | #define T_INT64(n) n##i64 73 | #elif defined(TNET_64) 74 | typedef long Int64; 75 | #define T_INT64(n) n##L 76 | #else 77 | typedef long long Int64; 78 | #define T_INT64(n) n##LL 79 | #endif 80 | 81 | typedef unsigned char Byte; 82 | typedef short Short; 83 | typedef int Int; 84 | typedef Int64 Long; 85 | typedef float Float; 86 | typedef double Double; 87 | 88 | typedef ::std::vector BoolSeq; 89 | 90 | typedef ::std::vector ByteSeq; 91 | 92 | typedef ::std::vector ShortSeq; 93 | 94 | typedef ::std::vector IntSeq; 95 | 96 | typedef ::std::vector LongSeq; 97 | 98 | typedef ::std::vector FloatSeq; 99 | 100 | typedef ::std::vector DoubleSeq; 101 | 102 | typedef ::std::vector<::std::string> StringSeq; 103 | 104 | inline int getSystemErrno() 105 | { 106 | return errno; 107 | } 108 | }//end namespace tbutil 109 | 110 | /// 引入定义的头文件 111 | #include "atomic.h" 112 | #include "config.h" 113 | #include "fileutil.h" 114 | #include "stringutil.h" 115 | #include "tbnetutil.h" 116 | #include "tbtimeutil.h" 117 | #include "process.h" 118 | #include "tblog.h" 119 | #include "WarningBuffer.h" 120 | #include "tbrwlock.h" 121 | 122 | #include "runnable.h" 123 | #include "iqueuehandler.h" 124 | #include "defaultrunnable.h" 125 | #include "thread.h" 126 | #include "threadmutex.h" 127 | #include "threadcond.h" 128 | 129 | #include "queuethread.h" 130 | #include "filequeue.h" 131 | #include "filequeuethread.h" 132 | #include "profiler.h" 133 | #include "bytebuffer.h" 134 | 135 | #endif 136 | 137 | -------------------------------------------------------------------------------- /tbsys/tbtimeutil.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #include "tbtimeutil.h" 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | namespace tbsys 24 | { 25 | 26 | /* 27 | * 得到当前时间 28 | */ 29 | int64_t CTimeUtil::getTime() 30 | { 31 | struct timeval t; 32 | gettimeofday(&t, NULL); 33 | return (static_cast(t.tv_sec) * static_cast(1000000) + static_cast(t.tv_usec)); 34 | } 35 | 36 | int64_t CTimeUtil::getMonotonicTime() 37 | { 38 | timespec t; 39 | clock_gettime(CLOCK_MONOTONIC, &t); 40 | return (static_cast(t.tv_sec) * static_cast(1000000) + static_cast(t.tv_nsec / 1000)); 41 | } 42 | 43 | /** 44 | * 把int转成20080101101010的格式 45 | */ 46 | char *CTimeUtil::timeToStr(time_t t, char *dest) 47 | { 48 | struct tm r; 49 | memset(&r, 0, sizeof(r)); 50 | if (localtime_r((const time_t *) &t, &r) == NULL) 51 | { 52 | fprintf(stderr, "TIME: %s (%d)\n", strerror(errno), errno); 53 | dest[0] = '\0'; 54 | return dest; 55 | } 56 | sprintf(dest, "%04d%02d%02d%02d%02d%02d", 57 | r.tm_year + 1900, r.tm_mon + 1, r.tm_mday, 58 | r.tm_hour, r.tm_min, r.tm_sec); 59 | return dest; 60 | } 61 | 62 | /** 63 | * 把字节串转成时间(当地时间) 64 | */ 65 | int CTimeUtil::strToTime(char *str) 66 | { 67 | if (str == NULL || strlen(str) != 14) 68 | { 69 | return 0; 70 | } 71 | char *p = str; 72 | while ((*p)) 73 | { 74 | if ((*p) < '0' || (*p) > '9') 75 | { 76 | return 0; 77 | } 78 | p++; 79 | } 80 | 81 | struct tm t; 82 | t.tm_year = (str[0] - '0') * 1000 + (str[1] - '0') * 100 + (str[2] - '0') * 10 + (str[3] - '0') - 1900; 83 | t.tm_mon = (str[4] - '0') * 10 + (str[5] - '0') - 1; 84 | t.tm_mday = (str[6] - '0') * 10 + (str[7] - '0'); 85 | t.tm_hour = (str[8] - '0') * 10 + (str[9] - '0'); 86 | t.tm_min = (str[10] - '0') * 10 + (str[11] - '0'); 87 | t.tm_sec = (str[12] - '0') * 10 + (str[13] - '0'); 88 | t.tm_isdst = 0; 89 | int t1 = mktime(&t); 90 | return t1; 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /tbsys/tbtimeutil.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYS_TIMEUTIL_H_ 17 | #define TBSYS_TIMEUTIL_H_ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | namespace tbsys 26 | { 27 | 28 | /** 29 | * @brief linux时间操作简单的封装 30 | */ 31 | class CTimeUtil 32 | { 33 | public: 34 | /** 35 | * 得到当前时间 36 | */ 37 | static int64_t getTime(); 38 | /** 39 | * 得到单调递增的时间 40 | */ 41 | static int64_t getMonotonicTime(); 42 | /** 43 | * 把int转成20080101101010的格式 44 | */ 45 | static char *timeToStr(time_t t, char *dest); 46 | /** 47 | * 把字节串转成时间(当地时间) 48 | */ 49 | static int strToTime(char *str); 50 | }; 51 | 52 | } 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /tbsys/thread.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYS_THREAD_H_ 17 | #define TBSYS_THREAD_H_ 18 | 19 | #include 20 | 21 | namespace tbsys 22 | { 23 | 24 | /** 25 | * @brief 对linux线程简单封装 26 | */ 27 | class CThread 28 | { 29 | 30 | public: 31 | /** 32 | * 构造函数 33 | */ 34 | CThread() 35 | { 36 | tid = 0; 37 | pid = 0; 38 | } 39 | 40 | /** 41 | * 起一个线程,开始运行 42 | */ 43 | bool start(Runnable *r, void *a) 44 | { 45 | runnable = r; 46 | args = a; 47 | return 0 == pthread_create(&tid, NULL, CThread::hook, this); 48 | } 49 | 50 | /** 51 | * 等待线程退出 52 | */ 53 | void join() 54 | { 55 | if (tid) 56 | { 57 | pthread_join(tid, NULL); 58 | tid = 0; 59 | pid = 0; 60 | } 61 | } 62 | 63 | /** 64 | * 得到Runnable对象 65 | * 66 | * @return Runnable 67 | */ 68 | Runnable *getRunnable() 69 | { 70 | return runnable; 71 | } 72 | 73 | /** 74 | * 得到回调参数 75 | * 76 | * @return args 77 | */ 78 | void *getArgs() 79 | { 80 | return args; 81 | } 82 | 83 | /*** 84 | * 得到线程的进程ID 85 | */ 86 | int getpid() 87 | { 88 | return pid; 89 | } 90 | 91 | /** 92 | * 线程的回调函数 93 | * 94 | */ 95 | 96 | static void *hook(void *arg) 97 | { 98 | CThread *thread = (CThread *) arg; 99 | thread->pid = gettid(); 100 | 101 | if (thread->getRunnable()) 102 | { 103 | thread->getRunnable()->run(thread, thread->getArgs()); 104 | } 105 | 106 | return (void *) NULL; 107 | } 108 | 109 | private: 110 | /** 111 | * 得到tid号 112 | */ 113 | #ifdef _syscall0 114 | static _syscall0(pid_t,gettid) 115 | #else 116 | static pid_t gettid() { return static_cast(syscall(__NR_gettid)); } 117 | #endif 118 | 119 | private: 120 | pthread_t tid; // pthread_self() id 121 | int pid; // 线程的进程ID 122 | Runnable *runnable; 123 | void *args; 124 | }; 125 | 126 | } 127 | 128 | #endif /*THREAD_H_*/ 129 | -------------------------------------------------------------------------------- /tbsys/threadcond.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYS_COND_H_ 17 | #define TBSYS_COND_H_ 18 | 19 | namespace tbsys 20 | { 21 | 22 | /** 23 | * @brief Linux线程条件变量 24 | */ 25 | class CThreadCond : public CThreadMutex 26 | { 27 | 28 | public: 29 | 30 | /** 31 | * 构造函数 32 | */ 33 | CThreadCond() 34 | { 35 | pthread_cond_init(&_cond, NULL); 36 | } 37 | 38 | /** 39 | * 析造函数 40 | */ 41 | ~CThreadCond() 42 | { 43 | pthread_cond_destroy(&_cond); 44 | } 45 | 46 | /** 47 | * 等待信号 48 | * 49 | * @param milliseconds 等待超时间(单位:ms), 0 = 永久等待, 50 | */ 51 | bool wait(int milliseconds = 0) 52 | { 53 | bool ret = true; 54 | 55 | if (milliseconds == 0) 56 | { // 永久等待 57 | pthread_cond_wait(&_cond, &_mutex); 58 | } 59 | else 60 | { 61 | 62 | struct timeval curtime; 63 | 64 | struct timespec abstime; 65 | gettimeofday(&curtime, NULL); 66 | 67 | int64_t us = (static_cast(curtime.tv_sec) * 68 | static_cast(1000000) + 69 | static_cast(curtime.tv_usec) + 70 | static_cast(milliseconds) * 71 | static_cast(1000)); 72 | 73 | abstime.tv_sec = static_cast(us / static_cast(1000000)); 74 | abstime.tv_nsec = static_cast(us % static_cast(1000000)) * 1000; 75 | ret = (pthread_cond_timedwait(&_cond, &_mutex, &abstime) == 0); 76 | } 77 | 78 | return ret; 79 | } 80 | 81 | /** 82 | * 唤醒一个 83 | */ 84 | void signal() 85 | { 86 | pthread_cond_signal(&_cond); 87 | } 88 | 89 | /** 90 | * 唤醒所有 91 | */ 92 | void broadcast() 93 | { 94 | pthread_cond_broadcast(&_cond); 95 | } 96 | 97 | private: 98 | pthread_cond_t _cond; 99 | }; 100 | 101 | } 102 | 103 | #endif /*COND_H_*/ 104 | -------------------------------------------------------------------------------- /tbsys/threadmutex.h: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) 2007-2010 Taobao Inc. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | * 8 | * 9 | * Version: $Id$ 10 | * 11 | * Authors: 12 | * duolong 13 | * 14 | */ 15 | 16 | #ifndef TBSYS_MUTEX_H_ 17 | #define TBSYS_MUTEX_H_ 18 | 19 | #include 20 | 21 | namespace tbsys 22 | { 23 | 24 | /* 25 | * author cjxrobot 26 | * 27 | * Linux线程锁 28 | */ 29 | 30 | /** 31 | * @brief linux线程锁互斥锁简单封装 32 | */ 33 | class CThreadMutex 34 | { 35 | 36 | public: 37 | /* 38 | * 构造函数 39 | */ 40 | CThreadMutex() 41 | { 42 | //assert(pthread_mutex_init(&_mutex, NULL) == 0); 43 | const int iRet = pthread_mutex_init(&_mutex, NULL); 44 | (void) iRet; 45 | assert(iRet == 0); 46 | } 47 | 48 | /* 49 | * 析造函数 50 | */ 51 | ~CThreadMutex() 52 | { 53 | pthread_mutex_destroy(&_mutex); 54 | } 55 | 56 | /** 57 | * 加锁 58 | */ 59 | 60 | void lock() 61 | { 62 | pthread_mutex_lock(&_mutex); 63 | } 64 | 65 | /** 66 | * trylock加锁 67 | */ 68 | 69 | int trylock() 70 | { 71 | return pthread_mutex_trylock(&_mutex); 72 | } 73 | 74 | /** 75 | * 解锁 76 | */ 77 | void unlock() 78 | { 79 | pthread_mutex_unlock(&_mutex); 80 | } 81 | 82 | protected: 83 | 84 | pthread_mutex_t _mutex; 85 | }; 86 | 87 | /** 88 | * @brief 线程的Guard 89 | */ 90 | class CThreadGuard 91 | { 92 | public: 93 | CThreadGuard(CThreadMutex *mutex) 94 | { 95 | _mutex = NULL; 96 | if (mutex) 97 | { 98 | _mutex = mutex; 99 | _mutex->lock(); 100 | } 101 | } 102 | ~CThreadGuard() 103 | { 104 | if (_mutex) 105 | { 106 | _mutex->unlock(); 107 | } 108 | } 109 | private: 110 | CThreadMutex *_mutex; 111 | }; 112 | 113 | } 114 | 115 | #endif /*MUTEX_H_*/ 116 | --------------------------------------------------------------------------------