diff --git a/servant/protocol b/servant/protocol index 48a520f..838bcfa 160000 --- a/servant/protocol +++ b/servant/protocol @@ -1 +1 @@ -Subproject commit 48a520fe192308217a4529438011d158da60f538 +Subproject commit 838bcfada355301f6832c6c88c2d180ac6a25d5f diff --git a/unittest b/unittest index 5f46a69..e663956 160000 --- a/unittest +++ b/unittest @@ -1 +1 @@ -Subproject commit 5f46a694b925be139aa16274a00b7d5ad611004c +Subproject commit e663956b02aa72f9491f759263da89d62502f7e8 diff --git a/util/include/util/tc_autoptr.h b/util/include/util/tc_autoptr.h index f10dfd6..84800a5 100644 --- a/util/include/util/tc_autoptr.h +++ b/util/include/util/tc_autoptr.h @@ -17,17 +17,13 @@ #ifndef __TC_AUTOPTR_H #define __TC_AUTOPTR_H -#include "util/tc_atomic.h" #include "util/tc_ex.h" +#include "util/tc_atomic.h" +#include +#include namespace tars { -/////////////////////////////////////////////////////// -/** -* @file tc_autoptr.h -* @brief 智能指针类(智能指针不能相互引用, 否则内存泄漏). -*/ -////////////////////////////////////////////////////// /** * @brief 空指针异常 @@ -43,22 +39,17 @@ struct TC_AutoPtrNull_Exception : public TC_Exception * * 所有需要智能指针支持的类都需要从该对象继承, * - * 内部采用引用计数TC_Atomic实现,对象可以放在容器中; */ -template -class TC_HandleBaseT +class TC_HandleBase { public: - /** 原子计数类型*/ - typedef T atomic_type; - /** * @brief 复制. * * @return TC_HandleBase& */ - TC_HandleBaseT& operator=(const TC_HandleBaseT&) + TC_HandleBase& operator=(const TC_HandleBase&) { return *this; } @@ -66,14 +57,14 @@ public: /** * @brief 增加计数 */ - void incRef() { _atomic.inc_fast(); } + void incRef() { ++_atomic; } /** * @brief 减少计数, 当计数==0时, 且需要删除数据时, 释放对象 */ void decRef() { - if(_atomic.dec_and_test() && !_bNoDelete) + if((--_atomic) == 0 && !_bNoDelete) { _bNoDelete = true; delete this; @@ -85,11 +76,11 @@ public: * * @return int 计数值 */ - int getRef() const { return _atomic.get(); } + int getRef() const { return _atomic; } /** - * @brief 设置不自动释放. - * + * @brief 设置不自动释放. + * * @param b 是否自动删除,true or false */ void setNoDelete(bool b) { _bNoDelete = b; } @@ -99,21 +90,21 @@ protected: /** * @brief 构造函数 */ - TC_HandleBaseT() : _atomic(0), _bNoDelete(false) + TC_HandleBase() : _atomic(0), _bNoDelete(false) { } /** * @brief 拷贝构造 */ - TC_HandleBaseT(const TC_HandleBaseT&) : _atomic(0), _bNoDelete(false) + TC_HandleBase(const TC_HandleBase&) : _atomic(0), _bNoDelete(false) { } /** * @brief 析够 */ - virtual ~TC_HandleBaseT() + virtual ~TC_HandleBase() { } @@ -122,7 +113,7 @@ protected: /** * 计数 */ - atomic_type _atomic; + std::atomic _atomic; /** * 是否自动删除 @@ -130,34 +121,6 @@ protected: bool _bNoDelete; }; -template<> -inline void TC_HandleBaseT::incRef() -{ - //__sync_fetch_and_add(&_atomic,1); - ++_atomic; -} - -template<> -inline void TC_HandleBaseT::decRef() -{ - //int c = __sync_fetch_and_sub(&_atomic, 1); - //if(c == 1 && !_bNoDelete) - if(--_atomic == 0 && !_bNoDelete) - { - _bNoDelete = true; - delete this; - } -} - -template<> -inline int TC_HandleBaseT::getRef() const -{ - //return __sync_fetch_and_sub(const_cast(&_atomic), 0); - return _atomic; -} - -typedef TC_HandleBaseT TC_HandleBase; - /** * @brief 智能指针模板类. * @@ -180,8 +143,8 @@ public: typedef T element_type; /** - * @brief 用原生指针初始化, 计数+1. - * + * @brief 用原生指针初始化, 计数+1. + * * @param p */ TC_AutoPtr(T* p = 0) @@ -195,8 +158,8 @@ public: } /** - * @brief 用其他智能指针r的原生指针初始化, 计数+1. - * + * @brief 用其他智能指针r的原生指针初始化, 计数+1. + * * @param Y * @param r */ @@ -212,8 +175,8 @@ public: } /** - * @brief 拷贝构造, 计数+1. - * + * @brief 拷贝构造, 计数+1. + * * @param r */ TC_AutoPtr(const TC_AutoPtr& r) @@ -238,9 +201,9 @@ public: } /** - * @brief 赋值, 普通指针. - * - * @param p + * @brief 赋值, 普通指针. + * + * @param p * @return TC_AutoPtr& */ TC_AutoPtr& operator=(T* p) @@ -264,10 +227,10 @@ public: } /** - * @brief 赋值, 其他类型智能指针. - * + * @brief 赋值, 其他类型智能指针. + * * @param Y - * @param r + * @param r * @return TC_AutoPtr& */ template @@ -292,9 +255,9 @@ public: } /** - * @brief 赋值, 该类型其他执政指针. - * - * @param r + * @brief 赋值, 该类型其他执政指针. + * + * @param r * @return TC_AutoPtr& */ TC_AutoPtr& operator=(const TC_AutoPtr& r) @@ -318,10 +281,10 @@ public: } /** - * @brief 将其他类型的智能指针换成当前类型的智能指针. - * + * @brief 将其他类型的智能指针换成当前类型的智能指针. + * * @param Y - * @param r + * @param r * @return TC_AutoPtr */ template @@ -331,10 +294,10 @@ public: } /** - * @brief 将其他原生类型的指针转换成当前类型的智能指针. - * + * @brief 将其他原生类型的指针转换成当前类型的智能指针. + * * @param Y - * @param p + * @param p * @return TC_AutoPtr */ template @@ -394,8 +357,8 @@ public: } /** - * @brief 交换指针. - * + * @brief 交换指针. + * * @param other */ void swap(TC_AutoPtr& other) @@ -425,7 +388,7 @@ public: template inline void TC_AutoPtr::throwNullHandleException() const { - throw TC_AutoPtrNull_Exception("autoptr null handle error"); + throw TC_AutoPtrNull_Exception("autoptr null handle error![" + string(typeid(T).name()) +"]"); } /** @@ -443,14 +406,9 @@ inline bool operator==(const TC_AutoPtr& lhs, const TC_AutoPtr& rhs) { T* l = lhs.get(); U* r = rhs.get(); - if(l && r) - { - return *l == *r; - } - else - { - return !l && !r; - } + + // 改为直接比较指针,而不是比较值 + return (l == r); } /** @@ -468,14 +426,9 @@ inline bool operator!=(const TC_AutoPtr& lhs, const TC_AutoPtr& rhs) { T* l = lhs.get(); U* r = rhs.get(); - if(l && r) - { - return *l != *r; - } - else - { - return l || r; - } + + // 改为直接比较指针,而不是比较值 + return (l != r); } /** @@ -495,7 +448,9 @@ inline bool operator<(const TC_AutoPtr& lhs, const TC_AutoPtr& rhs) U* r = rhs.get(); if(l && r) { - return *l < *r; + //return *l < *r; + // 改为直接比较指针,而不是比较值 + return (l < r); } else { diff --git a/util/include/util/tc_common.h b/util/include/util/tc_common.h index e41dde9..a100fb0 100644 --- a/util/include/util/tc_common.h +++ b/util/include/util/tc_common.h @@ -21,6 +21,13 @@ #define __USE_XOPEN #endif +#include "util/tc_platform.h" + +#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS +#include +#include +#endif + #include #include #include @@ -38,6 +45,7 @@ #include #include #include +#include #include #include @@ -149,6 +157,15 @@ public: */ static int strgmt2tm(const string &sString, struct tm &stTm); + /** + * @brief 格式化的字符串时间转为时间戳. + * + * @param sString 格式化的字符串时间 + * @param sFormat 格式化的字符串时间的格式,默认为紧凑格式 + * @return time_t 转换后的时间戳 + */ + static time_t str2time(const string &sString, const string &sFormat = "%Y%m%d%H%M%S"); + /** * @brief 时间转换成字符串. * @@ -167,6 +184,30 @@ public: */ static string tm2str(const time_t &t, const string &sFormat = "%Y%m%d%H%M%S"); + + /** + * @brief 时间转换tm. + * + * @param t 时间结构 + */ + static void tm2time(const time_t &t, struct tm &tt); + + /** + * @brief time_t转换成tm(不用系统的localtime_r, 否则很慢!!!) + * + * @param t 时间结构 + * @param sFormat 需要转换的目标格式,默认为紧凑格式 + * @return string 转换后的时间字符串 + */ + static void tm2tm(const time_t &t, struct tm &stTm); + + /** + * @brief 获取当前的秒和毫秒 + * + * @param t 时间结构 + */ + static int gettimeofday(struct timeval &tv); + /** * @brief 当前时间转换成紧凑格式字符串 * @param sFormat 格式,默认为紧凑格式 @@ -297,6 +338,15 @@ public: template static string tostr(const multimap &t); + /** + * @brief 把map输出为字符串. + * + * @param map 要转换的map对象 + * @return string 输出的字符串 + */ + template + static string tostr(const unordered_map &t); + /** * @brief pair 转化为字符串,保证map等关系容器可以直接用tostr来输出 * @param pair pair对象 @@ -757,6 +807,22 @@ string TC_Common::tostr(const multimap &t) return sBuffer; } +template +string TC_Common::tostr(const unordered_map &t) +{ + string sBuffer; + typename unordered_map::const_iterator it = t.begin(); + while (it != t.end()) { + sBuffer += " ["; + sBuffer += tostr(it->first); + sBuffer += "]=["; + sBuffer += tostr(it->second); + sBuffer += "] "; + ++it; + } + return sBuffer; +} + template string TC_Common::tostr(const pair &itPair) { diff --git a/util/include/util/tc_epoll_server.h b/util/include/util/tc_epoll_server.h index 8d3ba36..b921f0b 100644 --- a/util/include/util/tc_epoll_server.h +++ b/util/include/util/tc_epoll_server.h @@ -551,9 +551,9 @@ public: /** * 获取当前连接数 - * @return size_t + * @return int */ - size_t getNowConnection() const; + int getNowConnection() const; /** * 获取EpollServer @@ -769,7 +769,7 @@ public: /** * 当前连接数 */ - TC_Atomic _iCurConns; + std::atomic _iCurConns; /** * Handle个数 diff --git a/util/src/tc_common.cpp b/util/src/tc_common.cpp index af6b9d1..1147d95 100644 --- a/util/src/tc_common.cpp +++ b/util/src/tc_common.cpp @@ -108,9 +108,12 @@ string TC_Common::tostr(const unsigned long &t) template <> string TC_Common::tostr(const float &t) { - char buf[32]; - snprintf(buf, 32, "%.5f", t); - string s(buf); + //C++11 to_string,默认保留后面6位小数 + string s = std::to_string(t); + + // char buf[32]; + // snprintf(buf, 32, "%.5f", t); + // string s(buf); //去掉无效0, eg. 1.0300 -> 1.03;1.00 -> 1 bool bFlag = false; @@ -142,9 +145,12 @@ string TC_Common::tostr(const float &t) template <> string TC_Common::tostr(const double &t) { - char buf[32]; - snprintf(buf, 32, "%.5f", t); - string s(buf); + //C++11 to_string,默认保留后面6位小数 + string s = std::to_string(t); + + // char buf[32]; + // snprintf(buf, 32, "%.5f", t); + // string s(buf); //去掉无效0, eg. 1.0300 -> 1.03;1.00 -> 1 bool bFlag = false; @@ -364,12 +370,61 @@ bool TC_Common::isdigit(const string &sInput) return true; } + +//用于计算时区差异! +class TimezoneHelper +{ +public: + TimezoneHelper() + { + struct tm timeinfo; + time_t secs, local_secs, gmt_secs; + time(&secs); + + //带时区时间 +#if TARGET_PLATFORM_WINDOWS + localtime_s(&timeinfo, &secs); +#else + localtime_r(&secs, &timeinfo); +#endif + + local_secs = mktime(&timeinfo); + + //不带时区时间 + +#if TARGET_PLATFORM_WINDOWS + gmtime_s(&timeinfo, &secs); +#else + gmtime_r(&secs, &timeinfo); +#endif + + gmt_secs = mktime(&timeinfo); + timezone_diff_secs = local_secs - gmt_secs; + } + + static int64_t timezone_diff_secs; +}; + +int64_t TimezoneHelper::timezone_diff_secs = 0; + int TC_Common::str2tm(const string &sString, const string &sFormat, struct tm &stTm) { char *p = strptime(sString.c_str(), sFormat.c_str(), &stTm); return (p != NULL) ? 0 : -1; } +time_t TC_Common::str2time(const string &sString, const string &sFormat) +{ + struct tm stTm; + if (0 == str2tm(sString, sFormat, stTm)) + { + //注意这里没有直接用mktime, mktime会访问时区文件, 会巨慢! + static TimezoneHelper helper; + return timegm(&stTm) - TimezoneHelper::timezone_diff_secs; + } + return 0; +} + int TC_Common::strgmt2tm(const string &sString, struct tm &stTm) { return str2tm(sString, "%a, %d %b %Y %H:%M:%S GMT", stTm); @@ -384,14 +439,65 @@ string TC_Common::tm2str(const struct tm &stTm, const string &sFormat) return string(sTimeString); } +int TC_Common::gettimeofday(struct timeval &tv) +{ +#if TARGET_PLATFORM_WINDOWS + static const DWORDLONG FILETIME_to_timeval_skew = 116444736000000000; + FILETIME tfile; + ::GetSystemTimeAsFileTime(&tfile); + + ULARGE_INTEGER tmp; + tmp.LowPart = tfile.dwLowDateTime; + tmp.HighPart = tfile.dwHighDateTime; + tmp.QuadPart -= FILETIME_to_timeval_skew; + + ULARGE_INTEGER largeInt; + largeInt.QuadPart = tmp.QuadPart / (10000 * 1000); + tv.tv_sec = (long)(tmp.QuadPart / (10000 * 1000)); + tv.tv_usec = (long)((tmp.QuadPart % (10000 * 1000)) / 10); + return 0; +#else + return ::gettimeofday(&tv, 0); +#endif +} + +void TC_Common::tm2time(const time_t &t, struct tm &tt) +{ + //加快速度, 否则会比较慢, 不用localtime_r(会访问时区文件, 较慢) + static TimezoneHelper helper; + time_t localt = t + TimezoneHelper::timezone_diff_secs; + +#if TARGET_PLATFORM_WINDOWS + //localtime_s + gmtime_s(&tt, &localt); +#else + gmtime_r(&localt, &tt); +#endif +} + string TC_Common::tm2str(const time_t &t, const string &sFormat) { struct tm tt; - localtime_r(&t, &tt); + tm2time(t, tt); + // localtime_r(&t, &tt); return tm2str(tt, sFormat); } + +void TC_Common::tm2tm(const time_t &t, struct tm &tt) +{ + static TimezoneHelper helper; + time_t localt = t + TimezoneHelper::timezone_diff_secs; + +#if TARGET_PLATFORM_WINDOWS + gmtime_s(&tt, &localt); +#else + gmtime_r(&localt, &tt); +#endif + // gmtime_r(&localt, &stTm); +} + string TC_Common::now2str(const string &sFormat) { time_t t = time(NULL); @@ -407,8 +513,15 @@ string TC_Common::now2GMTstr() string TC_Common::tm2GMTstr(const time_t &t) { struct tm tt; - gmtime_r(&t, &tt); - return tm2str(tt, "%a, %d %b %Y %H:%M:%S GMT"); +#if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS + gmtime_r(&t, &tt); +#elif TARGET_PLATFORM_WINDOWS + _gmtime64_s(&tt, &t); +#endif + return tm2str(tt, "%a, %d %b %Y %H:%M:%S GMT"); + + // gmtime_r(&t, &tt); + // return tm2str(tt, "%a, %d %b %Y %H:%M:%S GMT"); } string TC_Common::tm2GMTstr(const struct tm &stTm) @@ -430,7 +543,8 @@ int64_t TC_Common::now2ms() { struct timeval tv; - gettimeofday(&tv, 0); + // gettimeofday(&tv, 0); + TC_Common::gettimeofday(tv); return tv.tv_sec * (int64_t)1000 + tv.tv_usec/1000; } @@ -439,7 +553,8 @@ int64_t TC_Common::now2us() { struct timeval tv; - gettimeofday(&tv, 0); + TC_Common::gettimeofday(tv); + // gettimeofday(&tv, 0); return tv.tv_sec * (int64_t)1000000 + tv.tv_usec; } @@ -634,6 +749,7 @@ bool TC_Common::matchPeriod(const string& s, const vector& pat) return false; } +#if TARGET_PLATFORM_LINUX || __APPLE__ void TC_Common::daemon() { pid_t pid; @@ -677,6 +793,7 @@ void TC_Common::ignorePipe() sigemptyset(&sig.sa_mask); sigaction(SIGPIPE,&sig,NULL); } +#endif bool TC_Common::isPrimeNumber(size_t n) { @@ -735,6 +852,8 @@ size_t TC_Common::toSize(const string &s, size_t iDefaultSize) return iDefaultSize; } +#if TARGET_PLATFORM_LINUX || __APPLE__ + // Generate the randome string, a SHA1-sized random number void TC_Common::getRandomHexChars(char* p, unsigned int len) { @@ -753,5 +872,7 @@ void TC_Common::getRandomHexChars(char* p, unsigned int len) } +#endif + } diff --git a/util/src/tc_epoll_server.cpp b/util/src/tc_epoll_server.cpp index 6317c39..90f3379 100644 --- a/util/src/tc_epoll_server.cpp +++ b/util/src/tc_epoll_server.cpp @@ -546,17 +546,17 @@ bool TC_EpollServer::BindAdapter::isLimitMaxConnection() const void TC_EpollServer::BindAdapter::decreaseNowConnection() { - _iCurConns.dec(); + _iCurConns++; } void TC_EpollServer::BindAdapter::increaseNowConnection() { - _iCurConns.inc(); + _iCurConns--; } -size_t TC_EpollServer::BindAdapter::getNowConnection() const +int TC_EpollServer::BindAdapter::getNowConnection() const { - return _iCurConns.get(); + return _iCurConns; } vector TC_EpollServer::BindAdapter::getConnStatus()