└── trunk ├── build.sh ├── rpm ├── scm.xml ├── t-csrd-tbnet-devel-VER.txt ├── t-csrd-tbnet-devel-build.sh └── t-csrd-tbnet-devel.spec ├── tbnet ├── AUTHORS ├── COPYING ├── ChangeLog ├── Makefile.am ├── NEWS ├── README ├── autogen.sh ├── configure.ac ├── src │ ├── Makefile.am │ ├── 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 │ ├── test │ │ ├── Makefile.am │ │ ├── dotest.cpp │ │ ├── epollsocketeventtf.cpp │ │ ├── epollsocketeventtf.h │ │ ├── packetqueuetf.cpp │ │ ├── packetqueuetf.h │ │ ├── sockettf.cpp │ │ └── sockettf.h │ ├── transport.cpp │ ├── transport.h │ ├── udpacceptor.h │ ├── udpcomponent.cpp │ ├── udpcomponent.h │ ├── udpconnection.cpp │ └── udpconnection.h └── test │ ├── Makefile.am │ ├── echoclient.cpp │ ├── echoserver.cpp │ └── httpserver.cpp └── tbsys ├── AUTHORS ├── ChangeLog ├── Makefile.am ├── NEWS ├── README ├── autogen.sh ├── configure.ac ├── src ├── Cond.cpp ├── Cond.h ├── CtrlCHandler.cpp ├── CtrlCHandler.h ├── EventHandler.h ├── Exception.cpp ├── Exception.h ├── Functional.h ├── Handle.h ├── Lock.h ├── Makefile.am ├── 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 └── test ├── Makefile.am ├── 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 /trunk/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -z $TBLIB_ROOT ]; then 4 | echo "TBLIB_ROOT has not set" 5 | exit; 6 | fi 7 | 8 | REAL_FILE=`readlink -f $0` 9 | cd `dirname $REAL_FILE` 10 | BASE_HOME="`pwd`" 11 | 12 | cd $BASE_HOME/tbsys 13 | if [ -z "$1" -o "$1" = 'make' ]; then 14 | sh autogen.sh 15 | CXXFLAGS='-O3 -Wall -D_NO_EXCEPTION' ./configure 16 | make -j 8 17 | fi 18 | if [ -z "$1" -o "$1" = 'make' -o "$1" = 'install' ]; then 19 | make install 20 | fi 21 | 22 | if [ "$1" = 'clean' ]; then 23 | make clean distclean 24 | sh autogen.sh clean 25 | fi 26 | 27 | cd $BASE_HOME/tbnet 28 | if [ -z "$1" -o "$1" = 'make' ]; then 29 | sh autogen.sh 30 | ./configure 31 | make -j 8 32 | fi 33 | if [ -z "$1" -o "$1" = 'install' ]; then 34 | make install 35 | fi 36 | if [ "$1" = 'clean' ]; then 37 | make clean distclean 38 | sh autogen.sh clean 39 | fi 40 | 41 | echo "have installed in $TBLIB_ROOT" 42 | -------------------------------------------------------------------------------- /trunk/rpm/scm.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 集团 8 | 9 |
技术共享平台
10 | 核心系统研发 11 | 存储 12 |
13 | 14 |
核心系统
15 | tair 16 |
17 | t-csrd-tbnet-devel 18 | C/C++ 19 | http://svn.taobao-develop.com/repos/ttsc/branches/V3286_common_20100813/common/ 20 |
21 |
22 |
23 | 24 | -------------------------------------------------------------------------------- /trunk/rpm/t-csrd-tbnet-devel-VER.txt: -------------------------------------------------------------------------------- 1 | 1.0.10 2 | -------------------------------------------------------------------------------- /trunk/rpm/t-csrd-tbnet-devel-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##for check 3 | export temppath=$1 4 | #export TBLIB_ROOT=/opt/csr/common 5 | cd $temppath/rpm 6 | if [ `cat /etc/redhat-release|cut -d " " -f 7|cut -d "." -f 1` = 4 ] 7 | then 8 | sed -i "s/^Release:.*$/Release: "$4".el4/" $2.spec 9 | else 10 | sed -i "s/^Release:.*$/Release: "$4".el5/" $2.spec 11 | fi 12 | sed -i "s/^Version:.*$/Version: "$3"/" $2.spec 13 | 14 | /usr/local/bin/rpm_create -p /opt/csr/common -v $3 -r $4 $2.spec -k 15 | mv `find . -name $2-$3-$4*rpm` . 16 | -------------------------------------------------------------------------------- /trunk/rpm/t-csrd-tbnet-devel.spec: -------------------------------------------------------------------------------- 1 | Summary: Taobao csrd middleware of TCP/IP communication 2 | Name: t-csrd-tbnet-devel 3 | Version: %{_version} 4 | Release: %(echo $RELEASE)%{?dist} 5 | Group: Taobao 6 | URL: http:://yum.corp.alimama.com 7 | Packager: Ye Feng 8 | License: Taobao 9 | Prefix:%{_prefix} 10 | 11 | %description 12 | %{_svn_path} 13 | %{_svn_revision} 14 | 15 | %define __arch_install_post %{nil} 16 | 17 | %description 18 | This package provides the headers and shared objects of tbnet. 19 | 20 | %build 21 | cd ../../.. 22 | chmod u+x build.sh tbnet/autogen.sh tbsys/autogen.sh 23 | export TBLIB_ROOT=$RPM_BUILD_ROOT/%{_prefix} 24 | ./build.sh make 25 | 26 | %install 27 | cd ../../.. 28 | export TBLIB_ROOT=$RPM_BUILD_ROOT/%{_prefix} 29 | ./build.sh install 30 | ./build.sh clean 31 | 32 | %clean 33 | rm -rf $RPM_BUILD_ROOT 34 | 35 | %post 36 | echo %{_prefix}/lib > /etc/ld.so.conf.d/tbnet.conf 37 | /sbin/ldconfig 38 | 39 | %postun 40 | rm -f /etc/ld.so.conf.d/tbnet.conf 41 | 42 | %files 43 | %defattr(0755, root, root) 44 | %{_prefix}/include 45 | %{_prefix}/lib 46 | 47 | %changelog 48 | * Tue Nov 10 2009 yefeng 49 | - Rebuild for Red Hat Enterprise Linux AS release 5.3(Tikanga) 50 | - SVN Tag: http://svn.taobao-develop.com/repos/ttsc/trunk/common 51 | 52 | -------------------------------------------------------------------------------- /trunk/tbnet/AUTHORS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/AUTHORS -------------------------------------------------------------------------------- /trunk/tbnet/ChangeLog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/ChangeLog -------------------------------------------------------------------------------- /trunk/tbnet/Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS=src test src/test 2 | UNITTESTDIRS=src/test 3 | .PHONY: $(UNITTESTDIRS) 4 | test: $(UNITTESTDIRS) 5 | $(UNITTESTDIRS): 6 | $(MAKE) -C $@ test 7 | 8 | -------------------------------------------------------------------------------- /trunk/tbnet/NEWS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/NEWS -------------------------------------------------------------------------------- /trunk/tbnet/README: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/README -------------------------------------------------------------------------------- /trunk/tbnet/autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "$1" == "clean" ]; then 4 | rm -rf aclocal.m4 autom4te.cache config.guess config.sub configure depcomp INSTALL install-sh ltmain.sh missing 5 | find . -name 'Makefile' -exec rm -f {} \; 6 | find . -name 'Makefile.in' -exec rm -f {} \; 7 | exit; 8 | fi 9 | 10 | libtoolize --force 11 | aclocal 12 | autoconf 13 | automake --add-missing --force 14 | -------------------------------------------------------------------------------- /trunk/tbnet/configure.ac: -------------------------------------------------------------------------------- 1 | # -*- Autoconf -*- 2 | # Process this file with autoconf to produce a configure script. 3 | 4 | AC_INIT(src/transport.h) 5 | AM_INIT_AUTOMAKE(tbnet, 0.1) 6 | 7 | # Checks for programs. 8 | AC_PROG_CXX 9 | AC_PROG_CC 10 | AC_PROG_CPP 11 | AC_PROG_INSTALL 12 | AC_PROG_LN_S 13 | AC_PROG_MAKE_SET 14 | AC_PROG_LIBTOOL 15 | AC_LANG_CPLUSPLUS 16 | CXXFLAGS="-O3 -Wall -fPIC" 17 | 18 | if test -n "${TBLIB_ROOT}"; then 19 | ac_default_prefix=${TBLIB_ROOT} 20 | includedir=${ac_default_prefix}/include/tbnet 21 | fi 22 | # Checks for libraries. 23 | 24 | # Checks for header files. 25 | AC_HEADER_STDC 26 | AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h string.h strings.h sys/socket.h sys/time.h unistd.h]) 27 | 28 | # Checks for typedefs, structures, and compiler characteristics. 29 | AC_HEADER_STDBOOL 30 | AC_C_CONST 31 | AC_C_INLINE 32 | AC_TYPE_SIZE_T 33 | AC_HEADER_TIME 34 | AC_STRUCT_TM 35 | AC_C_VOLATILE 36 | 37 | # Checks for library functions. 38 | AC_FUNC_MALLOC 39 | AC_FUNC_MEMCMP 40 | AC_TYPE_SIGNAL 41 | AC_FUNC_VPRINTF 42 | AC_CHECK_FUNCS([dup2 gethostbyname gettimeofday memmove memset socket strcasecmp strdup]) 43 | AC_PREFIX_DEFAULT(/usr/local/tbnet) 44 | AC_CONFIG_FILES([Makefile 45 | src/Makefile 46 | src/test/Makefile 47 | test/Makefile]) 48 | AC_OUTPUT 49 | -------------------------------------------------------------------------------- /trunk/tbnet/src/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS=-I$(TBLIB_ROOT)/include/tbsys 2 | source_list=channel.cpp channelpool.cpp connection.cpp controlpacket.cpp defaultpacketstreamer.cpp epollsocketevent.cpp httppacketstreamer.cpp httprequestpacket.cpp httpresponsepacket.cpp iocomponent.cpp packet.cpp packetqueue.cpp packetqueuethread.cpp serversocket.cpp socket.cpp socketevent.cpp stats.cpp tcpacceptor.cpp tcpcomponent.cpp tcpconnection.cpp transport.cpp udpcomponent.cpp udpconnection.cpp connectionmanager.cpp 3 | 4 | AM_LDFLAGS="-lpthread -lrt" 5 | test_sources= 6 | lib_LTLIBRARIES=libtbnet.la 7 | libtbnet_la_SOURCES=$(source_list) 8 | libtbnet_la_LDFLAGS=$(AM_LDFLAGS) -static-libgcc 9 | include_HEADERS=channel.h channelpool.h connection.h controlpacket.h databuffer.h defaultpacketstreamer.h epollsocketevent.h httppacketstreamer.h httprequestpacket.h httpresponsepacket.h iocomponent.h ipacketfactory.h ipackethandler.h ipacketstreamer.h iserveradapter.h packet.h packetqueue.h packetqueuethread.h serversocket.h socketevent.h socket.h stats.h tbnet.h tcpacceptor.h tcpcomponent.h tcpconnection.h transport.h udpacceptor.h udpcomponent.h udpconnection.h connectionmanager.h 10 | 11 | noinst_PROGRAMS= 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /trunk/tbnet/src/channel.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/channel.cpp -------------------------------------------------------------------------------- /trunk/tbnet/src/channel.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/channel.h -------------------------------------------------------------------------------- /trunk/tbnet/src/channelpool.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/channelpool.cpp -------------------------------------------------------------------------------- /trunk/tbnet/src/channelpool.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/channelpool.h -------------------------------------------------------------------------------- /trunk/tbnet/src/connection.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/connection.cpp -------------------------------------------------------------------------------- /trunk/tbnet/src/connection.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/connection.h -------------------------------------------------------------------------------- /trunk/tbnet/src/connectionmanager.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/connectionmanager.cpp -------------------------------------------------------------------------------- /trunk/tbnet/src/connectionmanager.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/connectionmanager.h -------------------------------------------------------------------------------- /trunk/tbnet/src/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 | ControlPacket ControlPacket::BadPacket(CMD_BAD_PACKET); 20 | ControlPacket ControlPacket::TimeoutPacket(CMD_TIMEOUT_PACKET); 21 | ControlPacket ControlPacket::DisconnPacket(CMD_DISCONN_PACKET); 22 | } 23 | -------------------------------------------------------------------------------- /trunk/tbnet/src/controlpacket.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/controlpacket.h -------------------------------------------------------------------------------- /trunk/tbnet/src/databuffer.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/databuffer.h -------------------------------------------------------------------------------- /trunk/tbnet/src/defaultpacketstreamer.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/defaultpacketstreamer.cpp -------------------------------------------------------------------------------- /trunk/tbnet/src/defaultpacketstreamer.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/defaultpacketstreamer.h -------------------------------------------------------------------------------- /trunk/tbnet/src/epollsocketevent.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/epollsocketevent.cpp -------------------------------------------------------------------------------- /trunk/tbnet/src/epollsocketevent.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/epollsocketevent.h -------------------------------------------------------------------------------- /trunk/tbnet/src/httppacketstreamer.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/httppacketstreamer.cpp -------------------------------------------------------------------------------- /trunk/tbnet/src/httppacketstreamer.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/httppacketstreamer.h -------------------------------------------------------------------------------- /trunk/tbnet/src/httprequestpacket.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/httprequestpacket.cpp -------------------------------------------------------------------------------- /trunk/tbnet/src/httprequestpacket.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/httprequestpacket.h -------------------------------------------------------------------------------- /trunk/tbnet/src/httpresponsepacket.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/httpresponsepacket.cpp -------------------------------------------------------------------------------- /trunk/tbnet/src/httpresponsepacket.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/httpresponsepacket.h -------------------------------------------------------------------------------- /trunk/tbnet/src/iocomponent.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/iocomponent.cpp -------------------------------------------------------------------------------- /trunk/tbnet/src/iocomponent.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/iocomponent.h -------------------------------------------------------------------------------- /trunk/tbnet/src/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 | class IPacketFactory { 22 | public: 23 | virtual ~IPacketFactory() {}; 24 | virtual Packet *createPacket(int pcode) = 0; 25 | }; 26 | } 27 | 28 | #endif /*IPACKET_FACTORY_H_*/ 29 | -------------------------------------------------------------------------------- /trunk/tbnet/src/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 | class IPacketHandler { 22 | public: 23 | enum HPRetCode { 24 | KEEP_CHANNEL = 0, 25 | CLOSE_CHANNEL = 1, 26 | FREE_CHANNEL = 2 27 | }; 28 | 29 | virtual ~IPacketHandler() {} 30 | virtual HPRetCode handlePacket(Packet *packet, void *args) = 0; 31 | }; 32 | } 33 | 34 | #endif /*IPACHETHANDLER_H_*/ 35 | -------------------------------------------------------------------------------- /trunk/tbnet/src/ipacketstreamer.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/ipacketstreamer.h -------------------------------------------------------------------------------- /trunk/tbnet/src/iserveradapter.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/iserveradapter.h -------------------------------------------------------------------------------- /trunk/tbnet/src/packet.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/packet.cpp -------------------------------------------------------------------------------- /trunk/tbnet/src/packet.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/packet.h -------------------------------------------------------------------------------- /trunk/tbnet/src/packetqueue.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/packetqueue.cpp -------------------------------------------------------------------------------- /trunk/tbnet/src/packetqueue.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/packetqueue.h -------------------------------------------------------------------------------- /trunk/tbnet/src/packetqueuethread.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/packetqueuethread.cpp -------------------------------------------------------------------------------- /trunk/tbnet/src/packetqueuethread.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/packetqueuethread.h -------------------------------------------------------------------------------- /trunk/tbnet/src/serversocket.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/serversocket.cpp -------------------------------------------------------------------------------- /trunk/tbnet/src/serversocket.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/serversocket.h -------------------------------------------------------------------------------- /trunk/tbnet/src/socket.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/socket.cpp -------------------------------------------------------------------------------- /trunk/tbnet/src/socket.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/socket.h -------------------------------------------------------------------------------- /trunk/tbnet/src/socketevent.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/socketevent.cpp -------------------------------------------------------------------------------- /trunk/tbnet/src/socketevent.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/socketevent.h -------------------------------------------------------------------------------- /trunk/tbnet/src/stats.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/stats.cpp -------------------------------------------------------------------------------- /trunk/tbnet/src/stats.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/stats.h -------------------------------------------------------------------------------- /trunk/tbnet/src/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 | class TimeUtil; 44 | class Thread; 45 | class Runnable; 46 | class DataBuffer; 47 | 48 | class Packet; 49 | class ControlPacket; 50 | class IPacketFactory; 51 | class IPacketHandler; 52 | class IPacketStreamer; 53 | class IServerAdapter; 54 | class DefaultPacketStreamer; 55 | class PacketQueue; 56 | 57 | class Socket; 58 | class ServerSocket; 59 | class IOEvent; 60 | class SocketEvent; 61 | class EPollSocketEvent; 62 | class Channel; 63 | class ChannelPool; 64 | class Connection; 65 | class IOComponent; 66 | class TCPAcceptor; 67 | class TCPComponent; 68 | class TCPConnection; 69 | class Transport; 70 | class UDPAcceptor; 71 | class UDPComponent; 72 | class UDPConnection; 73 | 74 | class HttpRequestPacket; 75 | class HttpResponsePacket; 76 | class HttpPacketStreamer; 77 | class DefaultHttpPacketFactory; 78 | class PacketQueueThread; 79 | class ConnectionManager; 80 | } 81 | 82 | #include "stats.h" 83 | 84 | #include "packet.h" 85 | #include "controlpacket.h" 86 | #include "ipacketfactory.h" 87 | #include "databuffer.h" 88 | #include "ipackethandler.h" 89 | #include "ipacketstreamer.h" 90 | #include "iserveradapter.h" 91 | #include "defaultpacketstreamer.h" 92 | #include "packetqueue.h" 93 | 94 | #include "socket.h" 95 | #include "serversocket.h" 96 | #include "socketevent.h" 97 | #include "epollsocketevent.h" 98 | 99 | #include "channel.h" 100 | #include "channelpool.h" 101 | #include "connection.h" 102 | #include "tcpconnection.h" 103 | #include "udpconnection.h" 104 | 105 | #include "iocomponent.h" 106 | #include "tcpacceptor.h" 107 | #include "tcpcomponent.h" 108 | #include "udpacceptor.h" 109 | #include "udpcomponent.h" 110 | #include "transport.h" 111 | 112 | #include "httprequestpacket.h" 113 | #include "httpresponsepacket.h" 114 | #include "httppacketstreamer.h" 115 | #include "packetqueuethread.h" 116 | #include "connectionmanager.h" 117 | 118 | #endif 119 | 120 | -------------------------------------------------------------------------------- /trunk/tbnet/src/tcpacceptor.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/tcpacceptor.cpp -------------------------------------------------------------------------------- /trunk/tbnet/src/tcpacceptor.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/tcpacceptor.h -------------------------------------------------------------------------------- /trunk/tbnet/src/tcpcomponent.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/tcpcomponent.cpp -------------------------------------------------------------------------------- /trunk/tbnet/src/tcpcomponent.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/tcpcomponent.h -------------------------------------------------------------------------------- /trunk/tbnet/src/tcpconnection.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/tcpconnection.cpp -------------------------------------------------------------------------------- /trunk/tbnet/src/tcpconnection.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/tcpconnection.h -------------------------------------------------------------------------------- /trunk/tbnet/src/test/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS=-I$(top_srcdir)/src 2 | LDADD=$(top_srcdir)/src/.libs/libanet.a 3 | AM_LDFLAGS=-lpthread -ldl 4 | 5 | test_sources= sockettf.cpp packetqueuetf.cpp 6 | 7 | check_PROGRAMS=dotest 8 | dotest_SOURCES=dotest.cpp $(test_sources) 9 | 10 | test: check 11 | ./dotest 12 | 13 | $(dotest_DEPENDENCIES): 14 | cd .. && make 15 | -------------------------------------------------------------------------------- /trunk/tbnet/src/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 | #include 25 | #include 26 | 27 | using namespace CppUnit; 28 | using namespace std; 29 | 30 | int main( int argc, char **argv) 31 | { 32 | TextUi::TestRunner runner; 33 | TestFactoryRegistry ®istry = TestFactoryRegistry::getRegistry(); 34 | runner.addTest( registry.makeTest() ); 35 | bool ok = runner.run("", false); 36 | return ok ? 0 : 1; 37 | } 38 | -------------------------------------------------------------------------------- /trunk/tbnet/src/test/epollsocketeventtf.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 "epollsocketeeventtf.h" 17 | #include 18 | 19 | namespace anet { 20 | CPPUNIT_TEST_SUITE_REGISTRATION(EpollSocketEeventTF); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /trunk/tbnet/src/test/epollsocketeventtf.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 | /** 17 | * $Id: $ 18 | */ 19 | 20 | #ifndef EPOLLSOCKETEVENTTF_H_ 21 | #define EPOLLSOCKETEVENTTF_H_ 22 | #include 23 | #include 24 | 2 25 | namespace anet { 26 | class EpollSocketEventTF : public CppUnit::TestFixture { 27 | CPPUNIT_TEST_SUITE(EpollSocketEventTF); 28 | CPPUNIT_TEST_SUITE_END(); 29 | public: 30 | void setUp(){} 31 | void tearDown(){} 32 | }; 33 | } 34 | 35 | #endif /*EPOLLSOCKETEVENTTF_H_*/ 36 | -------------------------------------------------------------------------------- /trunk/tbnet/src/test/packetqueuetf.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/test/packetqueuetf.cpp -------------------------------------------------------------------------------- /trunk/tbnet/src/test/packetqueuetf.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 | /** 17 | * $Id: packetqueuetf.h 6395 2008-07-02 04:46:42Z james.zhang $ 18 | */ 19 | 20 | #ifndef ANET__H_ 21 | #define PACKETQUEUETF_H_ 22 | #include 23 | #include 24 | #include 25 | 26 | namespace anet { 27 | class PacketQueueTF : public CppUnit::TestFixture { 28 | CPPUNIT_TEST_SUITE(PacketQueueTF); 29 | CPPUNIT_TEST(testPush); 30 | CPPUNIT_TEST(testPop); 31 | CPPUNIT_TEST(testMoveTo); 32 | CPPUNIT_TEST_SUITE_END(); 33 | public: 34 | void setUp(); 35 | void tearDown(); 36 | void testPush(); 37 | void testPop(); 38 | void testMoveTo(); 39 | }; 40 | } 41 | 42 | #endif /*PACKETQUEUETF_H_*/ 43 | -------------------------------------------------------------------------------- /trunk/tbnet/src/test/sockettf.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 "sockettf.h" 19 | #include "socket.h" 20 | #include "serversocket.h" 21 | #include "thread.h" 22 | using namespace std; 23 | namespace anet { 24 | CPPUNIT_TEST_SUITE_REGISTRATION(SocketTF); 25 | 26 | class PlainConnectRunnable : public Runnable { 27 | void run(Thread* thread, void *args){ 28 | Socket *socket = (Socket *) args; 29 | CPPUNIT_ASSERT(socket); 30 | CPPUNIT_ASSERT(socket->connect()); 31 | } 32 | }; 33 | 34 | struct SocketPair { 35 | ServerSocket * serverSocket; 36 | Socket *acceptedSocket; 37 | }; 38 | 39 | class PlainServerRunnable : public Runnable { 40 | void run(Thread* thread, void *args){ 41 | SocketPair *sockpair = (SocketPair*)args; 42 | CPPUNIT_ASSERT(sockpair->serverSocket); 43 | sockpair->acceptedSocket = sockpair->serverSocket->accept(); 44 | CPPUNIT_ASSERT(sockpair->acceptedSocket); 45 | } 46 | }; 47 | 48 | void SocketTF::setUp() { 49 | } 50 | void SocketTF::tearDown() { 51 | } 52 | 53 | void SocketTF::testSetGetAddress() { 54 | Socket socket; 55 | char result[32]; 56 | string expect; 57 | //testing invalid address 58 | CPPUNIT_ASSERT(!socket.setAddress("NoSushAddress.james.zhang",12345)); 59 | CPPUNIT_ASSERT(socket.setAddress(NULL, 12345)); 60 | CPPUNIT_ASSERT(socket.getAddr(result, 10)); 61 | CPPUNIT_ASSERT_EQUAL(string("0.0.0.0:1"), string(result)); 62 | CPPUNIT_ASSERT(socket.setAddress("", 0)); 63 | CPPUNIT_ASSERT(socket.setAddress("localhost", 12345)); 64 | CPPUNIT_ASSERT(socket.getAddr(result, 32)); 65 | CPPUNIT_ASSERT_EQUAL(string("127.0.0.1:12345"), string(result)); 66 | CPPUNIT_ASSERT(socket.setAddress("127.0.0.1", -1)); 67 | CPPUNIT_ASSERT(socket.getAddr(result, 32)); 68 | CPPUNIT_ASSERT_EQUAL(string("127.0.0.1:65535"), string(result)); 69 | CPPUNIT_ASSERT(socket.setAddress("202.165.102.205", 12345)); 70 | CPPUNIT_ASSERT(socket.setAddress("www.yahoo.com", 12345)); 71 | CPPUNIT_ASSERT(socket.setAddress("g.cn", 12345)); 72 | } 73 | 74 | void SocketTF::testReadWrite() { 75 | Socket socket; 76 | ServerSocket serverSocket; 77 | char data[]="Some Data"; 78 | char output[1024]; 79 | 80 | CPPUNIT_ASSERT_EQUAL(-1,socket.write(data, strlen(data))); 81 | CPPUNIT_ASSERT(socket.setAddress("localhost", 12345)); 82 | CPPUNIT_ASSERT(serverSocket.setAddress("localhost", 12345)); 83 | CPPUNIT_ASSERT(serverSocket.listen()); 84 | SocketPair socketPair; 85 | socketPair.serverSocket=&serverSocket; 86 | Thread tc, ts; 87 | PlainConnectRunnable pcr; 88 | PlainServerRunnable psr; 89 | tc.start(&pcr,&socket);//connect 90 | ts.start(&psr,&socketPair);//accept 91 | ts.join(); 92 | tc.join(); 93 | Socket *acceptedSocket = socketPair.acceptedSocket; 94 | acceptedSocket->setSoBlocking(false); 95 | socket.setSoBlocking(false); 96 | CPPUNIT_ASSERT(acceptedSocket); 97 | CPPUNIT_ASSERT_EQUAL(9, socket.write(data, strlen(data))); 98 | CPPUNIT_ASSERT_EQUAL(9, acceptedSocket->read(output, 10)); 99 | CPPUNIT_ASSERT_EQUAL(-1, acceptedSocket->read(NULL, 3)); 100 | CPPUNIT_ASSERT_EQUAL(string(data, 9), string(output, 9)); 101 | CPPUNIT_ASSERT_EQUAL(-1, acceptedSocket->read(output,10)); 102 | CPPUNIT_ASSERT_EQUAL(EAGAIN, Socket::getLastError()); 103 | CPPUNIT_ASSERT_EQUAL(3, socket.write(data, 3)); 104 | CPPUNIT_ASSERT_EQUAL(3, acceptedSocket->read(output, 10)); 105 | CPPUNIT_ASSERT_EQUAL(4, acceptedSocket->write(data, 4)); 106 | CPPUNIT_ASSERT_EQUAL(4, socket.read(output, 10)); 107 | CPPUNIT_ASSERT_EQUAL(string(data, 4), string(output, 4)); 108 | CPPUNIT_ASSERT_EQUAL(-1, socket.write(NULL, 3)); 109 | CPPUNIT_ASSERT_EQUAL(-1, acceptedSocket->read(NULL, 3)); 110 | acceptedSocket->close(); 111 | CPPUNIT_ASSERT_EQUAL(-1, acceptedSocket->read(output, 10)); 112 | delete acceptedSocket; 113 | socket.close(); 114 | CPPUNIT_ASSERT_EQUAL(-1, socket.write(data, 3)); 115 | tc.start(&pcr,&socket);//connect 116 | ts.start(&psr,&socketPair);//accept 117 | ts.join(); 118 | tc.join(); 119 | acceptedSocket = socketPair.acceptedSocket; 120 | acceptedSocket->setSoBlocking(false); 121 | CPPUNIT_ASSERT(acceptedSocket); 122 | acceptedSocket->shutdown(); 123 | /**@todo need to handle socket shutdown*/ 124 | // CPPUNIT_ASSERT_EQUAL(-1, acceptedSocket->read(output, 10)); 125 | // CPPUNIT_ASSERT_EQUAL(-1, acceptedSocket->write(data, 10)); 126 | socket.close(); 127 | delete acceptedSocket; 128 | CPPUNIT_ASSERT(socket.createUDP()); 129 | CPPUNIT_ASSERT_EQUAL(-1, socket.write(data, 3)); 130 | CPPUNIT_ASSERT(socket.setAddress("localhost",22)); 131 | CPPUNIT_ASSERT(socket.connect()); 132 | CPPUNIT_ASSERT_EQUAL(5, socket.write(data, 5)); 133 | // need more UDP interface? 134 | CPPUNIT_ASSERT_EQUAL(string("Need More"), string("UDP Interface")); 135 | } 136 | 137 | void SocketTF::testConnect(){ 138 | char data[] = "Short Data"; 139 | char output[256]; 140 | Socket socket; 141 | CPPUNIT_ASSERT(!socket.connect()); 142 | CPPUNIT_ASSERT(socket.setAddress("localhost",12346)); 143 | CPPUNIT_ASSERT(!socket.connect()); 144 | ServerSocket serverSocket; 145 | ServerSocket serverSocket2; 146 | CPPUNIT_ASSERT(!serverSocket.listen()); 147 | CPPUNIT_ASSERT(serverSocket.setAddress("localhost",12346)); 148 | CPPUNIT_ASSERT(serverSocket2.setAddress("localhost",12346)); 149 | CPPUNIT_ASSERT(serverSocket.listen()); 150 | CPPUNIT_ASSERT(!serverSocket2.listen()); 151 | 152 | CPPUNIT_ASSERT(socket.connect()); 153 | // should we detect if no body accept()? 154 | CPPUNIT_ASSERT_EQUAL(-1, socket.write(data,3)); 155 | Socket *acceptedSocket = serverSocket.accept(); 156 | CPPUNIT_ASSERT(acceptedSocket); 157 | CPPUNIT_ASSERT_EQUAL(3, acceptedSocket->read(output,256)); 158 | CPPUNIT_ASSERT_EQUAL(string(data,3), string(output,3)); 159 | Socket *acceptedSocket2 = serverSocket.accept(); 160 | CPPUNIT_ASSERT(!acceptedSocket2); 161 | delete acceptedSocket; 162 | CPPUNIT_ASSERT(socket.reconnect()); 163 | CPPUNIT_ASSERT_EQUAL(8, socket.write(data,8)); 164 | acceptedSocket2 = serverSocket.accept(); 165 | CPPUNIT_ASSERT(acceptedSocket2); 166 | CPPUNIT_ASSERT_EQUAL(8, acceptedSocket->read(output, 256)); 167 | CPPUNIT_ASSERT_EQUAL(string(data,8), string(output,8)); 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /trunk/tbnet/src/test/sockettf.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 | /** 17 | * $Id: sockettf.h 6395 2008-07-02 04:46:42Z james.zhang $ 18 | */ 19 | 20 | #ifndef SOCKETTF_H_ 21 | #define SOCKETTF_H_ 22 | #include 23 | #include 24 | #include 25 | 26 | namespace anet { 27 | class SocketTF : public CppUnit::TestFixture { 28 | CPPUNIT_TEST_SUITE(SocketTF); 29 | CPPUNIT_TEST(testSetGetAddress); // you can register more methods here 30 | CPPUNIT_TEST(testReadWrite); // you can register more methods here 31 | CPPUNIT_TEST(testConnect); 32 | CPPUNIT_TEST_SUITE_END(); 33 | public: 34 | void setUp(); 35 | void tearDown(); 36 | void testSetGetAddress(); 37 | void testReadWrite(); 38 | void testConnect(); 39 | }; 40 | } 41 | 42 | #endif /*SOCKETTF_H_*/ 43 | -------------------------------------------------------------------------------- /trunk/tbnet/src/transport.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/transport.cpp -------------------------------------------------------------------------------- /trunk/tbnet/src/transport.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/transport.h -------------------------------------------------------------------------------- /trunk/tbnet/src/udpacceptor.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/udpacceptor.h -------------------------------------------------------------------------------- /trunk/tbnet/src/udpcomponent.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/udpcomponent.cpp -------------------------------------------------------------------------------- /trunk/tbnet/src/udpcomponent.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/udpcomponent.h -------------------------------------------------------------------------------- /trunk/tbnet/src/udpconnection.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/udpconnection.cpp -------------------------------------------------------------------------------- /trunk/tbnet/src/udpconnection.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/src/udpconnection.h -------------------------------------------------------------------------------- /trunk/tbnet/test/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS=-I$(top_srcdir)/src -I$(top_srcdir)/../tbsys/src 2 | LDADD=$(top_srcdir)/src/.libs/libtbnet.a $(top_srcdir)/../tbsys/src/.libs/libtbsys.a 3 | AM_LDFLAGS=-lpthread -lrt 4 | 5 | noinst_PROGRAMS=echoserver echoclient httpserver 6 | echoserver_SOURCES=echoserver.cpp 7 | echoclient_SOURCES=echoclient.cpp 8 | httpserver_SOURCES=httpserver.cpp 9 | -------------------------------------------------------------------------------- /trunk/tbnet/test/echoclient.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/test/echoclient.cpp -------------------------------------------------------------------------------- /trunk/tbnet/test/echoserver.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/test/echoserver.cpp -------------------------------------------------------------------------------- /trunk/tbnet/test/httpserver.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbnet/test/httpserver.cpp -------------------------------------------------------------------------------- /trunk/tbsys/AUTHORS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/AUTHORS -------------------------------------------------------------------------------- /trunk/tbsys/ChangeLog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/ChangeLog -------------------------------------------------------------------------------- /trunk/tbsys/Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS=src test 2 | -------------------------------------------------------------------------------- /trunk/tbsys/NEWS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/NEWS -------------------------------------------------------------------------------- /trunk/tbsys/README: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/README -------------------------------------------------------------------------------- /trunk/tbsys/autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "$1" == "clean" ]; then 4 | make distclean 5 | rm -rf aclocal.m4 autom4te.cache config.guess config.sub configure depcomp INSTALL install-sh ltmain.sh missing config.status config.log libtool COPYING 6 | find . -name 'Makefile' -exec rm -f {} \; 7 | find . -name 'Makefile.in' -exec rm -f {} \; 8 | exit; 9 | fi 10 | 11 | libtoolize --force 12 | aclocal 13 | autoconf 14 | automake --add-missing --force 15 | -------------------------------------------------------------------------------- /trunk/tbsys/configure.ac: -------------------------------------------------------------------------------- 1 | # -*- Autoconf -*- 2 | # Process this file with autoconf to produce a configure script. 3 | 4 | AC_INIT(src/tbsys.h) 5 | AM_INIT_AUTOMAKE(tbsys, 0.1) 6 | 7 | # Checks for programs. 8 | AC_PROG_CXX 9 | AC_PROG_CC 10 | AC_PROG_CPP 11 | AC_PROG_INSTALL 12 | AC_PROG_LN_S 13 | AC_PROG_MAKE_SET 14 | AC_PROG_LIBTOOL 15 | AC_LANG_CPLUSPLUS 16 | CXXFLAGS="-g -Wall -fPIC" 17 | 18 | if test -n "${TBLIB_ROOT}"; then 19 | ac_default_prefix=${TBLIB_ROOT} 20 | includedir=${ac_default_prefix}/include/tbsys 21 | fi 22 | # Checks for libraries. 23 | 24 | # Checks for header files. 25 | AC_HEADER_STDC 26 | AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h string.h strings.h sys/socket.h sys/time.h unistd.h]) 27 | 28 | # Checks for typedefs, structures, and compiler characteristics. 29 | AC_HEADER_STDBOOL 30 | AC_C_CONST 31 | AC_C_INLINE 32 | AC_TYPE_SIZE_T 33 | AC_HEADER_TIME 34 | AC_STRUCT_TM 35 | AC_C_VOLATILE 36 | 37 | # Checks for library functions. 38 | AC_FUNC_MALLOC 39 | AC_FUNC_MEMCMP 40 | AC_TYPE_SIGNAL 41 | AC_FUNC_VPRINTF 42 | AC_CHECK_FUNCS([dup2 gethostbyname gettimeofday memmove memset socket strcasecmp strdup]) 43 | AC_PREFIX_DEFAULT(/usr/local/tbsys) 44 | AC_CONFIG_FILES([Makefile 45 | src/Makefile 46 | test/Makefile]) 47 | AC_OUTPUT 48 | -------------------------------------------------------------------------------- /trunk/tbsys/src/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 | -------------------------------------------------------------------------------- /trunk/tbsys/src/Cond.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/Cond.h -------------------------------------------------------------------------------- /trunk/tbsys/src/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 | -------------------------------------------------------------------------------- /trunk/tbsys/src/CtrlCHandler.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/CtrlCHandler.h -------------------------------------------------------------------------------- /trunk/tbsys/src/EventHandler.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/EventHandler.h -------------------------------------------------------------------------------- /trunk/tbsys/src/Exception.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 "Exception.h" 19 | #include "StaticMutex.h" 20 | using namespace std; 21 | namespace tbutil 22 | { 23 | Exception::Exception() : 24 | _file(0), 25 | _line(0) 26 | { 27 | } 28 | 29 | Exception::Exception(const char* file, int line) : 30 | _file(file), 31 | _line(line) 32 | { 33 | } 34 | 35 | Exception::~Exception() throw() 36 | { 37 | } 38 | 39 | const char* Exception::_name = "tbutil::Exception"; 40 | 41 | string Exception::name() const 42 | { 43 | return _name; 44 | } 45 | 46 | void Exception::print(ostream& out) const 47 | { 48 | if(_file && _line > 0) 49 | { 50 | out << _file << ':' << _line << ": "; 51 | } 52 | out << name(); 53 | } 54 | 55 | const char* Exception::what() const throw() 56 | { 57 | try 58 | { 59 | StaticMutex::Lock lock(globalMutex); 60 | { 61 | if(_str.empty()) 62 | { 63 | stringstream s; 64 | print(s); 65 | _str = s.str(); // Lazy initialization. 66 | } 67 | } 68 | return _str.c_str(); 69 | } 70 | catch(...) 71 | { 72 | } 73 | return ""; 74 | } 75 | 76 | Exception* Exception::clone() const 77 | { 78 | return new Exception(*this); 79 | } 80 | 81 | void Exception::_throw() const 82 | { 83 | throw *this; 84 | } 85 | 86 | const char* Exception::file() const 87 | { 88 | return _file; 89 | } 90 | 91 | int Exception::line() const 92 | { 93 | return _line; 94 | } 95 | 96 | std::ostream& operator << (std::ostream& out, const Exception& ex) 97 | { 98 | ex.print(out); 99 | return out; 100 | } 101 | 102 | NullHandleException::NullHandleException(const char* file, int line) : 103 | Exception(file, line) 104 | { 105 | //if(nullHandleAbort) 106 | { 107 | abort(); 108 | } 109 | } 110 | 111 | NullHandleException::~NullHandleException() throw() 112 | { 113 | } 114 | 115 | const char* NullHandleException::_name = "NullHandleException"; 116 | 117 | string NullHandleException::name() const 118 | { 119 | return _name; 120 | } 121 | 122 | Exception* NullHandleException::clone() const 123 | { 124 | return new NullHandleException(*this); 125 | } 126 | 127 | void NullHandleException::_throw() const 128 | { 129 | throw *this; 130 | } 131 | 132 | IllegalArgumentException::IllegalArgumentException(const char* file, int line) : 133 | Exception(file, line) 134 | { 135 | } 136 | 137 | IllegalArgumentException::IllegalArgumentException(const char* file, int line, const string& r) : 138 | Exception(file, line), 139 | _reason(r) 140 | { 141 | } 142 | 143 | IllegalArgumentException::~IllegalArgumentException() throw() 144 | { 145 | } 146 | 147 | const char* IllegalArgumentException::_name = "IllegalArgumentException"; 148 | 149 | string IllegalArgumentException::name() const 150 | { 151 | return _name; 152 | } 153 | 154 | void IllegalArgumentException::print(ostream& out) const 155 | { 156 | Exception::print(out); 157 | out << ": " << _reason; 158 | } 159 | 160 | Exception* IllegalArgumentException::clone() const 161 | { 162 | return new IllegalArgumentException(*this); 163 | } 164 | 165 | void IllegalArgumentException::_throw() const 166 | { 167 | throw *this; 168 | } 169 | 170 | string IllegalArgumentException::reason() const 171 | { 172 | return _reason; 173 | } 174 | 175 | SyscallException::SyscallException(const char* file, int line): 176 | Exception(file,line) 177 | { 178 | 179 | } 180 | 181 | SyscallException::SyscallException(const char* file, int line, int err ): 182 | Exception(file, line), 183 | _error(err) 184 | { 185 | } 186 | 187 | const char* SyscallException::_name = "SyscallException"; 188 | 189 | string SyscallException::name() const 190 | { 191 | return _name; 192 | } 193 | 194 | void SyscallException::print(ostream& os) const 195 | { 196 | Exception::print(os); 197 | if(_error != 0) 198 | { 199 | } 200 | } 201 | 202 | Exception* SyscallException::clone() const 203 | { 204 | return new SyscallException(*this); 205 | } 206 | 207 | void SyscallException::_throw() const 208 | { 209 | throw *this; 210 | } 211 | 212 | int SyscallException::error() 213 | { 214 | return _error; 215 | } 216 | }//end namespace tbutil 217 | 218 | -------------------------------------------------------------------------------- /trunk/tbsys/src/Exception.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/Exception.h -------------------------------------------------------------------------------- /trunk/tbsys/src/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::*p)(void) const) 42 | { 43 | return ConstMemFun >(p); 44 | } 45 | }//end namespace 46 | #endif 47 | -------------------------------------------------------------------------------- /trunk/tbsys/src/Handle.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/Handle.h -------------------------------------------------------------------------------- /trunk/tbsys/src/Lock.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/Lock.h -------------------------------------------------------------------------------- /trunk/tbsys/src/Makefile.am: -------------------------------------------------------------------------------- 1 | source_list=config.cpp defaultrunnable.cpp filequeue.cpp \ 2 | filequeuethread.cpp fileutil.cpp process.cpp \ 3 | queuethread.cpp stringutil.cpp tblog.cpp \ 4 | tbnetutil.cpp tbtimeutil.cpp tbrwlock.cpp\ 5 | Utility.cpp Time.cpp Cond.cpp RecMutex.cpp \ 6 | Shared.cpp TbThread.cpp StaticMutex.cpp Mutex.cpp\ 7 | Exception.cpp ThreadException.cpp CtrlCHandler.cpp\ 8 | Timer.cpp ThreadPool.cpp Service.cpp\ 9 | Network.cpp profiler.cpp bytebuffer.cpp WarningBuffer.cpp 10 | 11 | AM_LDFLAGS="-lpthread -lm -lrt" 12 | lib_LTLIBRARIES=libtbsys.la 13 | libtbsys_la_SOURCES=$(source_list) 14 | libtbsys_la_LDFLAGS=$(AM_LDFLAGS) -static-libgcc 15 | include_HEADERS=atomic.h config.h defaultrunnable.h filequeue.h \ 16 | filequeuethread.h fileutil.h iqueuehandler.h \ 17 | process.h queuethread.h runnable.h stringutil.h \ 18 | tblog.h tbnetutil.h tbsys.h tbtimeutil.h \ 19 | threadcond.h thread.h threadmutex.h linklist.h \ 20 | tbrwlock.h tblockguard.h PublicDefine.h Memory.hpp\ 21 | Cond.h Functional.h Lock.h Network.h EventHandler.h\ 22 | Service.h ThreadException.h Time.h Handle.h Monitor.h\ 23 | RecMutex.h Shared.h TbThread.h Timer.h CtrlCHandler.h\ 24 | Exception.h Mutex.h StaticMutex.h ThreadPool.h Utility.h \ 25 | profiler.h bytebuffer.h WarningBuffer.h 26 | 27 | noinst_PROGRAMS= 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /trunk/tbsys/src/Memory.hpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/Memory.hpp -------------------------------------------------------------------------------- /trunk/tbsys/src/Monitor.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/Monitor.h -------------------------------------------------------------------------------- /trunk/tbsys/src/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 | -------------------------------------------------------------------------------- /trunk/tbsys/src/Mutex.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/Mutex.h -------------------------------------------------------------------------------- /trunk/tbsys/src/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 | -------------------------------------------------------------------------------- /trunk/tbsys/src/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 | -------------------------------------------------------------------------------- /trunk/tbsys/src/PublicDefine.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/PublicDefine.h -------------------------------------------------------------------------------- /trunk/tbsys/src/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 | 169 | bool RecMutex::willUnlock() const 170 | { 171 | return _count == 1; 172 | } 173 | }//end namespace 174 | -------------------------------------------------------------------------------- /trunk/tbsys/src/RecMutex.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/RecMutex.h -------------------------------------------------------------------------------- /trunk/tbsys/src/Service.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/Service.cpp -------------------------------------------------------------------------------- /trunk/tbsys/src/Service.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/Service.h -------------------------------------------------------------------------------- /trunk/tbsys/src/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 | -------------------------------------------------------------------------------- /trunk/tbsys/src/Shared.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/Shared.h -------------------------------------------------------------------------------- /trunk/tbsys/src/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 | -------------------------------------------------------------------------------- /trunk/tbsys/src/StaticMutex.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/StaticMutex.h -------------------------------------------------------------------------------- /trunk/tbsys/src/TbThread.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 | #include 22 | #include 23 | #include "TbThread.h" 24 | #include "Time.h" 25 | #include "ThreadException.h" 26 | #include "Cond.h" 27 | #include "PublicDefine.h" 28 | 29 | using namespace std; 30 | namespace tbutil 31 | { 32 | Thread::Thread() : 33 | _running(false), 34 | _started(false), 35 | _detachable(false), 36 | _thread(0) 37 | { 38 | } 39 | 40 | Thread::~Thread() 41 | { 42 | } 43 | 44 | extern "C" 45 | { 46 | static void* startHook(void* arg) 47 | { 48 | ThreadPtr thread; 49 | try 50 | { 51 | Thread* rawThread = static_cast(arg); 52 | thread = rawThread; 53 | rawThread->__decRef(); 54 | thread->run(); 55 | } 56 | catch(...) 57 | { 58 | std::terminate(); 59 | } 60 | thread->_done(); 61 | return 0; 62 | } 63 | } 64 | 65 | int Thread::start(size_t stackSize) 66 | { 67 | ThreadPtr keepMe = this; 68 | Mutex::Lock sync(_mutex); 69 | 70 | if(_started) 71 | { 72 | #ifdef _NO_EXCEPTION 73 | JUST_RETURN( _started == true , -1 ); 74 | TBSYS_LOG(ERROR,"%s","ThreadStartedException"); 75 | #else 76 | throw ThreadStartedException(__FILE__, __LINE__); 77 | #endif 78 | } 79 | 80 | __incRef(); 81 | 82 | if(stackSize > 0) 83 | { 84 | pthread_attr_t attr; 85 | int rt = pthread_attr_init(&attr); 86 | #ifdef _NO_EXCEPTION 87 | if ( 0 != rt ) 88 | { 89 | __decRef(); 90 | TBSYS_LOG(ERROR,"%s","ThreadSyscallException"); 91 | return -1; 92 | } 93 | #else 94 | if ( 0 != rt ) 95 | { 96 | __decRef(); 97 | throw ThreadSyscallException(__FILE__, __LINE__, rt); 98 | } 99 | #endif 100 | 101 | if(stackSize < PTHREAD_STACK_MIN) 102 | { 103 | stackSize = PTHREAD_STACK_MIN; 104 | } 105 | 106 | rt = pthread_attr_setstacksize(&attr, stackSize); 107 | #ifdef _NO_EXCEPTION 108 | if ( 0 != rt ) 109 | { 110 | __decRef(); 111 | TBSYS_LOG(ERROR,"%s","ThreadSyscallException"); 112 | return -1; 113 | } 114 | #else 115 | if( 0 != rt ) 116 | { 117 | __decRef(); 118 | throw ThreadSyscallException(__FILE__, __LINE__, rt); 119 | } 120 | #endif 121 | rt = pthread_create(&_thread, &attr, startHook, this); 122 | #ifdef _NO_EXCEPTION 123 | if ( 0 != rt ) 124 | { 125 | __decRef(); 126 | TBSYS_LOG(ERROR,"%s","ThreadSyscallException"); 127 | return -1; 128 | } 129 | #else 130 | if( 0 != rt ) 131 | { 132 | __decRef(); 133 | throw ThreadSyscallException(__FILE__, __LINE__, rt); 134 | } 135 | #endif 136 | } 137 | else 138 | { 139 | const int rt = pthread_create(&_thread, 0, startHook, this); 140 | #ifdef _NO_EXCEPTION 141 | if ( 0 != rt ) 142 | { 143 | __decRef(); 144 | TBSYS_LOG(ERROR,"%s","ThreadSyscallException"); 145 | return -1; 146 | } 147 | #else 148 | if( 0 != rt ) 149 | { 150 | __decRef(); 151 | throw ThreadSyscallException(__FILE__, __LINE__, rt); 152 | } 153 | #endif 154 | } 155 | 156 | if ( _detachable ) 157 | { 158 | detach(); 159 | } 160 | _started = true; 161 | _running = true; 162 | return 0; 163 | } 164 | 165 | bool Thread::isAlive() const 166 | { 167 | return _running; 168 | } 169 | 170 | void Thread::_done() 171 | { 172 | Mutex::Lock lock(_mutex); 173 | _running = false; 174 | } 175 | 176 | int Thread::join() 177 | { 178 | if(_detachable) 179 | { 180 | #ifdef _NO_EXCEPTION 181 | TBSYS_LOG(ERROR,"%s","BadThreadControlException"); 182 | JUST_RETURN( _detachable==true , -1); 183 | #else 184 | throw BadThreadControlException(__FILE__, __LINE__); 185 | #endif 186 | } 187 | 188 | const int rt = pthread_join(_thread, NULL); 189 | #ifdef _NO_EXCEPTION 190 | if ( 0 != rt ) 191 | { 192 | TBSYS_LOG(ERROR,"%s","ThreadSyscallException"); 193 | return -1; 194 | } 195 | #else 196 | if( 0 != rt ) 197 | { 198 | throw ThreadSyscallException(__FILE__, __LINE__, rt); 199 | } 200 | #endif 201 | return 0; 202 | } 203 | 204 | int Thread::detach() 205 | { 206 | if(!_detachable) 207 | { 208 | #ifdef _NO_EXCEPTION 209 | TBSYS_LOG(ERROR,"%s","BadThreadControlException"); 210 | JUST_RETURN( _detachable==false, -1 ); 211 | #else 212 | throw BadThreadControlException(__FILE__, __LINE__); 213 | #endif 214 | } 215 | 216 | const int rt = pthread_detach(_thread); 217 | #ifdef _NO_EXCEPTION 218 | if ( 0 != rt ) 219 | { 220 | TBSYS_LOG(ERROR,"%s","ThreadSyscallException"); 221 | return -1; 222 | } 223 | #else 224 | if( 0 != rt ) 225 | { 226 | throw ThreadSyscallException(__FILE__, __LINE__, rt); 227 | } 228 | #endif 229 | return 0; 230 | } 231 | 232 | 233 | pthread_t Thread::id() const 234 | { 235 | return _thread;; 236 | } 237 | 238 | void Thread::ssleep(const tbutil::Time& timeout) 239 | { 240 | struct timeval tv = timeout; 241 | struct timespec ts; 242 | ts.tv_sec = tv.tv_sec; 243 | ts.tv_nsec = tv.tv_usec * 1000L; 244 | nanosleep(&ts, 0); 245 | } 246 | 247 | void Thread::yield() 248 | { 249 | sched_yield(); 250 | } 251 | }//end namespace tbutil 252 | -------------------------------------------------------------------------------- /trunk/tbsys/src/TbThread.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/TbThread.h -------------------------------------------------------------------------------- /trunk/tbsys/src/ThreadException.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 "ThreadException.h" 17 | #include "Time.h" 18 | 19 | using namespace std; 20 | namespace tbutil 21 | { 22 | ThreadSyscallException::ThreadSyscallException(const char* file, int line, int err ): 23 | SyscallException(file, line, err) 24 | { 25 | } 26 | 27 | const char* tbutil::ThreadSyscallException::_name = "::ThreadSyscallException"; 28 | 29 | string ThreadSyscallException::name() const 30 | { 31 | return _name; 32 | } 33 | 34 | Exception* ThreadSyscallException::clone() const 35 | { 36 | return new ThreadSyscallException(*this); 37 | } 38 | 39 | void ThreadSyscallException::_throw() const 40 | { 41 | throw *this; 42 | } 43 | 44 | ThreadLockedException::ThreadLockedException(const char* file, int line) : 45 | Exception(file, line) 46 | { 47 | } 48 | 49 | const char* tbutil::ThreadLockedException::_name = "::ThreadLockedException"; 50 | 51 | string ThreadLockedException::name() const 52 | { 53 | return _name; 54 | } 55 | 56 | Exception* ThreadLockedException::clone() const 57 | { 58 | return new ThreadLockedException(*this); 59 | } 60 | 61 | void ThreadLockedException::_throw() const 62 | { 63 | throw *this; 64 | } 65 | 66 | ThreadStartedException::ThreadStartedException(const char* file, int line) : 67 | Exception(file, line) 68 | { 69 | } 70 | 71 | const char* tbutil::ThreadStartedException::_name = "::ThreadStartedException"; 72 | 73 | string ThreadStartedException::name() const 74 | { 75 | return _name; 76 | } 77 | 78 | Exception* ThreadStartedException::clone() const 79 | { 80 | return new ThreadStartedException(*this); 81 | } 82 | 83 | void ThreadStartedException::_throw() const 84 | { 85 | throw *this; 86 | } 87 | 88 | ThreadNotStartedException::ThreadNotStartedException(const char* file, int line) : 89 | Exception(file, line) 90 | { 91 | } 92 | 93 | const char* tbutil::ThreadNotStartedException::_name = "::ThreadNotStartedException"; 94 | 95 | string ThreadNotStartedException::name() const 96 | { 97 | return _name; 98 | } 99 | 100 | Exception* ThreadNotStartedException::clone() const 101 | { 102 | return new ThreadNotStartedException(*this); 103 | } 104 | 105 | void ThreadNotStartedException::_throw() const 106 | { 107 | throw *this; 108 | } 109 | 110 | 111 | BadThreadControlException::BadThreadControlException(const char* file, int line) : 112 | Exception(file, line) 113 | { 114 | } 115 | 116 | const char* tbutil::BadThreadControlException::_name = "::BadThreadControlException"; 117 | 118 | string BadThreadControlException::name() const 119 | { 120 | return _name; 121 | } 122 | 123 | Exception* BadThreadControlException::clone() const 124 | { 125 | return new BadThreadControlException(*this); 126 | } 127 | 128 | void BadThreadControlException::_throw() const 129 | { 130 | throw *this; 131 | } 132 | 133 | InvalidTimeoutException::InvalidTimeoutException(const char* file, int line, 134 | const tbutil::Time& timeout): 135 | Exception(file, line), 136 | _timeout(timeout) 137 | { 138 | } 139 | 140 | const char* tbutil::InvalidTimeoutException::_name = "::InvalidTimeoutException"; 141 | 142 | string InvalidTimeoutException::name() const 143 | { 144 | return _name; 145 | } 146 | 147 | void InvalidTimeoutException::print(ostream& os) const 148 | { 149 | Exception::print(os); 150 | } 151 | 152 | Exception* InvalidTimeoutException::clone() const 153 | { 154 | return new InvalidTimeoutException(*this); 155 | } 156 | 157 | void InvalidTimeoutException::_throw() const 158 | { 159 | throw *this; 160 | } 161 | const char* tbutil::ThreadCreateException::_name="::ThreadCreateException"; 162 | 163 | ThreadCreateException::ThreadCreateException(const char* file , int line): 164 | Exception(file,line) 165 | { 166 | 167 | } 168 | 169 | string ThreadCreateException::name() const 170 | { 171 | return _name; 172 | } 173 | 174 | void ThreadCreateException::print(ostream& os ) const 175 | { 176 | Exception::print(os); 177 | } 178 | 179 | Exception* ThreadCreateException::clone() const 180 | { 181 | return new ThreadCreateException(*this); 182 | } 183 | 184 | void ThreadCreateException::_throw() const 185 | { 186 | throw *this; 187 | } 188 | }//end namespace tbutil 189 | -------------------------------------------------------------------------------- /trunk/tbsys/src/ThreadException.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/ThreadException.h -------------------------------------------------------------------------------- /trunk/tbsys/src/ThreadPool.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 "ThreadPool.h" 17 | #include "Functional.h" 18 | #include "Exception.h" 19 | #include "Memory.hpp" 20 | 21 | using namespace std; 22 | namespace tbutil 23 | { 24 | ThreadPool::ThreadPool(int size , int sizeMax, int sizeWarn,int listSizeMax,int stackSize) : 25 | _destroyed(false), 26 | _listSize( 0 ), 27 | _procSize( 0 ), 28 | _listSizeMax( listSizeMax), 29 | _size(size), 30 | _sizeMax(sizeMax), 31 | _sizeWarn(sizeWarn), 32 | _stackSize(0), 33 | _running(0), 34 | _inUse(0), 35 | _load(1.0), 36 | _promote(true), 37 | _waitingNumber(0) 38 | { 39 | if ( size < 1 ) 40 | size = 1; 41 | 42 | if ( sizeMax < size ) 43 | sizeMax = size; 44 | 45 | if ( sizeWarn > sizeMax ) 46 | sizeWarn = sizeMax; 47 | 48 | if ( stackSize < 0 ) 49 | stackSize = 16 * 1024 * 1024; 50 | 51 | const_cast(_size) = size; 52 | const_cast(_sizeMax) = sizeMax; 53 | const_cast(_sizeWarn) = sizeWarn; 54 | const_cast(_stackSize) = static_cast(stackSize); 55 | 56 | try 57 | { 58 | for(int i = 0 ; i < _size ; ++i) 59 | { 60 | ThreadPtr thread = new EventHandlerThread(this); 61 | thread->start(_stackSize); 62 | _threads.push_back(thread); 63 | ++_running; 64 | } 65 | } 66 | catch(const Exception& ex) 67 | { 68 | destroy(); 69 | joinWithAllThreads(); 70 | } 71 | } 72 | 73 | ThreadPool::~ThreadPool() 74 | { 75 | assert(_destroyed); 76 | _monitor.lock(); 77 | TBSYS_LOG(DEBUG,"_workItem.size: %d,_listSize: %d,_procSize: %d", _workItems.size(),_listSize,_procSize); 78 | while( !_workItems.empty() ) 79 | { 80 | ThreadPoolWorkItem* workItem = _workItems.front(); 81 | if ( workItem != NULL ) 82 | { 83 | workItem->destroy(); 84 | tbsys::gDelete(workItem); 85 | } 86 | _workItems.pop_front(); 87 | } 88 | _monitor.unlock(); 89 | } 90 | 91 | void ThreadPool::destroy() 92 | { 93 | this->lock(); 94 | assert(!_destroyed); 95 | _destroyed = true; 96 | this->notifyAll(); 97 | this->unlock(); 98 | _monitor.lock(); 99 | _monitor.notifyAll(); 100 | _monitor.unlock(); 101 | } 102 | 103 | int ThreadPool::execute(ThreadPoolWorkItem* workItem) 104 | { 105 | if ( _destroyed) 106 | { 107 | //TBSYS_LOG(ERROR,"%s","ThreadPoolDestroyedException"); 108 | return -1; 109 | } 110 | if (_listSize > _listSizeMax ) 111 | { 112 | //TBSYS_LOG(DEBUG,"%s","ThreadPoolQueueFullException"); 113 | return -1; 114 | } 115 | 116 | _monitor.lock(); 117 | _workItems.push_back(workItem); 118 | ++_listSize; 119 | _monitor.notify(); 120 | _monitor.unlock(); 121 | return 0; 122 | } 123 | 124 | void ThreadPool::promoteFollower( pthread_t thid ) 125 | { 126 | if(_sizeMax > 1) 127 | { 128 | this->lock(); 129 | assert(!_promote); 130 | _promote = true; 131 | this->notify(); 132 | 133 | if(!_destroyed) 134 | { 135 | assert(_inUse >= 0); 136 | ++_inUse; 137 | 138 | if(_inUse == _sizeWarn) 139 | { 140 | /*cout << "thread pool `" << "' is running low on threads\n" 141 | << "Size=" << _size << ", " << "SizeMax=" << _sizeMax << ", " 142 | << "SizeWarn=" << _sizeWarn<<", " <<"_inUse=" <<_inUse << ", " 143 | << "_running=" << _running <<". " <<"threads.size="<< _threads.size() << ", " 144 | << "_workItems.size="<< _workItems.size()<start(_stackSize); 154 | _threads.push_back(thread); 155 | ++_running; 156 | } 157 | catch(const Exception& ex) 158 | { 159 | throw ThreadCreateException(__FILE__,__LINE__); 160 | } 161 | } 162 | } 163 | this->unlock(); 164 | } 165 | } 166 | 167 | void ThreadPool::joinWithAllThreads() 168 | { 169 | assert(_destroyed); 170 | for(vector::iterator p = _threads.begin(); p != _threads.end(); ++p) 171 | { 172 | (*p)->join(); 173 | } 174 | } 175 | 176 | 177 | bool ThreadPool::isMaxCapacity() const 178 | { 179 | return _listSize > _listSizeMax ? true:false; 180 | } 181 | 182 | bool ThreadPool::run( pthread_t thid) 183 | { 184 | ThreadPool* self = this; 185 | while(true) 186 | { 187 | #ifdef DEBUG 188 | cout<<"["< 1 ) 191 | { 192 | this->lock(); 193 | while( !_promote ) 194 | { 195 | #ifdef DEBUG 196 | cout<<"["<wait(); 199 | #ifdef DEBUG 200 | cout<<"["<unlock(); 207 | return false; 208 | } 209 | #ifdef DEBUG 210 | cout<<"["<unlock(); 215 | } 216 | 217 | #ifdef DEBUG 218 | cout<<"["<execute(self); 270 | } 271 | catch(const Exception& ex) 272 | { 273 | cout << "exception in" << "while calling execute():"<destroy(); 282 | tbsys::gDelete( workItem ); 283 | } 284 | } 285 | #ifdef DEBUG 286 | cout<<"["< 1) 289 | { 290 | this->lock(); 291 | if(!_destroyed) 292 | { 293 | const int sz = static_cast(_threads.size()); 294 | assert(_running <= sz); 295 | if(_running < sz) 296 | { 297 | vector::iterator start = 298 | partition(_threads.begin(), _threads.end(), constMemFun(&Thread::isAlive)); 299 | 300 | for(vector::iterator p = start; p != _threads.end(); ++p) 301 | { 302 | (*p)->join(); 303 | --_running; 304 | } 305 | 306 | _threads.erase(start, _threads.end()); 307 | } 308 | #ifdef DEBUG 309 | cout<<"["<(_inUse); 312 | if(_load < inUse) 313 | { 314 | _load = inUse; 315 | } 316 | else 317 | { 318 | const double loadFactor = 0.05; // TODO: Configurable? 319 | const double oneMinusLoadFactor = 1 - loadFactor; 320 | _load = _load * oneMinusLoadFactor + inUse * loadFactor; 321 | } 322 | 323 | if(_running > _size) 324 | { 325 | cout<<"_running: "<<_running<<"_size :"<<_size<(_load + 0.5); 327 | 328 | if(load + 1 < _running) 329 | { 330 | assert(_inUse > 0); 331 | --_inUse; 332 | 333 | assert(_running > 0); 334 | --_running; 335 | this->unlock(); 336 | return false; 337 | } 338 | }*/ 339 | assert(_inUse > 0); 340 | --_inUse; 341 | } 342 | this->unlock(); 343 | }//end _sizeMax > 1 344 | }//end while 345 | } 346 | 347 | ThreadPool::EventHandlerThread::EventHandlerThread(const ThreadPool* pool) 348 | { 349 | _pool = (ThreadPool*)pool; 350 | } 351 | 352 | void ThreadPool::EventHandlerThread::run() 353 | { 354 | bool promote; 355 | 356 | try 357 | { 358 | promote = _pool->run( id() ); 359 | } 360 | catch(const std::exception& ex) 361 | { 362 | promote = true; 363 | cout<_promote<_sizeMax > 1) 375 | { 376 | { 377 | _pool->lock(); 378 | assert(!_pool->_promote); 379 | _pool->_promote = true; 380 | _pool->notify(); 381 | _pool->unlock(); 382 | } 383 | } 384 | } 385 | }//end namespace tbutil 386 | -------------------------------------------------------------------------------- /trunk/tbsys/src/ThreadPool.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/ThreadPool.h -------------------------------------------------------------------------------- /trunk/tbsys/src/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 | if(clock_gettime(CLOCK_MONOTONIC, &ts) < 0) 48 | { 49 | #ifdef _NO_EXCEPTION 50 | TBSYS_LOG(ERROR,"%s","SyscallException"); 51 | assert(0); 52 | #else 53 | throw SyscallException(__FILE__, __LINE__, errno); 54 | #endif 55 | } 56 | return Time(ts.tv_sec * T_INT64(1000000) + ts.tv_nsec / T_INT64(1000)); 57 | } 58 | } 59 | 60 | Time Time::seconds(Int64 t) 61 | { 62 | return Time(t * T_INT64(1000000)); 63 | } 64 | 65 | Time Time::milliSeconds(Int64 t) 66 | { 67 | return Time(t * T_INT64(1000)); 68 | } 69 | 70 | Time Time::microSeconds(Int64 t) 71 | { 72 | return Time(t); 73 | } 74 | 75 | Time::operator timeval() const 76 | { 77 | timeval tv; 78 | tv.tv_sec = static_cast(_usec / 1000000); 79 | tv.tv_usec = static_cast(_usec % 1000000); 80 | return tv; 81 | } 82 | 83 | Int64 Time::toSeconds() const 84 | { 85 | return _usec / 1000000; 86 | } 87 | 88 | Int64 Time::toMilliSeconds() const 89 | { 90 | return _usec / 1000; 91 | } 92 | 93 | Int64 Time::toMicroSeconds() const 94 | { 95 | return _usec; 96 | } 97 | 98 | double Time::toSecondsDouble() const 99 | { 100 | return _usec / 1000000.0; 101 | } 102 | 103 | double Time::toMilliSecondsDouble() const 104 | { 105 | return _usec / 1000.0; 106 | } 107 | 108 | double Time::toMicroSecondsDouble() const 109 | { 110 | return static_cast(_usec); 111 | } 112 | 113 | std::string Time::toDateTime() const 114 | { 115 | time_t time = static_cast(_usec / 1000000); 116 | 117 | struct tm* t; 118 | struct tm tr; 119 | localtime_r(&time, &tr); 120 | t = &tr; 121 | 122 | char buf[32]; 123 | strftime(buf, sizeof(buf), "%F %H:%M:%S", t); 124 | //strftime(buf, sizeof(buf), "%x %H:%M:%S", t); 125 | 126 | std::ostringstream os; 127 | os << buf << "."; 128 | os.fill('0'); 129 | os.width(3); 130 | os << static_cast(_usec % 1000000 / 1000); 131 | return os.str(); 132 | } 133 | 134 | std::string Time::toDuration() const 135 | { 136 | Int64 usecs = _usec % 1000000; 137 | Int64 secs = _usec / 1000000 % 60; 138 | Int64 mins = _usec / 1000000 / 60 % 60; 139 | Int64 hours = _usec / 1000000 / 60 / 60 % 24; 140 | Int64 days = _usec / 1000000 / 60 / 60 / 24; 141 | 142 | using namespace std; 143 | 144 | ostringstream os; 145 | if(days != 0) 146 | { 147 | os << days << "d "; 148 | } 149 | os << setfill('0') << setw(2) << hours << ":" << setw(2) << mins << ":" << setw(2) << secs; 150 | if(usecs != 0) 151 | { 152 | os << "." << setw(3) << (usecs / 1000); 153 | } 154 | 155 | return os.str(); 156 | } 157 | 158 | Time::Time(Int64 usec) : 159 | _usec(usec) 160 | { 161 | } 162 | 163 | }//end namespace tbutil 164 | -------------------------------------------------------------------------------- /trunk/tbsys/src/Time.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/Time.h -------------------------------------------------------------------------------- /trunk/tbsys/src/Timer.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 "Timer.h" 17 | #include "Exception.h" 18 | 19 | using namespace std; 20 | namespace tbutil 21 | { 22 | Timer::Timer() : 23 | Thread(), 24 | _destroyed(false) 25 | { 26 | start(); 27 | } 28 | 29 | void Timer::destroy() 30 | { 31 | { 32 | Monitor::Lock sync(_monitor); 33 | if(_destroyed) 34 | { 35 | return; 36 | } 37 | _destroyed = true; 38 | _monitor.notifyAll(); 39 | _tasks.clear(); 40 | _tokens.clear(); 41 | } 42 | 43 | if(!_detachable) 44 | { 45 | join(); 46 | } 47 | } 48 | 49 | int Timer::schedule(const TimerTaskPtr& task, const Time& delay) 50 | { 51 | Monitor::Lock sync(_monitor); 52 | if(_destroyed) 53 | { 54 | #ifdef _NO_EXCEPTION 55 | TBSYS_LOG(ERROR,"%s","timer destroyed..."); 56 | return -1; 57 | #else 58 | throw IllegalArgumentException(__FILE__, __LINE__, "timer destroyed"); 59 | #endif 60 | } 61 | 62 | Time time = Time::now(Time::Monotonic) + delay; 63 | bool inserted = _tasks.insert(make_pair(task, time)).second; 64 | if(!inserted) 65 | { 66 | #ifdef _NO_EXCEPTION 67 | TBSYS_LOG(ERROR,"%s","task is already schedulded..."); 68 | return -1; 69 | #else 70 | throw IllegalArgumentException(__FILE__, __LINE__, "task is already schedulded"); 71 | #endif 72 | } 73 | _tokens.insert(Token(time, Time(), task)); 74 | 75 | if(_wakeUpTime == Time() || time < _wakeUpTime) 76 | { 77 | _monitor.notify(); 78 | } 79 | return 0; 80 | } 81 | 82 | int Timer::scheduleRepeated(const TimerTaskPtr& task, const Time& delay) 83 | { 84 | Monitor::Lock sync(_monitor); 85 | if(_destroyed) 86 | { 87 | #ifdef _NO_EXCEPTION 88 | TBSYS_LOG(ERROR,"%s","timer destroyed..."); 89 | return -1; 90 | #else 91 | throw IllegalArgumentException(__FILE__, __LINE__, "timer destroyed"); 92 | #endif 93 | } 94 | 95 | const Token token(Time::now(Time::Monotonic) + delay, delay, task); 96 | bool inserted = _tasks.insert(make_pair(task, token.scheduledTime)).second; 97 | if(!inserted) 98 | { 99 | #ifdef _NO_EXCEPTION 100 | TBSYS_LOG(ERROR,"%s","task is already schedulded..."); 101 | return -1; 102 | #else 103 | throw IllegalArgumentException(__FILE__, __LINE__, "task is already schedulded"); 104 | #endif 105 | } 106 | _tokens.insert(token); 107 | 108 | if(_wakeUpTime == Time() || token.scheduledTime < _wakeUpTime) 109 | { 110 | _monitor.notify(); 111 | } 112 | return 0; 113 | } 114 | 115 | bool Timer::cancel(const TimerTaskPtr& task) 116 | { 117 | Monitor::Lock sync(_monitor); 118 | if(_destroyed) 119 | { 120 | return false; 121 | } 122 | 123 | map::iterator p = _tasks.find(task); 124 | if(p == _tasks.end()) 125 | { 126 | return false; 127 | } 128 | 129 | _tokens.erase(Token(p->second, Time(), p->first)); 130 | _tasks.erase(p); 131 | 132 | return true; 133 | } 134 | 135 | void 136 | Timer::run() 137 | { 138 | Token token(Time(), Time(), 0); 139 | while(true) 140 | { 141 | { 142 | Monitor::Lock sync(_monitor); 143 | 144 | if(!_destroyed) 145 | { 146 | if(token.delay != Time()) 147 | { 148 | map::iterator p = _tasks.find(token.task); 149 | if(p != _tasks.end()) 150 | { 151 | token.scheduledTime = Time::now(Time::Monotonic) + token.delay; 152 | p->second = token.scheduledTime; 153 | _tokens.insert(token); 154 | } 155 | } 156 | token = Token(Time(), Time(), 0); 157 | 158 | if(_tokens.empty()) 159 | { 160 | _wakeUpTime = Time(); 161 | _monitor.wait(); 162 | } 163 | } 164 | 165 | if(_destroyed) 166 | { 167 | break; 168 | } 169 | 170 | while(!_tokens.empty() && !_destroyed) 171 | { 172 | const Time now = Time::now(Time::Monotonic); 173 | const Token& first = *(_tokens.begin()); 174 | if(first.scheduledTime <= now) 175 | { 176 | token = first; 177 | _tokens.erase(_tokens.begin()); 178 | if(token.delay == Time()) 179 | { 180 | _tasks.erase(token.task); 181 | } 182 | break; 183 | } 184 | 185 | _wakeUpTime = first.scheduledTime; 186 | _monitor.timedWait(first.scheduledTime - now); 187 | } 188 | 189 | if(_destroyed) 190 | { 191 | break; 192 | } 193 | } 194 | 195 | if(token.task) 196 | { 197 | try 198 | { 199 | token.task->runTimerTask(); 200 | } 201 | catch(const std::exception& e) 202 | { 203 | cerr << "Timer::run(): uncaught exception:\n" << e.what() << endl; 204 | } 205 | catch(...) 206 | { 207 | cerr << "Timer::run(): uncaught exception" << endl; 208 | } 209 | } 210 | } 211 | } 212 | }// end namespace tbutil 213 | -------------------------------------------------------------------------------- /trunk/tbsys/src/Timer.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/Timer.h -------------------------------------------------------------------------------- /trunk/tbsys/src/Utility.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/Utility.cpp -------------------------------------------------------------------------------- /trunk/tbsys/src/Utility.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/Utility.h -------------------------------------------------------------------------------- /trunk/tbsys/src/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 | bool WarningBuffer::is_log_on_ = false; 21 | 22 | WarningBuffer *get_tsi_warning_buffer() 23 | { 24 | static WarningBufferFactory instance; 25 | return instance.get_buffer(); 26 | } 27 | 28 | 29 | }; 30 | 31 | -------------------------------------------------------------------------------- /trunk/tbsys/src/WarningBuffer.h: -------------------------------------------------------------------------------- 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.h, 09/27/2012 05:01:00 PM xiaochu Exp $ 10 | * 11 | * Author: 12 | * xiaochu.yh 13 | * Description: 14 | * fix length string ring buffer for warning message 15 | * 16 | */ 17 | #ifndef TBSYS_WARNING_BUFFER_H_ 18 | #define TBSYS_WARNING_BUFFER_H_ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include "tblog.h" 27 | 28 | namespace tbsys 29 | { 30 | class WarningBuffer 31 | { 32 | public: 33 | WarningBuffer() : append_idx_(0), total_warning_count_(0) 34 | { 35 | // nop 36 | } 37 | ~WarningBuffer() 38 | { 39 | reset(); 40 | } 41 | inline void reset(void) 42 | { 43 | append_idx_ = 0; 44 | total_warning_count_ = 0; 45 | } 46 | inline static void set_warn_log_on(const bool is_log_on) 47 | { 48 | is_log_on_ = is_log_on; 49 | } 50 | inline static bool is_warn_log_on(void) 51 | { 52 | return is_log_on_; 53 | } 54 | inline uint32_t get_total_warning_count(void) const 55 | { 56 | return total_warning_count_; 57 | } 58 | inline uint32_t get_buffer_size(void) const 59 | { 60 | return BUFFER_SIZE; 61 | } 62 | inline uint32_t get_readable_warning_count(void) const 63 | { 64 | return (total_warning_count_ < get_buffer_size()) ? total_warning_count_ : get_buffer_size(); 65 | } 66 | inline uint32_t get_max_warn_len(void) const 67 | { 68 | return WarningItem::STR_LEN; 69 | } 70 | 71 | /* 72 | * 获取WARNING字符串 73 | * idx取值范围[0, get_readable_warning_count) 74 | * 返回值为对应WARNING字符串 75 | * 当idx超出取值范围的时候返回NULL 76 | */ 77 | const char *get_warning(const uint32_t idx) const 78 | { 79 | const char *ret = NULL; 80 | if (idx < get_readable_warning_count()) 81 | { 82 | uint32_t loc = idx; 83 | if (total_warning_count_ > BUFFER_SIZE) 84 | { 85 | loc = (append_idx_ + idx) % BUFFER_SIZE; 86 | } 87 | ret = item_[loc].get(); 88 | } 89 | return ret; 90 | } 91 | /* 92 | * 将WARNING写入到Buffer中 93 | * 如果buffer已满,覆盖最老的Warning 94 | * 如果str长度超过STR_LEN,自动截断 95 | */ 96 | int append_warning(const char *str) 97 | { 98 | //if (is_log_on_) 99 | { 100 | item_[append_idx_].set(str); 101 | append_idx_ = (append_idx_ + 1) % BUFFER_SIZE; 102 | total_warning_count_++; 103 | } 104 | return 0; 105 | } 106 | 107 | void set_err_msg(const char* str) 108 | { 109 | err_msg_.set(str); 110 | } 111 | const char* get_err_msg() const 112 | { 113 | return err_msg_.get(); 114 | } 115 | WarningBuffer& operator= (const WarningBuffer &other) 116 | { 117 | if (this != &other) 118 | { 119 | uint32_t n = total_warning_count_ >= BUFFER_SIZE ? BUFFER_SIZE : append_idx_; 120 | for (uint32_t i = 0; i < n; ++i) 121 | { 122 | item_[i] = other.item_[i]; 123 | } 124 | err_msg_ = other.err_msg_; 125 | append_idx_ = other.append_idx_; 126 | total_warning_count_ = other.total_warning_count_; 127 | } 128 | return *this; 129 | } 130 | private: 131 | struct WarningItem{ 132 | static const uint32_t STR_LEN = 512; 133 | char msg_[STR_LEN]; 134 | int64_t timestamp_; 135 | int log_level_; 136 | int line_no_; 137 | 138 | void set(const char*str) 139 | { 140 | snprintf(msg_, STR_LEN, "%s", str); 141 | } 142 | const char *get() const 143 | { 144 | return static_cast(msg_); 145 | } 146 | WarningItem &operator= (const WarningItem &other) 147 | { 148 | if (this != &other) 149 | { 150 | strcpy(msg_, other.msg_); 151 | timestamp_ = other.timestamp_; 152 | log_level_ = other.log_level_; 153 | line_no_ = other.line_no_; 154 | } 155 | return *this; 156 | } 157 | }; 158 | 159 | private: 160 | // const define 161 | static const uint32_t BUFFER_SIZE = 64; 162 | WarningItem item_[BUFFER_SIZE]; 163 | WarningItem err_msg_; 164 | uint32_t append_idx_; 165 | uint32_t total_warning_count_; 166 | static bool is_log_on_; 167 | }; 168 | 169 | class WarningBufferFactory 170 | { 171 | public: 172 | WarningBufferFactory() : key_(INVALID_THREAD_KEY) 173 | { 174 | create_thread_key(); 175 | } 176 | 177 | ~WarningBufferFactory() 178 | { 179 | delete_thread_key(); 180 | } 181 | 182 | WarningBuffer* get_buffer() const 183 | { 184 | WarningBuffer * buffer = NULL; 185 | if (INVALID_THREAD_KEY != key_) 186 | { 187 | void* ptr = pthread_getspecific(key_); 188 | if (NULL == ptr) 189 | { 190 | ptr = malloc(sizeof(WarningBuffer)); 191 | if (NULL != ptr) 192 | { 193 | int ret = pthread_setspecific(key_, ptr); 194 | if (0 != ret) 195 | { 196 | // TBSYS_LOG(ERROR, "pthread_setspecific failed:%d", ret); 197 | free(ptr); 198 | ptr = NULL; 199 | } 200 | else 201 | { 202 | buffer = new (ptr) WarningBuffer(); 203 | } 204 | } 205 | else 206 | { 207 | // malloc failed; 208 | // TBSYS_LOG(ERROR, "malloc thread specific memeory failed."); 209 | } 210 | } 211 | else 212 | { 213 | // got exist ptr; 214 | buffer = reinterpret_cast(ptr); 215 | } 216 | } 217 | else 218 | { 219 | // TBSYS_LOG(ERROR, "thread key must be initialized " 220 | // "and size must great than zero, key:%u,size:%d", key_, size_); 221 | } 222 | return buffer; 223 | } 224 | private: 225 | int create_thread_key() 226 | { 227 | int ret = pthread_key_create(&key_, destroy_thread_key); 228 | if (0 != ret) 229 | { 230 | TBSYS_LOG(ERROR, "cannot create thread key:%d", ret); 231 | } 232 | return (0 == ret) ? 0 : 1; 233 | } 234 | 235 | int delete_thread_key() 236 | { 237 | int ret = -1; 238 | if (INVALID_THREAD_KEY != key_) 239 | { 240 | ret = pthread_key_delete(key_); 241 | } 242 | if (0 != ret) 243 | { 244 | TBSYS_LOG(ERROR, "delete thread key key_ failed."); 245 | } 246 | return (0 == ret) ? 0 : 1; 247 | } 248 | 249 | static void destroy_thread_key(void* ptr) 250 | { 251 | if (NULL != ptr) free(ptr); 252 | //fprintf(stderr, "destroy %p\n", ptr); 253 | } 254 | private: 255 | static const pthread_key_t INVALID_THREAD_KEY = ((uint32_t)-1);//UINT32_MAX;; 256 | private: 257 | pthread_key_t key_; 258 | }; 259 | 260 | WarningBuffer *get_tsi_warning_buffer(); 261 | } 262 | #endif //TBSYS_WARNING_BUFFER_H_ 263 | -------------------------------------------------------------------------------- /trunk/tbsys/src/atomic.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 | /** 17 | * Copyright (C) 2007 Doug Judd (Zvents, Inc.) 18 | * 19 | * This file is part of Hypertable. 20 | * 21 | * Hypertable is free software; you can redistribute it and/or 22 | * modify it under the terms of the GNU General Public License 23 | * as published by the Free Software Foundation; either version 2 24 | * of the License, or any later version. 25 | * 26 | * Hypertable is distributed in the hope that it will be useful, 27 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 28 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 29 | * GNU General Public License for more details. 30 | * 31 | * You should have received a copy of the GNU General Public License 32 | * along with this program; if not, write to the Free Software 33 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 34 | */ 35 | 36 | #ifndef TBSYS_ATOMIC_H 37 | #define TBSYS_ATOMIC_H 38 | 39 | /* 40 | * Atomic operations that C can't guarantee us. Useful for 41 | * resource counting etc.. 42 | */ 43 | 44 | #define LOCK "lock ; " 45 | 46 | /* 47 | * Make sure gcc doesn't try to be clever and move things around 48 | * on us. We need to use _exactly_ the address the user gave us, 49 | * not some alias that contains the same information. 50 | */ 51 | typedef struct { volatile int counter; } atomic_t; 52 | 53 | #define ATOMIC_INIT(i) { (i) } 54 | 55 | /** 56 | * atomic_read - read atomic variable 57 | * @param v pointer of type atomic_t 58 | * 59 | * Atomically reads the value of v. 60 | */ 61 | #define atomic_read(v) ((v)->counter) 62 | 63 | /** 64 | * atomic_set - set atomic variable 65 | * @param v pointer of type atomic_t 66 | * @param i required value 67 | * 68 | * Atomically sets the value of v to i. 69 | */ 70 | #define atomic_set(v,i) (((v)->counter) = (i)) 71 | 72 | /** 73 | * atomic_add - add integer to atomic variable 74 | * @param i integer value to add 75 | * @param v pointer of type atomic_t 76 | * 77 | * Atomically adds i to v. 78 | */ 79 | static __inline__ void atomic_add(int i, atomic_t *v) 80 | { 81 | __asm__ __volatile__( 82 | LOCK "addl %1,%0" 83 | :"=m" (v->counter) 84 | :"ir" (i), "m" (v->counter)); 85 | } 86 | 87 | /** 88 | * atomic_sub - subtract the atomic variable 89 | * @param i integer value to subtract 90 | * @param v pointer of type atomic_t 91 | * 92 | * Atomically subtracts i from v. 93 | */ 94 | static __inline__ void atomic_sub(int i, atomic_t *v) 95 | { 96 | __asm__ __volatile__( 97 | LOCK "subl %1,%0" 98 | :"=m" (v->counter) 99 | :"ir" (i), "m" (v->counter)); 100 | } 101 | 102 | 103 | /** 104 | * atomic_add_return - add and return 105 | * @param v pointer of type atomic_t 106 | * @param i integer value to add 107 | * 108 | * Atomically adds i to v and returns i + v 109 | */ 110 | static __inline__ int atomic_add_return(int i, atomic_t *v) 111 | { 112 | int __i; 113 | /* Modern 486+ processor */ 114 | __i = i; 115 | __asm__ __volatile__( 116 | LOCK "xaddl %0, %1" 117 | :"+r" (i), "+m" (v->counter) 118 | : : "memory"); 119 | return i + __i; 120 | } 121 | 122 | static __inline__ int atomic_sub_return(int i, atomic_t *v) 123 | { 124 | return atomic_add_return(-i,v); 125 | } 126 | 127 | 128 | /** 129 | * atomic_sub_and_test - subtract value from variable and test result 130 | * @param i integer value to subtract 131 | * @param v pointer of type atomic_t 132 | * 133 | * Atomically subtracts i from v and returns 134 | * true if the result is zero, or false for all 135 | * other cases. 136 | */ 137 | static __inline__ int atomic_sub_and_test(int i, atomic_t *v) 138 | { 139 | unsigned char c; 140 | 141 | __asm__ __volatile__( 142 | LOCK "subl %2,%0; sete %1" 143 | :"=m" (v->counter), "=qm" (c) 144 | :"ir" (i), "m" (v->counter) : "memory"); 145 | return c; 146 | } 147 | 148 | /** 149 | * atomic_inc - increment atomic variable 150 | * @param v pointer of type atomic_t 151 | * 152 | * Atomically increments v by 1. 153 | */ 154 | static __inline__ void atomic_inc(atomic_t *v) 155 | { 156 | __asm__ __volatile__( 157 | LOCK "incl %0" 158 | :"=m" (v->counter) 159 | :"m" (v->counter)); 160 | } 161 | 162 | /** 163 | * atomic_dec - decrement atomic variable 164 | * @param v pointer of type atomic_t 165 | * 166 | * Atomically decrements v by 1. 167 | */ 168 | static __inline__ void atomic_dec(atomic_t *v) 169 | { 170 | __asm__ __volatile__( 171 | LOCK "decl %0" 172 | :"=m" (v->counter) 173 | :"m" (v->counter)); 174 | } 175 | 176 | /** 177 | * atomic_dec_and_test - decrement and test 178 | * @param v pointer of type atomic_t 179 | * 180 | * Atomically decrements v by 1 and 181 | * returns true if the result is 0, or false for all other 182 | * cases. 183 | */ 184 | static __inline__ int atomic_dec_and_test(atomic_t *v) 185 | { 186 | unsigned char c; 187 | 188 | __asm__ __volatile__( 189 | LOCK "decl %0; sete %1" 190 | :"=m" (v->counter), "=qm" (c) 191 | :"m" (v->counter) : "memory"); 192 | return c != 0; 193 | } 194 | 195 | /** 196 | * atomic_inc_and_test - increment and test 197 | * @param v pointer of type atomic_t 198 | * 199 | * Atomically increments v by 1 200 | * and returns true if the result is zero, or false for all 201 | * other cases. 202 | */ 203 | static __inline__ int atomic_inc_and_test(atomic_t *v) 204 | { 205 | unsigned char c; 206 | 207 | __asm__ __volatile__( 208 | LOCK "incl %0; sete %1" 209 | :"=m" (v->counter), "=qm" (c) 210 | :"m" (v->counter) : "memory"); 211 | return c != 0; 212 | } 213 | 214 | /** 215 | * atomic_add_negative - add and test if negative 216 | * @param v pointer of type atomic_t 217 | * @param i integer value to add 218 | * 219 | * Atomically adds i to v and returns true 220 | * if the result is negative, or false when 221 | * result is greater than or equal to zero. 222 | */ 223 | static __inline__ int atomic_add_negative(int i, atomic_t *v) 224 | { 225 | unsigned char c; 226 | 227 | __asm__ __volatile__( 228 | LOCK "addl %2,%0; sets %1" 229 | :"=m" (v->counter), "=qm" (c) 230 | :"ir" (i), "m" (v->counter) : "memory"); 231 | return c; 232 | } 233 | 234 | /* These are x86-specific, used by some header files */ 235 | #define atomic_clear_mask(mask, addr) \ 236 | __asm__ __volatile__(LOCK "andl %0,%1" \ 237 | : : "r" (~(mask)),"m" (*addr) : "memory") 238 | 239 | #define atomic_set_mask(mask, addr) \ 240 | __asm__ __volatile__(LOCK "orl %0,%1" \ 241 | : : "r" (mask),"m" (*(addr)) : "memory") 242 | 243 | #define atomic_inc_return(v) (atomic_add_return(1,v)) 244 | #define atomic_dec_return(v) (atomic_sub_return(1,v)) 245 | 246 | #endif // ATOMIC_H 247 | -------------------------------------------------------------------------------- /trunk/tbsys/src/bytebuffer.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 "bytebuffer.h" 17 | 18 | using namespace tbutil; 19 | 20 | //--------------------------------------------------------- 21 | //----- exception out_of_range 22 | //--------------------------------------------------------- 23 | ByteBuffer::out_of_range::out_of_range(uint32_t p, uint32_t l, uint32_t s) 24 | { 25 | snprintf(errmsg_, MAX_ERROR_MSG_LEN, 26 | "current postion: %u, field length: %u," 27 | "out of range size %u", p, l, s); 28 | } 29 | 30 | const char* ByteBuffer::out_of_range::what() const throw() 31 | { 32 | return errmsg_; 33 | } 34 | 35 | //--------------------------------------------------------- 36 | //----- class ByteBuffer 37 | //--------------------------------------------------------- 38 | 39 | 40 | 41 | /** 42 | * Constructor use byte buffer's size 43 | * @param size 44 | * allocate data buffer only when size > 0 45 | * in this cases, ByteBuffer manage own buffer's lifecycle. 46 | */ 47 | ByteBuffer::ByteBuffer(uint32_t size) 48 | : data_(NULL), size_(size), position_(0), own_(true) 49 | { 50 | if (size_ > 0) { 51 | data_ = allocate(size_); 52 | } 53 | } 54 | 55 | ByteBuffer::ByteBuffer() 56 | : data_(NULL), size_(0), position_(0), own_(true) 57 | { 58 | } 59 | 60 | /** 61 | * Constructor use another data buffer 62 | * @param @see copy 63 | */ 64 | ByteBuffer::ByteBuffer(const char* data, uint32_t offset, uint32_t size) 65 | : data_(NULL), size_(size), position_(0), own_(true) 66 | { 67 | copy(data, offset, size); 68 | } 69 | 70 | ByteBuffer::ByteBuffer(const ByteBuffer& rhs) 71 | : data_(NULL), size_(0), position_(0), own_(true) 72 | { 73 | reset(); 74 | copy(rhs.data_, 0, rhs.size_); 75 | } 76 | 77 | ByteBuffer::~ByteBuffer() 78 | { 79 | free(); 80 | } 81 | 82 | ByteBuffer & ByteBuffer::assign(const char* data, uint32_t offset, uint32_t size) 83 | { 84 | reset(); 85 | copy(data, offset, size); 86 | return *this; 87 | } 88 | 89 | /** 90 | * Caution! in this case, ByteBuffer don't response for data_ memory, you need 91 | * handle this situation by yourself. 92 | * @param @see copy 93 | */ 94 | ByteBuffer & ByteBuffer::wrap(char* data, uint32_t offset, uint32_t size) 95 | { 96 | reset(); 97 | // must be set in here 98 | own_ = false; 99 | data_ = data + offset; 100 | size_ = size; 101 | return *this; 102 | } 103 | 104 | /** 105 | * Copy Constructor 106 | * must free before copy from another ByteBuffer 107 | */ 108 | ByteBuffer & ByteBuffer::operator=(const ByteBuffer& rhs) 109 | { 110 | if (this == &rhs) return *this; 111 | else { 112 | reset(); 113 | copy(rhs.data_, 0, rhs.size_); 114 | } 115 | return *this; 116 | } 117 | 118 | /** 119 | * copy data from buffer 120 | * @param data source buffer 121 | * @param offset copy buffer position from (data) 122 | * @param size copy buffer length from (data) 123 | */ 124 | ByteBuffer & ByteBuffer::copy(const char* data, uint32_t offset, uint32_t size) 125 | { 126 | reset(); 127 | 128 | size_ = size; 129 | if (size_ > 0) { 130 | data_ = allocate(size_); 131 | memcpy(data_, data + offset, size_); 132 | } 133 | 134 | return *this; 135 | } 136 | 137 | char* ByteBuffer::allocate(uint32_t size) const 138 | { 139 | char* data = (char*)malloc(size); 140 | assert(data); 141 | return data; 142 | } 143 | 144 | void ByteBuffer::free() 145 | { 146 | if (own_ && data_) ::free(data_); 147 | data_ = NULL; 148 | } 149 | 150 | /** 151 | * reset any of old data_ 152 | * @param 153 | * @return 154 | */ 155 | void ByteBuffer::reset() 156 | { 157 | free(); 158 | position_ = 0; 159 | size_ = 0; 160 | own_ = true; 161 | } 162 | 163 | void ByteBuffer::reset(uint32_t size) 164 | { 165 | free(); 166 | size_ = size; 167 | if (size_ > 0) { 168 | data_ = allocate(size_); 169 | } 170 | } 171 | 172 | /** 173 | * reset current position_ 174 | * @param p new position 175 | * @return old position 176 | */ 177 | uint32_t ByteBuffer::position(uint32_t p) throw (ByteBuffer::out_of_range) 178 | { 179 | if (p > size_) throw out_of_range(position_, p, size_); 180 | uint32_t oldp = position_; 181 | position_ = p; 182 | return oldp; 183 | } 184 | 185 | /** 186 | * put string in ByteBuffer, plus size of string in head. 187 | * @data NULL-terminated string 188 | * @offset #see wrap 189 | * @size #see wrap 190 | */ 191 | ByteBuffer & ByteBuffer::put(const char* src, 192 | uint32_t offset, uint32_t size) throw (ByteBuffer::out_of_range) 193 | { 194 | if (position_ + size > size_) throw out_of_range(position_, size, size_); 195 | memcpy(data_ + position_, src + offset, size); 196 | position_ += size; 197 | return *this; 198 | } 199 | 200 | ByteBuffer & ByteBuffer::putString(const std::string & v) throw (ByteBuffer::out_of_range) 201 | { 202 | //return putString(v.c_str(), 0U, v.size()); 203 | put(v.size() + 1); 204 | put(v.c_str(), 0, v.size() + 1); 205 | return *this; 206 | } 207 | 208 | ByteBuffer & ByteBuffer::getString(std::string & v) throw (ByteBuffer::out_of_range) 209 | { 210 | uint32_t size = 0; 211 | get(size); 212 | if (size > 0) { 213 | char * data = new char[size]; 214 | get(data, 0, size); 215 | v.assign(data); 216 | delete []data; 217 | } 218 | return *this; 219 | } 220 | 221 | 222 | /** 223 | * get data_ buffer directly 224 | * @param dst 225 | * @param #see wrap 226 | */ 227 | ByteBuffer & ByteBuffer::get(char* dst, 228 | uint32_t offset, uint32_t size) throw (ByteBuffer::out_of_range) 229 | { 230 | if (position_ + size > size_) throw out_of_range(position_, size, size_); 231 | memcpy(dst + offset, data_ + position_, size); 232 | position_ += size; 233 | return *this; 234 | } 235 | 236 | ByteBuffer & ByteBuffer::get(int index, char* dst, 237 | uint32_t offset, uint32_t size) throw (ByteBuffer::out_of_range) 238 | { 239 | position_ = index; 240 | return get(dst, offset, size); 241 | } 242 | 243 | 244 | /** 245 | * you need use this method very carefully. 246 | * it does not copy data_ to dst, only make dst point to right position 247 | * 248 | * @param index < 0 start from current position_ otherwise use index. 249 | * @param #see wrap 250 | */ 251 | ByteBuffer & ByteBuffer::getRef(int index, const char* &dst, 252 | uint32_t size) throw (out_of_range) 253 | { 254 | //if (own_) throw out_of_range(position_, index, size); 255 | rawData(index, dst, size); 256 | if (index < 0) position_ += size; 257 | else position_ = index + size; 258 | return *this; 259 | } 260 | 261 | const ByteBuffer & ByteBuffer::rawData(int index, const char* &dst, 262 | uint32_t size) const throw (out_of_range) 263 | { 264 | if (index < 0) index = position_; 265 | if (index + size > size_) throw out_of_range(index, size, size_); 266 | dst = data_ + index; 267 | return *this; 268 | } 269 | 270 | 271 | 272 | 273 | 274 | -------------------------------------------------------------------------------- /trunk/tbsys/src/bytebuffer.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_BYTEBUFFER_H__ 17 | #define __TBSYS_BYTEBUFFER_H__ 18 | 19 | #include "tbsys.h" 20 | 21 | namespace tbutil { 22 | /** 23 | * ByteBuffer 类似于Java里面的同名类,是一个二进制流的封装 24 | * 25 | * ByteBuffer必须预先分配好固定大小的一块缓冲,当put或get的位置超过 26 | * 初始设定的大小,会抛出 ByteBuffer::out_of_range 异常 27 | * ByteBuffer 负责管理缓冲的内存,但是如果你使用wrap方法,则内存由你 28 | * 自己管理,所以使用wrap的时候一定知道你自己必须为自己的内存负责. 29 | * 30 | * ByteBuffer 是流的形式,支持 << 和 >>操作符 31 | * put和get方法是流操作符的实现,分别是放入和取出一个特定类型的元素 32 | * 这两个方法都会导致内部的position指针移动 33 | * 34 | * peek 方法同get一样取出当前位置的元素,但是不移动position指针 35 | * 36 | */ 37 | class ByteBuffer 38 | { 39 | public: 40 | class out_of_range : public std::exception 41 | { 42 | public: 43 | out_of_range(uint32_t p, uint32_t l, uint32_t s); 44 | virtual ~out_of_range() throw() {} 45 | 46 | virtual const char* what() const throw() ; 47 | private: 48 | static const uint32_t MAX_ERROR_MSG_LEN = 256; 49 | char errmsg_[MAX_ERROR_MSG_LEN]; 50 | }; 51 | public: 52 | explicit ByteBuffer() ; 53 | explicit ByteBuffer(uint32_t size); 54 | explicit ByteBuffer(const ByteBuffer& rhs); 55 | ByteBuffer(const char* data, uint32_t offset, uint32_t size); 56 | ByteBuffer & assign(const char* data, uint32_t offset, uint32_t size); 57 | ByteBuffer & wrap(char* data, uint32_t offset, uint32_t size); 58 | ByteBuffer & operator=(const ByteBuffer& rhs); 59 | virtual ~ByteBuffer(); 60 | 61 | public: 62 | // generic put & get 63 | template ByteBuffer & put (const T & e) throw (out_of_range); 64 | template ByteBuffer & get (T & e) throw (out_of_range); 65 | template ByteBuffer & put (const std::vector & v) throw (out_of_range) ; 66 | template ByteBuffer & get (std::vector & v) throw (out_of_range); 67 | template ByteBuffer & operator<<(const T &e) throw (out_of_range) { return put(e); } 68 | template ByteBuffer & operator>>(T &e) throw (out_of_range) { return get(e); } 69 | 70 | template const ByteBuffer & peek (T & e) const throw (out_of_range); 71 | template T get () throw (out_of_range); 72 | 73 | // specialize put & get with std::string 74 | ByteBuffer & put(const std::string & e) throw (out_of_range) { return putString(e); } 75 | ByteBuffer & get(std::string & e) throw (out_of_range) { return getString(e); } 76 | 77 | 78 | ByteBuffer & putString(const std::string & v) throw (out_of_range); 79 | ByteBuffer & getString(std::string & v) throw (out_of_range); 80 | 81 | // get data_ directly.. 82 | virtual ByteBuffer & put(const char* src, uint32_t offset, uint32_t size) throw (out_of_range); 83 | virtual ByteBuffer & get(char* dst, uint32_t offset, uint32_t size) throw (out_of_range); 84 | // relative get method, from index of data_ 85 | ByteBuffer & get(int index, char* dst, uint32_t offset, uint32_t size) throw (out_of_range); 86 | // fetch data_ directly, use them very carefully 87 | ByteBuffer & getRef(int index, const char* &dst, uint32_t size) throw (out_of_range); 88 | const ByteBuffer & rawData(int index, const char* &dst, uint32_t size) const throw (out_of_range) ; 89 | 90 | template ByteBuffer & getRef(int index, T* &dst) throw (out_of_range); 91 | template ByteBuffer & getRef(int index, const T* &dst) throw (out_of_range); 92 | 93 | public: 94 | void reset(); 95 | void reset(uint32_t size); 96 | uint32_t position(uint32_t p) throw (ByteBuffer::out_of_range); 97 | uint32_t position() const { return position_; } 98 | uint32_t size() const { return size_; } 99 | int32_t remaining() const { return size_ - position_; } 100 | 101 | protected: 102 | char* allocate(uint32_t size) const; 103 | void free(); 104 | ByteBuffer & copy(const char* data, uint32_t offset, uint32_t length); 105 | 106 | protected: 107 | char* data_; 108 | uint32_t size_; 109 | uint32_t position_; 110 | bool own_; 111 | }; 112 | 113 | template 114 | ByteBuffer & ByteBuffer::put(const T & e) 115 | throw (ByteBuffer::out_of_range) 116 | { 117 | if (position_ + sizeof(T) > size_) 118 | throw out_of_range(position_, sizeof(T), size_); 119 | memcpy(data_ + position_, &e, sizeof(T)); 120 | position_ += sizeof(T); 121 | return *this; 122 | } 123 | 124 | template 125 | ByteBuffer & ByteBuffer::get(T & e) 126 | throw (ByteBuffer::out_of_range) 127 | { 128 | if (position_ + sizeof(T) > size_) 129 | throw out_of_range(position_, sizeof(T), size_); 130 | peek(e); 131 | position_ += sizeof(T); 132 | return *this; 133 | } 134 | 135 | template 136 | T ByteBuffer::get() 137 | throw (ByteBuffer::out_of_range) 138 | { 139 | T e; 140 | get(e); 141 | return e; 142 | } 143 | 144 | 145 | template 146 | const ByteBuffer & ByteBuffer::peek(T & e) const 147 | throw (ByteBuffer::out_of_range) 148 | { 149 | if (position_ + sizeof(T) > size_) 150 | throw out_of_range(position_, sizeof(T), size_); 151 | memcpy(&e, data_ + position_, sizeof(T)); 152 | return *this; 153 | } 154 | 155 | template 156 | ByteBuffer & ByteBuffer::put(const std::vector & v) 157 | throw (ByteBuffer::out_of_range) 158 | { 159 | put(v.size()); 160 | for (uint32_t i = 0; i < v.size(); ++i) 161 | { 162 | put(v[i]); 163 | } 164 | return *this; 165 | } 166 | 167 | template 168 | ByteBuffer & ByteBuffer::get(std::vector & v) 169 | throw (ByteBuffer::out_of_range) 170 | { 171 | uint32_t size; 172 | get(size); 173 | T e; 174 | for (uint32_t i = 0; i < size; ++i) 175 | { 176 | get(e); 177 | v.push_back(e); 178 | } 179 | return *this; 180 | } 181 | 182 | template 183 | ByteBuffer & ByteBuffer::getRef(int index, T* &dst) 184 | throw (out_of_range) 185 | { 186 | const char* ref = 0; 187 | getRef(index, ref, sizeof(T)); 188 | dst = (T*) ref; 189 | return *this; 190 | } 191 | 192 | template 193 | ByteBuffer & ByteBuffer::getRef(int index, const T* &dst) 194 | throw (out_of_range) 195 | { 196 | const char* ref = 0; 197 | getRef(index, ref, sizeof(T)); 198 | dst = (const T*) ref; 199 | return *this; 200 | } 201 | 202 | } // end namespace tfs 203 | 204 | #endif //__BYTEBUFFER_H__ 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | -------------------------------------------------------------------------------- /trunk/tbsys/src/config.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/config.cpp -------------------------------------------------------------------------------- /trunk/tbsys/src/config.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/config.h -------------------------------------------------------------------------------- /trunk/tbsys/src/defaultrunnable.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/defaultrunnable.cpp -------------------------------------------------------------------------------- /trunk/tbsys/src/defaultrunnable.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/defaultrunnable.h -------------------------------------------------------------------------------- /trunk/tbsys/src/filequeue.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/filequeue.cpp -------------------------------------------------------------------------------- /trunk/tbsys/src/filequeue.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/filequeue.h -------------------------------------------------------------------------------- /trunk/tbsys/src/filequeuethread.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/filequeuethread.cpp -------------------------------------------------------------------------------- /trunk/tbsys/src/filequeuethread.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/filequeuethread.h -------------------------------------------------------------------------------- /trunk/tbsys/src/fileutil.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/fileutil.cpp -------------------------------------------------------------------------------- /trunk/tbsys/src/fileutil.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/fileutil.h -------------------------------------------------------------------------------- /trunk/tbsys/src/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 | class IQueueHandler { 22 | public: 23 | virtual ~IQueueHandler() {} 24 | virtual bool handleQueue(void *data, int len, int threadIndex, void *args) = 0; 25 | }; 26 | 27 | } 28 | 29 | #endif /*TBSYS_QUEUE_HANDLER_H_*/ 30 | -------------------------------------------------------------------------------- /trunk/tbsys/src/linklist.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/linklist.h -------------------------------------------------------------------------------- /trunk/tbsys/src/process.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/process.cpp -------------------------------------------------------------------------------- /trunk/tbsys/src/process.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/process.h -------------------------------------------------------------------------------- /trunk/tbsys/src/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 | threshold = 10000; // 10ms 26 | status = 1; // default enable 27 | } 28 | 29 | void Profiler::start(const string& description) { 30 | if (entry.get() != NULL) 31 | reset(); 32 | 33 | entry.set(new Entry(description, NULL, NULL)); 34 | } 35 | 36 | void Profiler::stop() { 37 | end(); 38 | } 39 | 40 | void Profiler::reset() { 41 | if(entry.get() != NULL) { 42 | delete entry.get(); 43 | entry.set(NULL); 44 | } 45 | } 46 | 47 | void Profiler::begin(const string& description) { 48 | Entry *ce = getCurrentEntry(); 49 | if(ce != NULL) 50 | ce->doSubEntry(description); 51 | } 52 | 53 | void Profiler::end() { 54 | Entry *ce = getCurrentEntry(); 55 | if(ce != NULL) 56 | ce->release(); 57 | } 58 | 59 | long Profiler::getDuration() { 60 | return entry.get()->getDuration(); 61 | } 62 | 63 | Entry *Profiler::getCurrentEntry() { 64 | Entry *se = entry.get(); 65 | Entry *e = NULL; 66 | 67 | if (se != NULL) { 68 | do { 69 | e = se; 70 | se = e->getUnreleasedEntry(); 71 | } while (se != NULL); 72 | } 73 | 74 | return e; 75 | } 76 | 77 | void Profiler::dump() { 78 | Profiler::end(); 79 | Entry *ent = entry.get(); 80 | if (ent != NULL && ent->getDuration() >= threshold && Profiler::status == 1) 81 | TBSYS_LOG(WARN, "%s", ent->toString().c_str()); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /trunk/tbsys/src/profiler.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/profiler.h -------------------------------------------------------------------------------- /trunk/tbsys/src/queuethread.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/queuethread.cpp -------------------------------------------------------------------------------- /trunk/tbsys/src/queuethread.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/queuethread.h -------------------------------------------------------------------------------- /trunk/tbsys/src/runnable.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/runnable.h -------------------------------------------------------------------------------- /trunk/tbsys/src/stringutil.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/stringutil.cpp -------------------------------------------------------------------------------- /trunk/tbsys/src/stringutil.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/stringutil.h -------------------------------------------------------------------------------- /trunk/tbsys/src/tblockguard.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/tblockguard.h -------------------------------------------------------------------------------- /trunk/tbsys/src/tblog.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 "tblog.h" 17 | #include "WarningBuffer.h" 18 | #include 19 | #include 20 | namespace tbsys 21 | { 22 | 23 | const char * const CLogger::_errstr[] = {"ERROR","USER_ERR","WARN","INFO","TRACE","DEBUG"}; 24 | 25 | CLogger::CLogger() { 26 | _fd = fileno(stderr); 27 | _wf_fd = fileno(stderr); 28 | _level = 9; 29 | _wf_level = 2; /* WARN */ 30 | _name = NULL; 31 | _check = 0; 32 | _maxFileSize = 0; 33 | _maxFileIndex = 0; 34 | pthread_mutex_init(&_fileSizeMutex, NULL ); 35 | pthread_mutex_init(&_fileIndexMutex, NULL ); 36 | _flag = false; 37 | _wf_flag = false; 38 | } 39 | 40 | CLogger::~CLogger() { 41 | if (_name != NULL) { 42 | free(_name); 43 | _name = NULL; 44 | close(_fd); 45 | if (_wf_flag) close(_wf_fd); 46 | } 47 | pthread_mutex_destroy(&_fileSizeMutex); 48 | pthread_mutex_destroy(&_fileIndexMutex); 49 | } 50 | 51 | void CLogger::setLogLevel(const char *level, const char *wf_level) 52 | { 53 | if (level == NULL) return; 54 | int l = sizeof(_errstr)/sizeof(char*); 55 | for (int i=0; i_level) return; 120 | 121 | if (_check && _name) { 122 | checkFile(); 123 | } 124 | 125 | struct timeval tv; 126 | gettimeofday(&tv, NULL); 127 | struct tm tm; 128 | ::localtime_r((const time_t*)&tv.tv_sec, &tm); 129 | 130 | char data1[4000]; 131 | char head[128]; 132 | 133 | va_list args; 134 | va_start(args, fmt); 135 | int data_size = vsnprintf(data1, 4000, fmt, args); 136 | va_end(args); 137 | if (data_size >= 4000) 138 | { 139 | data_size = 3999; 140 | } 141 | // remove trailing '\n' 142 | while (data1[data_size-1] == '\n') data_size --; 143 | data1[data_size] = '\0'; 144 | 145 | int head_size; 146 | if (level < TBSYS_LOG_LEVEL_INFO) { 147 | head_size = snprintf(head,128,"[%04d-%02d-%02d %02d:%02d:%02d.%06ld] %-5s %s (%s:%d) [%ld] ", 148 | tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, 149 | tm.tm_hour, tm.tm_min, tm.tm_sec, tv.tv_usec, 150 | _errstr[level], function, file, line, tid); 151 | } else { 152 | head_size = snprintf(head,128,"[%04d-%02d-%02d %02d:%02d:%02d.%06ld] %-5s %s:%d [%ld] ", 153 | tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, 154 | tm.tm_hour, tm.tm_min, tm.tm_sec, tv.tv_usec, 155 | _errstr[level], file, line, tid); 156 | } 157 | struct iovec vec[3]; 158 | vec[0].iov_base = head; 159 | vec[0].iov_len = head_size; 160 | vec[1].iov_base = data1; 161 | vec[1].iov_len = data_size; 162 | vec[2].iov_base = NEWLINE; 163 | vec[2].iov_len = sizeof(NEWLINE); 164 | if (data_size > 0) 165 | { 166 | ::writev(_fd, vec, 3); 167 | if (_wf_flag && level <= _wf_level) 168 | ::writev(_wf_fd, vec, 3); 169 | } 170 | if ( _maxFileSize ){ 171 | pthread_mutex_lock(&_fileSizeMutex); 172 | off_t offset = ::lseek(_fd, 0, SEEK_END); 173 | if ( offset < 0 ){ 174 | // we got an error , ignore for now 175 | } else { 176 | if ( static_cast(offset) >= _maxFileSize ) { 177 | rotateLog(NULL); 178 | } 179 | } 180 | pthread_mutex_unlock(&_fileSizeMutex); 181 | } 182 | 183 | // write data to warning buffer for SQL 184 | if (WarningBuffer::is_warn_log_on() && data_size > 0) 185 | { 186 | if (level == TBSYS_LOG_LEVEL_WARN) 187 | { // WARN only 188 | WarningBuffer *wb = get_tsi_warning_buffer(); 189 | if (NULL != wb) 190 | { 191 | wb->append_warning(data1); 192 | } 193 | } 194 | else if (level == TBSYS_LOG_LEVEL_USER_ERROR) 195 | { 196 | WarningBuffer *wb = get_tsi_warning_buffer(); 197 | if (NULL != wb) 198 | { 199 | wb->set_err_msg(data1); 200 | } 201 | } 202 | } 203 | return; 204 | } 205 | 206 | void CLogger::rotateLog(const char *filename, const char *fmt) 207 | { 208 | if (filename == NULL && _name != NULL) 209 | { 210 | filename = _name; 211 | } 212 | char wf_filename[256]; 213 | if (filename != NULL) 214 | { 215 | snprintf(wf_filename, sizeof(wf_filename), "%s.wf", filename); 216 | } 217 | if (access(filename, R_OK) == 0) 218 | { 219 | char oldLogFile[256]; 220 | char old_wf_log_file[256]; 221 | time_t t; 222 | time(&t); 223 | struct tm tm; 224 | localtime_r((const time_t*)&t, &tm); 225 | if (fmt != NULL) 226 | { 227 | char tmptime[256]; 228 | strftime(tmptime, sizeof(tmptime), fmt, &tm); 229 | sprintf(oldLogFile, "%s.%s", filename, tmptime); 230 | snprintf(old_wf_log_file, sizeof(old_wf_log_file), "%s.%s", wf_filename, tmptime); 231 | } 232 | else 233 | { 234 | sprintf(oldLogFile, "%s.%04d%02d%02d%02d%02d%02d", 235 | filename, tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, 236 | tm.tm_hour, tm.tm_min, tm.tm_sec); 237 | snprintf(old_wf_log_file, sizeof(old_wf_log_file), "%s.%04d%02d%02d%02d%02d%02d", 238 | wf_filename, tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, 239 | tm.tm_hour, tm.tm_min, tm.tm_sec); 240 | } 241 | if ( _maxFileIndex > 0 ) 242 | { 243 | pthread_mutex_lock(&_fileIndexMutex); 244 | if ( _fileList.size() >= _maxFileIndex ) 245 | { 246 | std::string oldFile = _fileList.front(); 247 | _fileList.pop_front(); 248 | unlink( oldFile.c_str()); 249 | } 250 | _fileList.push_back(oldLogFile); 251 | pthread_mutex_unlock(&_fileIndexMutex); 252 | } 253 | rename(filename, oldLogFile); 254 | if (_wf_flag && _maxFileIndex > 0) 255 | { 256 | pthread_mutex_lock(&_fileIndexMutex); 257 | if (_wf_file_list.size() >= _maxFileIndex) 258 | { 259 | std::string old_wf_file = _wf_file_list.front(); 260 | _wf_file_list.pop_front(); 261 | unlink(old_wf_file.c_str()); 262 | } 263 | _wf_file_list.push_back(old_wf_log_file); 264 | pthread_mutex_unlock(&_fileIndexMutex); 265 | } 266 | rename(wf_filename, old_wf_log_file); 267 | } 268 | int fd = open(filename, O_RDWR | O_CREAT | O_APPEND | O_LARGEFILE, LOG_FILE_MODE); 269 | if (!_flag) 270 | { 271 | dup2(fd, _fd); 272 | dup2(fd, 1); 273 | if (_fd != 2) dup2(fd, 2); 274 | close(fd); 275 | } 276 | else 277 | { 278 | if (_fd != 2) 279 | { 280 | close(_fd); 281 | } 282 | _fd = fd; 283 | } 284 | if (_wf_flag) 285 | { 286 | fd = open(wf_filename, O_RDWR | O_CREAT | O_APPEND | O_LARGEFILE, LOG_FILE_MODE); 287 | if (_wf_fd != 2) 288 | { 289 | close(_wf_fd); 290 | } 291 | _wf_fd = fd; 292 | } 293 | } 294 | 295 | void CLogger::checkFile() 296 | { 297 | struct stat stFile; 298 | struct stat stFd; 299 | 300 | fstat(_fd, &stFd); 301 | int err = stat(_name, &stFile); 302 | if ((err == -1 && errno == ENOENT) 303 | || (err == 0 && (stFile.st_dev != stFd.st_dev || stFile.st_ino != stFd.st_ino))) { 304 | int fd = open(_name, O_RDWR | O_CREAT | O_APPEND | O_LARGEFILE, LOG_FILE_MODE); 305 | if (!_flag) 306 | { 307 | dup2(fd, _fd); 308 | dup2(fd, 1); 309 | if (_fd != 2) dup2(fd, 2); 310 | close(fd); 311 | } 312 | else 313 | { 314 | if (_fd != 2) 315 | { 316 | close(_fd); 317 | } 318 | _fd = fd; 319 | } 320 | } 321 | } 322 | 323 | CLogger::CLogger& CLogger::getLogger() 324 | { 325 | static CLogger logger; 326 | return logger; 327 | } 328 | 329 | void CLogger::setMaxFileSize( int64_t maxFileSize) 330 | { 331 | // 1GB 332 | if ( maxFileSize < 0x0 || maxFileSize > 0x40000000){ 333 | maxFileSize = 0x40000000;//1GB 334 | } 335 | _maxFileSize = maxFileSize; 336 | } 337 | 338 | void CLogger::setMaxFileIndex( int maxFileIndex ) 339 | { 340 | if ( maxFileIndex < 0x00 ) { 341 | maxFileIndex = 0x0F; 342 | } 343 | if ( maxFileIndex > 0x400 ) {//1024 344 | maxFileIndex = 0x400;//1024 345 | } 346 | _maxFileIndex = maxFileIndex; 347 | } 348 | } 349 | 350 | ///////////// 351 | -------------------------------------------------------------------------------- /trunk/tbsys/src/tblog.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_LOG_H 17 | #define TBSYS_LOG_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 | #define TBSYS_LOG_LEVEL_ERROR 0 35 | #define TBSYS_LOG_LEVEL_USER_ERROR 1 36 | #define TBSYS_LOG_LEVEL_WARN 2 37 | #define TBSYS_LOG_LEVEL_INFO 3 38 | #define TBSYS_LOG_LEVEL_TRACE 4 39 | #define TBSYS_LOG_LEVEL_DEBUG 5 40 | #define TBSYS_LOG_LEVEL(level) TBSYS_LOG_LEVEL_##level, __FILE__, __LINE__, __FUNCTION__, pthread_self() 41 | #define TBSYS_LOG_NUM_LEVEL(level) level, __FILE__, __LINE__, __FUNCTION__, pthread_self() 42 | #define TBSYS_LOGGER tbsys::CLogger::getLogger() 43 | #define TBSYS_PRINT(level, ...) TBSYS_LOGGER.logMessage(TBSYS_LOG_LEVEL(level), __VA_ARGS__) 44 | #define TBSYS_LOG_BASE(level, ...) (TBSYS_LOG_LEVEL_##level>TBSYS_LOGGER._level) ? (void)0 : TBSYS_PRINT(level, __VA_ARGS__) 45 | #define TBSYS_LOG(level, _fmt_, args...) ((TBSYS_LOG_LEVEL_##level>TBSYS_LOGGER._level) ? (void)0 : TBSYS_LOG_BASE(level,_fmt_, ##args)) 46 | #define TBSYS_LOG_US(level, _fmt_, args...) \ 47 | ((TBSYS_LOG_LEVEL_##level>TBSYS_LOGGER._level) ? (void)0 : TBSYS_LOG_BASE(level, "[%ld][%ld][%ld] " _fmt_, \ 48 | pthread_self(), tbsys::CLogger::get_cur_tv().tv_sec, \ 49 | tbsys::CLogger::get_cur_tv().tv_usec, ##args)) 50 | 51 | namespace tbsys { 52 | using std::deque; 53 | using std::string; 54 | 55 | /** 56 | * @brief ¼òµ¥µÄÈÕ־ϵͳ 57 | */ 58 | class CLogger { 59 | public: 60 | 61 | static const mode_t LOG_FILE_MODE = 0644; 62 | CLogger(); 63 | ~CLogger(); 64 | /** 65 | * @brief 66 | * 67 | * @param filename 68 | * @param fmt 69 | */ 70 | void rotateLog(const char *filename, const char *fmt = NULL); 71 | /** 72 | * @brief ½«ÈÕÖ¾ÄÚÈÝдÈëÎļþ 73 | * 74 | * @param level ÈÕÖ¾µÄ¼¶±ð 75 | * @param file ÈÕÖ¾ÄÚÈÝËùÔÚµÄÎļþ 76 | * @param line ÈÕÖ¾ÄÚÈÝËùÔÚµÄÎļþµÄÐкŠ77 | * @param function дÈëÈÕÖ¾ÄÚÈݵĺ¯ÊýÃû³Æ 78 | * @param fmt 79 | * @param ... 80 | */ 81 | void logMessage(int level, const char *file, int line, const char *function, pthread_t tid, const char *fmt, ...) __attribute__ ((format (printf, 7, 8))); 82 | /** 83 | * @brief set log putout level 84 | * 85 | * @param level DEBUG|WARN|INFO|TRACE|ERROR 86 | * 87 | * @param wf_level set the level putout to wf log file 88 | */ 89 | void setLogLevel(const char *level, const char *wf_level = NULL); 90 | /** 91 | * @brief set log file name 92 | * 93 | * @param filename log file name 94 | * 95 | * @param flag whether to redirect stdout to log file, if false, redirect it 96 | * 97 | * @param open_wf whether to open wf log file, default close 98 | */ 99 | void setFileName(const char *filename, bool flag = false, bool open_wf = false); 100 | /** 101 | * @brief ¼ì²âÎļþÊÇ·ñÒѾ­´ò¿ª,±ê×¼Êä³ö,´íÎóÊä³öÖØ¶¨Ïò 102 | */ 103 | void checkFile(); 104 | void setCheck(int v) {_check = v;} 105 | /** 106 | * @brief ÉèÖÃÈÕÖ¾ÎļþÎļþµÄ´óС,´ïµ½maxFileSize¾Íдò¿ªÒ»¸öÎļþ 107 | * Èç¹û²»ÉèÖôËÏÈÕ־ϵͳ»áºöÂÔÈÕÖ¾¹ö¶¯ 108 | * 109 | * @param maxFileSize ÈÕÖ¾ÎļþµÄ´óС 110 | */ 111 | void setMaxFileSize( int64_t maxFileSize=0x40000000); 112 | /** 113 | * @brief ±£Áô×î½ümaxFileIndex¸öÈÕÖ¾Îļþ£¬³¬³ömaxFileIndex¸öÈÕÖ¾Îļþ 114 | * »á°´Ê±¼äÏȺóɾ³ý,µ«½ø³ÌÖØÆôºóÈÕ־ϵͳ»á°´Ê±¼äÏȺóÖØÐÂͳ¼Æ 115 | * 116 | * @param maxFileIndex ±£ÁôÎļþµÄ×î´ó¸öÊý 117 | */ 118 | void setMaxFileIndex( int maxFileIndex= 0x0F); 119 | 120 | static inline struct timeval get_cur_tv() 121 | { 122 | struct timeval tv; 123 | gettimeofday(&tv, NULL); 124 | return tv; 125 | }; 126 | 127 | static CLogger& getLogger(); 128 | 129 | private: 130 | int _fd; 131 | int _wf_fd; 132 | char *_name; 133 | int _check; 134 | size_t _maxFileIndex; 135 | int64_t _maxFileSize; 136 | bool _flag; 137 | bool _wf_flag; 138 | 139 | public: 140 | int _level; 141 | int _wf_level; 142 | 143 | private: 144 | std::deque _fileList; 145 | std::deque _wf_file_list; 146 | static const char *const _errstr[]; 147 | pthread_mutex_t _fileSizeMutex; 148 | pthread_mutex_t _fileIndexMutex; 149 | }; 150 | 151 | } 152 | #endif 153 | -------------------------------------------------------------------------------- /trunk/tbsys/src/tbnetutil.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/tbnetutil.cpp -------------------------------------------------------------------------------- /trunk/tbsys/src/tbnetutil.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/tbnetutil.h -------------------------------------------------------------------------------- /trunk/tbsys/src/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 | -------------------------------------------------------------------------------- /trunk/tbsys/src/tbrwlock.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/tbrwlock.h -------------------------------------------------------------------------------- /trunk/tbsys/src/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 | 35 | namespace tbsys { 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< Byte> ByteSeq; 91 | 92 | typedef ::std::vector< Short> ShortSeq; 93 | 94 | typedef ::std::vector< Int> IntSeq; 95 | 96 | typedef ::std::vector< Long> LongSeq; 97 | 98 | typedef ::std::vector< Float> FloatSeq; 99 | 100 | typedef ::std::vector< Double> 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 | #include "atomic.h" 111 | #include "config.h" 112 | #include "fileutil.h" 113 | #include "stringutil.h" 114 | #include "tbnetutil.h" 115 | #include "tbtimeutil.h" 116 | #include "process.h" 117 | #include "tblog.h" 118 | #include "WarningBuffer.h" 119 | #include "tbrwlock.h" 120 | 121 | #include "runnable.h" 122 | #include "iqueuehandler.h" 123 | #include "defaultrunnable.h" 124 | #include "thread.h" 125 | #include "threadmutex.h" 126 | #include "threadcond.h" 127 | 128 | #include "queuethread.h" 129 | #include "filequeue.h" 130 | #include "filequeuethread.h" 131 | #include "profiler.h" 132 | #include "bytebuffer.h" 133 | 134 | #endif 135 | 136 | -------------------------------------------------------------------------------- /trunk/tbsys/src/tbtimeutil.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/tbtimeutil.cpp -------------------------------------------------------------------------------- /trunk/tbsys/src/tbtimeutil.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/tbtimeutil.h -------------------------------------------------------------------------------- /trunk/tbsys/src/thread.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/thread.h -------------------------------------------------------------------------------- /trunk/tbsys/src/threadcond.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/threadcond.h -------------------------------------------------------------------------------- /trunk/tbsys/src/threadmutex.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/src/threadmutex.h -------------------------------------------------------------------------------- /trunk/tbsys/test/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS=-I$(top_srcdir)/src 2 | LDADD=$(top_srcdir)/src/.libs/libtbsys.a 3 | AM_LDFLAGS="-lrt -lm -lpthread" 4 | 5 | noinst_PROGRAMS=testfilequeue testqueuethread testconfig \ 6 | teststringutil testnetutil testlog \ 7 | testfileutil testtimeutil testthread\ 8 | testtimer testthreadpool testService \ 9 | testwarningbuffer 10 | 11 | testfilequeue_SOURCES=testfilequeue.cpp 12 | testqueuethread_SOURCES=testqueuethread.cpp 13 | testconfig_SOURCES=testconfig.cpp 14 | teststringutil_SOURCES=teststringutil.cpp 15 | testnetutil_SOURCES=testnetutil.cpp 16 | testlog_SOURCES=testlog.cpp 17 | testfileutil_SOURCES=testfileutil.cpp 18 | testtimeutil_SOURCES=testtimeutil.cpp 19 | testthread_SOURCES=testBase.cpp testthread.cpp 20 | testtimer_SOURCES=testBase.cpp testTimer.cpp 21 | testthreadpool_SOURCES=testBase.cpp testThreadPool.cpp 22 | testService_SOURCES=testBase.cpp testService.cpp 23 | testwarningbuffer_SOURCES=testwarningbuffer.cpp 24 | -------------------------------------------------------------------------------- /trunk/tbsys/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 | 22 | testFailed::testFailed(const std::string& name ): 23 | _name( name) 24 | { 25 | 26 | } 27 | 28 | testBase::testBase(const string& name): 29 | _name( name ) 30 | { 31 | 32 | } 33 | 34 | std::string testBase::name() const 35 | { 36 | return _name; 37 | } 38 | 39 | void testBase::start() 40 | { 41 | cout<<"running "<<_name< 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 | -------------------------------------------------------------------------------- /trunk/tbsys/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< 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: 43 | printf("SIGUSR1\n"); 44 | break; 45 | case SIGPIPE: 46 | printf("SIGPIPE\n"); 47 | break; 48 | case SIGTERM: 49 | printf("SIGTERM\n"); 50 | break; 51 | case SIGINT: 52 | printf("SIGINT\n"); 53 | break; 54 | case SIGSEGV: 55 | printf("SIGSEGV\n"); 56 | break; 57 | case SIGABRT: 58 | printf("SIGABRT\n"); 59 | break; 60 | case 40: 61 | printf("40\n"); 62 | case SIGHUP: 63 | printf("SIGHUP\n"); 64 | break; 65 | } 66 | return 0; 67 | } 68 | virtual bool destroy() 69 | { 70 | return true; 71 | } 72 | }; 73 | 74 | int main(int argc, char* argv[]) 75 | { 76 | testService app; 77 | app.main(argc, argv); 78 | return 0; 79 | } 80 | 81 | -------------------------------------------------------------------------------- /trunk/tbsys/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: "<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 | -------------------------------------------------------------------------------- /trunk/tbsys/test/testTimer.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 "testCommon.h" 18 | #include 19 | 20 | using namespace tbutil; 21 | using namespace tbutil; 22 | using namespace std; 23 | 24 | class TestTask : public TimerTask, Monitor 25 | { 26 | public: 27 | 28 | TestTask() : _count(0) 29 | { 30 | } 31 | 32 | TestTask(const tbutil::Time& scheduledTime) : 33 | _scheduledTime(scheduledTime), 34 | _count(0) 35 | { 36 | } 37 | 38 | virtual void 39 | runTimerTask() 40 | { 41 | Lock sync(*this); 42 | ++_count; 43 | _run = tbutil::Time::now(tbutil::Time::Monotonic); 44 | //cerr << "run: " << _scheduledTime.toMilliSeconds() << " " << _run.toMilliSeconds() << endl; 45 | notifyAll(); 46 | } 47 | 48 | virtual bool 49 | operator<(const TestTask& r) const 50 | { 51 | return _scheduledTime < r._scheduledTime; 52 | } 53 | 54 | virtual bool 55 | hasRun() const 56 | { 57 | Lock sync(*this); 58 | return _run != tbutil::Time(); 59 | } 60 | 61 | int 62 | getCount() const 63 | { 64 | Lock sync(*this); 65 | return _count; 66 | } 67 | 68 | virtual tbutil::Time 69 | getRunTime() const 70 | { 71 | Lock sync(*this); 72 | return _run; 73 | } 74 | 75 | tbutil::Time 76 | getScheduledTime() const 77 | { 78 | return _scheduledTime; 79 | } 80 | 81 | virtual void 82 | waitForRun() 83 | { 84 | Lock sync(*this); 85 | while(_run == tbutil::Time()) 86 | { 87 | if(!timedWait(tbutil::Time::seconds(10))) 88 | { 89 | test(false); // Timeout. 90 | } 91 | } 92 | } 93 | 94 | void 95 | clear() 96 | { 97 | _run = tbutil::Time(); 98 | _count = 0; 99 | } 100 | 101 | private: 102 | 103 | tbutil::Time _run; 104 | tbutil::Time _scheduledTime; 105 | int _count; 106 | }; 107 | typedef tbutil::Handle TestTaskPtr; 108 | 109 | 110 | class DestroyTask : public TimerTask, Monitor 111 | { 112 | public: 113 | 114 | DestroyTask(const tbutil::TimerPtr& timer) : 115 | _timer(timer), 116 | _run(false) 117 | { 118 | } 119 | 120 | virtual void 121 | runTimerTask() 122 | { 123 | Lock sync(*this); 124 | _timer->destroy(); 125 | _run = true; 126 | notify(); 127 | } 128 | 129 | virtual void 130 | waitForRun() 131 | { 132 | Lock sync(*this); 133 | while(!_run) 134 | { 135 | if(!timedWait(tbutil::Time::seconds(10))) 136 | { 137 | test(false); // Timeout. 138 | } 139 | } 140 | } 141 | 142 | private: 143 | 144 | TimerPtr _timer; 145 | bool _run; 146 | }; 147 | typedef Handle DestroyTaskPtr; 148 | 149 | int main(int argc, char* argv[]) 150 | { 151 | tbutil::Time t = tbutil::Time::now(); 152 | cout<<" time string : "<schedule(task, tbutil::Time()); 159 | task->waitForRun(); 160 | task->clear(); 161 | while(true) 162 | { 163 | try 164 | { 165 | timer->schedule(task, tbutil::Time::milliSeconds(-10)); 166 | timer->schedule(task, tbutil::Time()); 167 | } 168 | catch(const tbutil::IllegalArgumentException&) 169 | { 170 | break; 171 | } 172 | task->waitForRun(); 173 | task->clear(); 174 | } 175 | } 176 | 177 | { 178 | TestTaskPtr task = new TestTask(); 179 | test(!timer->cancel(task)); 180 | timer->schedule(task, tbutil::Time::seconds(1)); 181 | test(!task->hasRun() && timer->cancel(task) && !task->hasRun()); 182 | test(!timer->cancel(task)); 183 | Thread::ssleep(tbutil::Time::milliSeconds(1100)); 184 | test(!task->hasRun()); 185 | } 186 | 187 | { 188 | vector tasks; 189 | tbutil::Time start = Time::now(Time::Monotonic) + Time::milliSeconds(500); 190 | for(int i = 0; i < 20; ++i) 191 | { 192 | tasks.push_back(new TestTask(Time::milliSeconds(500 + i * 5))); 193 | } 194 | 195 | random_shuffle(tasks.begin(), tasks.end()); 196 | vector::const_iterator p; 197 | for(p = tasks.begin(); p != tasks.end(); ++p) 198 | { 199 | timer->schedule(*p, (*p)->getScheduledTime()); 200 | } 201 | 202 | for(p = tasks.begin(); p != tasks.end(); ++p) 203 | { 204 | (*p)->waitForRun(); 205 | } 206 | 207 | test(Time::now(Time::Monotonic) > start); 208 | 209 | sort(tasks.begin(), tasks.end()); 210 | for(p = tasks.begin(); p + 1 != tasks.end(); ++p) 211 | { 212 | if((*p)->getRunTime() > (*(p + 1))->getRunTime()) 213 | { 214 | test(false); 215 | } 216 | } 217 | } 218 | 219 | { 220 | TestTaskPtr task = new TestTask(); 221 | timer->scheduleRepeated(task, tbutil::Time::milliSeconds(20)); 222 | Thread::ssleep(Time::milliSeconds(500)); 223 | test(task->hasRun()); 224 | test(task->getCount() > 1); 225 | test(task->getCount() < 26); 226 | test(timer->cancel(task)); 227 | int count = task->getCount(); 228 | Thread::ssleep(Time::milliSeconds(100)); 229 | test(count == task->getCount() || count + 1 == task->getCount()); 230 | } 231 | 232 | timer->destroy(); 233 | timer = 0; 234 | } 235 | cout << "ok" << endl; 236 | 237 | cout << "testing timer destroy... " << endl; 238 | { 239 | { 240 | TimerPtr timer = new Timer(); 241 | TestTaskPtr testTask = new TestTask(); 242 | //timer->schedule(testTask, Time()); 243 | //timer->destroy(); 244 | try 245 | { 246 | timer->schedule(testTask, Time()); 247 | } 248 | catch(const IllegalArgumentException& e ) 249 | { 250 | cout<< e < 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 | fprintf(stderr, "%s filename\n", argv[0]); 25 | return 1; 26 | } 27 | 28 | if (TBSYS_CONFIG.load(argv[1])) { 29 | fprintf(stderr, "load config failure: %s\n", argv[1]); 30 | } 31 | 32 | fprintf(stderr, "string=%s\n", TBSYS_CONFIG.getString("test_section", "string")); 33 | fprintf(stderr, "int=%d\n", TBSYS_CONFIG.getInt("test_section", "int")); 34 | 35 | vector strList = TBSYS_CONFIG.getStringList("test_section", "stringlist"); 36 | for(int i=0; i<(int)strList.size(); i++) { 37 | fprintf(stderr, "string%d=%s\n", i+1, strList[i]); 38 | } 39 | 40 | vector intList = TBSYS_CONFIG.getIntList("test_section", "intlist"); 41 | for(int i=0; i<(int)intList.size(); i++) { 42 | fprintf(stderr, "int%d=%d\n", i+1, intList[i]); 43 | } 44 | 45 | // getSectionKey(char *section, vector &keys) 46 | vector keys; 47 | TBSYS_CONFIG.getSectionKey("test_section", keys); 48 | for(uint32_t i=0; i 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 | mQueueThread->stop(); 33 | mQueueThread = NULL; 34 | } 35 | return 0; 36 | } 37 | }; 38 | 39 | int main(int argc, char *argv[]) 40 | { 41 | atomic_set(&mReadCount, 0); 42 | char testqueue[64]; 43 | 44 | if (argc>1) { 45 | mWriteCount = atoi(argv[1]); 46 | } 47 | sprintf(testqueue, "q_%d_%d", getpid(), rand()); 48 | CFileQueue queue("/tmp/queue", testqueue); 49 | CMyHandler handler; 50 | CFileQueueThread queueThread(&queue, 3, &handler, NULL); 51 | mQueueThread = &queueThread; 52 | queueThread.start(); 53 | char data[1024]; 54 | for(int i=1; i<=mWriteCount; i++) { 55 | int len = sprintf(data, "data_%05d", i); 56 | queueThread.writeData(data, len+1); 57 | //printf("TEST==> writeData: %d, (%s)\n", i, data); 58 | fflush(stdout); 59 | //if (rand() % 111 == 0) { 60 | //usleep(100000); 61 | //} 62 | } 63 | queueThread.wait(); 64 | printf("mReadCount: %d\n", atomic_read(&mReadCount)); 65 | printf("OK\n"); 66 | return 0; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /trunk/tbsys/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 | -------------------------------------------------------------------------------- /trunk/tbsys/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 | TBSYS_LOG(ERROR, "xxx: %s:%d", "xxxx", i); 30 | TBSYS_LOG(WARN, "xxx: %s:%d", "xxxx", i); 31 | TBSYS_LOG(INFO, "xxx: %s:%d", "xxxx", i); 32 | TBSYS_LOG(DEBUG, "xxx: %s:%d", "xxxx", i); 33 | //getchar(); 34 | } 35 | //test rotateLog() 36 | CLogger logger; 37 | logger.setFileName("/tmp/test.log", false, true); 38 | logger.setLogLevel("INFO"); 39 | logger.setMaxFileIndex(100); 40 | for (int i = 0; i < 10; i++) 41 | { 42 | for (int j = 0; j < 50; j++) 43 | { 44 | logger.logMessage(TBSYS_LOG_LEVEL_ERROR, __FILE__, __LINE__, __FUNCTION__, 45 | pthread_self(), "test rotateLog(): %d", j); 46 | } 47 | logger.rotateLog(NULL); 48 | sleep(2); 49 | } 50 | 51 | return 0; 52 | } 53 | 54 | -------------------------------------------------------------------------------- /trunk/tbsys/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); m.insert(x); 46 | x = CNetUtil::strToAddr("192.168.207.12", port); m.insert(x); 47 | x = CNetUtil::strToAddr("192.168.207.12", port+1); m.insert(x); 48 | x = CNetUtil::strToAddr("192.168.207.12", port-1); m.insert(x); 49 | x = CNetUtil::strToAddr("92.168.207.191", port); m.insert(x); 50 | x = CNetUtil::strToAddr("172.168.207.192", port); m.insert(x); 51 | x = CNetUtil::strToAddr("172.168.207.12", port); m.insert(x); 52 | x = CNetUtil::strToAddr("172.169.207.12", port); m.insert(x); 53 | x = CNetUtil::strToAddr("172.168.207.13", port); m.insert(x); 54 | x = CNetUtil::strToAddr("182.168.207.11", port); m.insert(x); 55 | x = CNetUtil::strToAddr("182.168.207.12", port); m.insert(x); 56 | x = CNetUtil::strToAddr("182.169.207.12", port); m.insert(x); 57 | x = CNetUtil::strToAddr("182.168.207.13", port); m.insert(x); 58 | set::iterator it; 59 | for(it=m.begin(); it!=m.end(); ++it) { 60 | fprintf(stderr, "%s\n", CNetUtil::addrToString(*it).c_str()); 61 | } 62 | } 63 | 64 | 65 | int main(int argc, char *argv[]) 66 | { 67 | //test1(); 68 | char *ip = "192.168.207.158:2089"; 69 | int port = 2071; 70 | uint32_t ipx = CNetUtil::getLocalAddr(NULL); 71 | unsigned char *bytes = (unsigned char *) &ipx; 72 | ipx<<=8; 73 | int index = 1; 74 | while(ipx!=0) { 75 | fprintf(stderr, "ip: "); 76 | for(int i=index; i<4; i++) fprintf(stderr, "%d.", bytes[i]); 77 | fprintf(stderr, "\n"); 78 | ipx<<=8; 79 | index++; 80 | } 81 | _UUID_HostIp = ipx; 82 | uint32_t ipx1 = CNetUtil::getAddr("192.168.207.157"); 83 | fprintf(stderr, "ipx: %X, ipx1: %X\n", ipx, ipx1); 84 | uint64_t uuid; 85 | for(int i=0; i<10; i++) { 86 | uuid = newUUID(); 87 | fprintf(stderr, "uuid: %llu, %llX\n", uuid, uuid); 88 | } 89 | 90 | uint64_t x = CNetUtil::strToAddr(ip, port); 91 | uint64_t x1 = CNetUtil::ipToAddr(ipx, port); 92 | 93 | fprintf(stderr, "x: %llu, %llu %s\n", x, x1, CNetUtil::addrToString(x).c_str()); 94 | 95 | return 0; 96 | } 97 | 98 | -------------------------------------------------------------------------------- /trunk/tbsys/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 | mQueueThread->stop(); 33 | mQueueThread = NULL; 34 | } 35 | return 0; 36 | } 37 | }; 38 | 39 | int main(int argc, char *argv[]) 40 | { 41 | if (argc>1) { 42 | mWriteCount = atoi(argv[1]); 43 | } 44 | CMyHandler handler; 45 | CQueueThread queueThread(3, &handler, NULL); 46 | mQueueThread = &queueThread; 47 | queueThread.start(); 48 | char data[1024]; 49 | for(int i=1; i<=mWriteCount; i++) { 50 | int len = sprintf(data, "data_%05d", i); 51 | queueThread.writeData(data, len+1); 52 | // printf("TEST==> writeData: %d, (%s)\n", i, data); 53 | // fflush(stdout); 54 | //if (rand() % 111 == 0) { 55 | //usleep(100000); 56 | //} 57 | } 58 | queueThread.wait(); 59 | 60 | printf("mReadCount: %d\n", atomic_read(&mReadCount)); 61 | printf("OK\n"); 62 | 63 | return 0; 64 | } 65 | 66 | -------------------------------------------------------------------------------- /trunk/tbsys/test/teststringutil.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kayaklee/tb-common-util/55d59a19d8f4fa49754f7df33e6571bc364b8cfd/trunk/tbsys/test/teststringutil.cpp -------------------------------------------------------------------------------- /trunk/tbsys/test/testthread.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 | #include 22 | #include 23 | #include 24 | #include "testBase.h" 25 | #include "testCommon.h" 26 | #include 27 | #include "testCommon.h" 28 | 29 | using namespace std; 30 | using namespace tbutil; 31 | static const string testName1("thread alive"); 32 | 33 | class CondVar : public Monitor 34 | { 35 | public: 36 | CondVar(): 37 | _done( false) 38 | { 39 | 40 | } 41 | 42 | void waitForSignal() 43 | { 44 | Monitor::Lock sync(*this); 45 | while( !_done ) 46 | { 47 | wait(); 48 | } 49 | } 50 | void signal() 51 | { 52 | Monitor::Lock sync(*this); 53 | _done = true; 54 | notify(); 55 | } 56 | private: 57 | bool _done; 58 | }; 59 | 60 | class AliveTestThread : public Thread 61 | { 62 | public: 63 | AliveTestThread(CondVar& childCreated, CondVar& parentReady ): 64 | _childCreated(childCreated), 65 | _parentReady(parentReady) 66 | { 67 | 68 | } 69 | virtual void run() 70 | { 71 | try 72 | { 73 | _childCreated.signal(); 74 | _parentReady.waitForSignal(); 75 | } 76 | catch( Exception& e ) 77 | { 78 | 79 | } 80 | } 81 | private: 82 | CondVar& _childCreated; 83 | CondVar& _parentReady; 84 | }; 85 | 86 | typedef Handle AliveTestThreadPtr; 87 | 88 | class AliveTest : public testBase 89 | { 90 | public: 91 | AliveTest(): 92 | testBase(testName1) 93 | { 94 | 95 | } 96 | 97 | virtual void run() 98 | { 99 | CondVar childCreated; 100 | CondVar parentReady; 101 | AliveTestThreadPtr t = new AliveTestThread(childCreated, parentReady); 102 | t->start(); 103 | childCreated.waitForSignal(); 104 | test(t->isAlive()); 105 | parentReady.signal(); 106 | t->join(); 107 | test(!t->isAlive()); 108 | } 109 | }; 110 | 111 | class MonitorMutexTestThread: public Thread 112 | { 113 | public: 114 | MonitorMutexTestThread( Monitor& m ): 115 | _monitor( m ), 116 | _tryLock( false ) 117 | { 118 | 119 | } 120 | 121 | virtual void run() 122 | { 123 | Monitor::TryLock trylock(_monitor); 124 | test(!trylock.acquired() ); 125 | { 126 | Mutex::Lock lock(_tryLockMutex); 127 | _tryLock = true; 128 | } 129 | _tryLockCond.signal(); 130 | Monitor::Lock lock(_monitor); 131 | } 132 | 133 | void waitTryLock() 134 | { 135 | Mutex::Lock lock(_tryLockMutex); 136 | while( !_tryLock) 137 | { 138 | _tryLockCond.wait(lock); 139 | } 140 | } 141 | 142 | Monitor& _monitor; 143 | bool _tryLock; 144 | 145 | Cond _tryLockCond; 146 | Mutex _tryLockMutex; 147 | }; 148 | 149 | typedef Handle MonitorMutexTestThreadPtr; 150 | 151 | class MonitorMutexTestThread2 : public Thread 152 | { 153 | public: 154 | MonitorMutexTestThread2(Monitor&m): 155 | _finished( false), 156 | _monitor(m) 157 | { 158 | 159 | } 160 | virtual void run() 161 | { 162 | Monitor::Lock lock(_monitor ); 163 | _monitor.wait(); 164 | _finished = true; 165 | } 166 | 167 | bool _finished; 168 | Monitor& _monitor; 169 | }; 170 | 171 | typedef Handle MonitorMutexTestThread2Ptr; 172 | 173 | 174 | static const string monitorName("Monitor"); 175 | 176 | class MonitorMutxTest : public testBase 177 | { 178 | public: 179 | MonitorMutxTest() : 180 | testBase(monitorName) 181 | { 182 | 183 | } 184 | 185 | void run(); 186 | }; 187 | 188 | void MonitorMutxTest::run() 189 | { 190 | Monitor monitor; 191 | MonitorMutexTestThreadPtr t1; 192 | MonitorMutexTestThread2Ptr t2; 193 | MonitorMutexTestThread2Ptr t3; 194 | 195 | { 196 | Monitor::Lock lock(monitor); 197 | try 198 | { 199 | Monitor::TryLock tlock(monitor); 200 | test(!tlock.acquired()); 201 | } 202 | catch( const ThreadLockedException& e ) 203 | { 204 | cout<<"thread locked Execption: "<start(); 208 | t1->waitTryLock(); 209 | } 210 | t1->join(); 211 | 212 | // test notify() 213 | t2 = new MonitorMutexTestThread2(monitor); 214 | t2->start(); 215 | t3 = new MonitorMutexTestThread2(monitor); 216 | t3->start(); 217 | 218 | Thread::ssleep(Time::seconds(1)); 219 | 220 | { 221 | Monitor::Lock lock(monitor); 222 | monitor.notify(); 223 | } 224 | 225 | Thread::ssleep(Time::seconds(1)); 226 | 227 | test((t2->_finished && !t3->_finished ) 228 | || (t3->_finished && !t2->_finished)); 229 | 230 | { 231 | Monitor::Lock lock(monitor); 232 | monitor.notify(); 233 | } 234 | 235 | t2->join(); 236 | t3->join(); 237 | 238 | Thread::ssleep(Time::seconds(1)); 239 | 240 | 241 | //test notifyAll() 242 | t2 = new MonitorMutexTestThread2(monitor); 243 | t2->start(); 244 | t3 = new MonitorMutexTestThread2(monitor); 245 | t3->start(); 246 | 247 | Thread::ssleep(Time::seconds(1)); 248 | 249 | { 250 | Monitor::Lock lock(monitor); 251 | monitor.notifyAll(); 252 | } 253 | 254 | Thread::ssleep(Time::seconds(1)); 255 | 256 | t2->join(); 257 | t3->join(); 258 | 259 | // test timeWait() 260 | { 261 | Monitor::Lock lock(monitor); 262 | try 263 | { 264 | monitor.timedWait(Time::milliSeconds(-1)); 265 | test(false); 266 | } 267 | catch( const std::exception& ex ) 268 | { 269 | 270 | } 271 | const bool bRet = monitor.timedWait(Time::milliSeconds(500)); 272 | cout<<"bRet: "< RecMutexTestThreadPtr; 315 | 316 | static const std::string recMutexName("RecMutex"); 317 | class RecMutexTest : public testBase 318 | { 319 | public: 320 | RecMutexTest(): 321 | testBase(recMutexName) 322 | { 323 | 324 | } 325 | virtual void run(); 326 | }; 327 | 328 | void RecMutexTest::run() 329 | { 330 | RecMutex mutex; 331 | RecMutexTestThreadPtr t1; 332 | { 333 | RecMutex::Lock lock(mutex); 334 | cout<<"lock 1"<start(); 343 | t1->waitTryLock(); 344 | } 345 | t1->join(); 346 | } 347 | 348 | #include 349 | 350 | using namespace tbutil; 351 | std::list allTests; 352 | 353 | int main() 354 | { 355 | cout<<(2<<31-1)<::const_iterator p = allTests.begin(); 360 | for(; p != allTests.end(); ++p) 361 | { 362 | (*p)->start(); 363 | } 364 | return 0; 365 | } 366 | -------------------------------------------------------------------------------- /trunk/tbsys/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 | -------------------------------------------------------------------------------- /trunk/tbsys/test/testwarningbuffer.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: testwarningbuffer.cpp, 09/27/2012 06:42:21 PM xiaochu Exp $ 10 | * 11 | * Author: 12 | * xiaochu.yh 13 | * Description: 14 | * test warning buffer 15 | * 16 | */ 17 | #include "WarningBuffer.h" 18 | #include 19 | #include 20 | #include 21 | 22 | using namespace tbsys; 23 | using namespace std; 24 | 25 | void check_init_state(WarningBuffer &buffer) 26 | { 27 | assert(0 == buffer.get_readable_warning_count()); 28 | assert(0 == buffer.get_total_warning_count()); 29 | assert(NULL == buffer.get_warning(0)); 30 | assert(NULL == buffer.get_warning(1)); 31 | assert(NULL == buffer.get_warning(1000)); 32 | } 33 | 34 | void tsi_basic_check() 35 | { 36 | uint32_t i = 0; 37 | WarningBuffer * buffer = get_tsi_warning_buffer(); 38 | assert(NULL != buffer); 39 | check_init_state(*buffer); 40 | // over write string test 41 | buffer->reset(); 42 | check_init_state(*buffer); 43 | for (i = 0; i < buffer->get_buffer_size() * 2; i++) 44 | { 45 | char buf[1024]; 46 | sprintf(buf, "%d", i); 47 | assert(0 == buffer->append_warning(buf)); 48 | } 49 | for (i = 0; i < buffer->get_buffer_size(); i++) 50 | { 51 | char buf[1024]; 52 | sprintf(buf, "%d", i + buffer->get_buffer_size()); 53 | assert(0 == strcmp(buf, buffer->get_warning(i))); 54 | } 55 | fprintf(stderr, "pass overwrite test\n"); 56 | } 57 | 58 | WarningBuffer *bug_buffer; 59 | 60 | void* thread( void* para ) 61 | { 62 | para = NULL; 63 | pthread_t t = pthread_self(); 64 | WarningBuffer *b1 = get_tsi_warning_buffer(); 65 | fprintf(stderr, "thread %lu buf: %p\n", (uint64_t)t, b1); 66 | sleep(1); 67 | WarningBuffer *b2 = get_tsi_warning_buffer(); 68 | fprintf(stderr, "thread %lu buf: %p\n", (uint64_t)t, b2); 69 | assert(b1 == b2); 70 | sleep(1); 71 | bug_buffer = b2; 72 | return NULL; 73 | } 74 | 75 | void tsi_multi_thread_check() 76 | { 77 | pthread_t t1,t2; 78 | void *st1, *st2; 79 | pthread_create( &t1, NULL, thread, NULL ); 80 | pthread_create( &t2, NULL, thread, NULL ); 81 | pthread_join( t1, &st1 ); 82 | pthread_join( t2, &st2 ); 83 | fprintf(stderr, "multi_thread_check ok\n"); 84 | } 85 | 86 | int main(int argc, char *argv[]) 87 | { 88 | tsi_basic_check(); 89 | tsi_multi_thread_check(); 90 | // basic random test 91 | uint32_t i = 0; 92 | WarningBuffer buffer; 93 | check_init_state(buffer); 94 | for (i = 0; i < buffer.get_buffer_size(); i++) 95 | { 96 | char buf[1024]; 97 | sprintf(buf, "hello%d", i); 98 | assert(NULL == buffer.get_warning(i)); 99 | assert(i == buffer.get_readable_warning_count()); 100 | assert(i == buffer.get_total_warning_count()); 101 | assert(0 == buffer.append_warning(buf)); 102 | assert(i+1 == buffer.get_readable_warning_count()); 103 | assert(i+1 == buffer.get_total_warning_count()); 104 | assert(NULL != buffer.get_warning(i)); 105 | } 106 | 107 | for (i = 0; i < buffer.get_buffer_size() * 2; i++) 108 | { 109 | char buf[1024]; 110 | sprintf(buf, "hello%d", i); 111 | assert(buffer.get_buffer_size() + i == buffer.get_total_warning_count()); 112 | assert(0 == buffer.append_warning(buf)); 113 | assert(buffer.get_buffer_size() == buffer.get_readable_warning_count()); 114 | assert(buffer.get_buffer_size() + i + 1 == buffer.get_total_warning_count()); 115 | if (i < buffer.get_buffer_size()) 116 | { 117 | assert(NULL != buffer.get_warning(i)); 118 | } 119 | else 120 | { 121 | assert(NULL == buffer.get_warning(i)); 122 | } 123 | } 124 | #if 0 125 | for (i = 0; i <= buffer.get_buffer_size(); i++) 126 | { 127 | fprintf(stderr, "%s\n", buffer.get_warning(i)); 128 | } 129 | #endif 130 | // none over write string test 131 | buffer.reset(); 132 | check_init_state(buffer); 133 | for (i = 0; i < buffer.get_buffer_size(); i++) 134 | { 135 | char buf[1024]; 136 | sprintf(buf, "%d", i); 137 | assert(0 == buffer.append_warning(buf)); 138 | } 139 | for (i = 0; i < buffer.get_buffer_size(); i++) 140 | { 141 | char buf[1024]; 142 | sprintf(buf, "%d", i); 143 | assert(0 == strcmp(buf, buffer.get_warning(i))); 144 | } 145 | fprintf(stderr, "pass none overwrite test\n"); 146 | 147 | // over write string test 148 | buffer.reset(); 149 | check_init_state(buffer); 150 | for (i = 0; i < buffer.get_buffer_size() * 2; i++) 151 | { 152 | char buf[1024]; 153 | sprintf(buf, "%d", i); 154 | assert(0 == buffer.append_warning(buf)); 155 | } 156 | for (i = 0; i < buffer.get_buffer_size(); i++) 157 | { 158 | char buf[1024]; 159 | sprintf(buf, "%d", i + buffer.get_buffer_size()); 160 | assert(0 == strcmp(buf, buffer.get_warning(i))); 161 | } 162 | fprintf(stderr, "pass overwrite test\n"); 163 | 164 | // truncate test 165 | buffer.reset(); 166 | check_init_state(buffer); 167 | { 168 | char buf[1024*2]; 169 | memset(buf, 'A', 1024*2); 170 | assert(0 == buffer.append_warning(buf)); 171 | assert(0 != strcmp(buffer.get_warning(0), buf)); 172 | assert(0 == strncmp(buffer.get_warning(0), buf, buffer.get_max_warn_len()-1)); 173 | } 174 | fprintf(stderr, "pass truncate test\n"); 175 | fprintf(stderr, "ok\n"); 176 | return 0; 177 | } 178 | --------------------------------------------------------------------------------