X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Futil.h;h=88cc1e79ea01b2967dae579537466d973c7fda76;hb=58ac600b2c94f12309fc5e18933891590dc1eb4c;hp=cd0761ee3926b843c5d1f2f75e597f2f0bce1d49;hpb=76d660ebd336d3dd47dd555ebbaa721a4cc978b2;p=novacoin.git diff --git a/src/util.h b/src/util.h index cd0761e..88cc1e7 100644 --- a/src/util.h +++ b/src/util.h @@ -1,6 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2012 The Bitcoin developers // Distributed under the MIT/X11 software license, see the accompanying -// file license.txt or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_UTIL_H #define BITCOIN_UTIL_H @@ -15,7 +16,6 @@ #include #include -#include #include #include #include @@ -67,14 +67,6 @@ typedef unsigned long long uint64; // This is needed because the foreach macro can't get over the comma in pair #define PAIRTYPE(t1, t2) pair -// Used to bypass the rule against non-const reference to temporary -// where it makes sense with wrappers such as CFlatData or CTxDB -template -inline T& REF(const T& val) -{ - return (T&)val; -} - // Align by increasing pointer, must have extra space at end of buffer template T* alignup(T* p) @@ -123,7 +115,9 @@ typedef u_int SOCKET; #define Beep(n1,n2) (0) inline void Sleep(int64 n) { - boost::thread::sleep(boost::get_system_time() + boost::posix_time::milliseconds(n)); + /*Boost has a year 2038 problem— if the request sleep time is past epoch+2^31 seconds the sleep returns instantly. + So we clamp our sleeps here to 10 years and hope that boost is fixed by 2028.*/ + boost::thread::sleep(boost::get_system_time() + boost::posix_time::milliseconds(n>315576000000LL?315576000000LL:n)); } #endif @@ -223,31 +217,17 @@ std::string FormatFullVersion(); -// Wrapper to automatically initialize critical sections +// Wrapper to automatically initialize mutex class CCriticalSection { -#ifdef __WXMSW__ -protected: - CRITICAL_SECTION cs; -public: - explicit CCriticalSection() { InitializeCriticalSection(&cs); } - ~CCriticalSection() { DeleteCriticalSection(&cs); } - void Enter() { EnterCriticalSection(&cs); } - void Leave() { LeaveCriticalSection(&cs); } - bool TryEnter() { return TryEnterCriticalSection(&cs); } -#else protected: boost::interprocess::interprocess_recursive_mutex mutex; public: explicit CCriticalSection() { } ~CCriticalSection() { } - void Enter() { mutex.lock(); } - void Leave() { mutex.unlock(); } - bool TryEnter() { return mutex.try_lock(); } -#endif -public: - const char* pszFile; - int nLine; + void Enter(const char* pszName, const char* pszFile, int nLine); + void Leave(); + bool TryEnter(const char* pszName, const char* pszFile, int nLine); }; // Automatically leave critical section when leaving block, needed for exception safety @@ -255,9 +235,17 @@ class CCriticalBlock { protected: CCriticalSection* pcs; + public: - CCriticalBlock(CCriticalSection& csIn) { pcs = &csIn; pcs->Enter(); } - ~CCriticalBlock() { pcs->Leave(); } + CCriticalBlock(CCriticalSection& csIn, const char* pszName, const char* pszFile, int nLine) + { + pcs = &csIn; + pcs->Enter(pszName, pszFile, nLine); + } + ~CCriticalBlock() + { + pcs->Leave(); + } }; // WARNING: This will catch continue and break! @@ -265,22 +253,38 @@ public: // I'd rather be careful than suffer the other more error prone syntax. // The compiler will optimise away all this loop junk. #define CRITICAL_BLOCK(cs) \ - for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by CRITICAL_BLOCK!", !fcriticalblockonce)), fcriticalblockonce=false) \ - for (CCriticalBlock criticalblock(cs); fcriticalblockonce && (cs.pszFile=__FILE__, cs.nLine=__LINE__, true); fcriticalblockonce=false, cs.pszFile=NULL, cs.nLine=0) + for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by CRITICAL_BLOCK!" && !fcriticalblockonce)), fcriticalblockonce=false) \ + for (CCriticalBlock criticalblock(cs, #cs, __FILE__, __LINE__); fcriticalblockonce; fcriticalblockonce=false) + +#define ENTER_CRITICAL_SECTION(cs) \ + (cs).Enter(#cs, __FILE__, __LINE__) + +#define LEAVE_CRITICAL_SECTION(cs) \ + (cs).Leave() class CTryCriticalBlock { protected: CCriticalSection* pcs; + public: - CTryCriticalBlock(CCriticalSection& csIn) { pcs = (csIn.TryEnter() ? &csIn : NULL); } - ~CTryCriticalBlock() { if (pcs) pcs->Leave(); } + CTryCriticalBlock(CCriticalSection& csIn, const char* pszName, const char* pszFile, int nLine) + { + pcs = (csIn.TryEnter(pszName, pszFile, nLine) ? &csIn : NULL); + } + ~CTryCriticalBlock() + { + if (pcs) + { + pcs->Leave(); + } + } bool Entered() { return pcs != NULL; } }; #define TRY_CRITICAL_BLOCK(cs) \ - for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by TRY_CRITICAL_BLOCK!", !fcriticalblockonce)), fcriticalblockonce=false) \ - for (CTryCriticalBlock criticalblock(cs); fcriticalblockonce && (fcriticalblockonce = criticalblock.Entered()) && (cs.pszFile=__FILE__, cs.nLine=__LINE__, true); fcriticalblockonce=false, cs.pszFile=NULL, cs.nLine=0) + for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by TRY_CRITICAL_BLOCK!" && !fcriticalblockonce)), fcriticalblockonce=false) \ + for (CTryCriticalBlock criticalblock(cs, #cs, __FILE__, __LINE__); fcriticalblockonce && (fcriticalblockonce = criticalblock.Entered()); fcriticalblockonce=false) @@ -446,7 +450,7 @@ inline int64 GetArg(const std::string& strArg, int64 nDefault) return nDefault; } -inline bool GetBoolArg(const std::string& strArg) +inline bool GetBoolArg(const std::string& strArg, bool fDefault=false) { if (mapArgs.count(strArg)) { @@ -454,9 +458,26 @@ inline bool GetBoolArg(const std::string& strArg) return true; return (atoi(mapArgs[strArg]) != 0); } - return false; + return fDefault; } +/** + * Set an argument if it doesn't already have a value + * + * @param strArg Argument to set (e.g. "-foo") + * @param strValue Value (e.g. "1") + * @return true if argument gets set, false if it already had a value + */ +bool SoftSetArg(const std::string& strArg, const std::string& strValue); + +/** + * Set a boolean argument if it doesn't already have a value + * + * @param strArg Argument to set (e.g. "-foo") + * @param fValue Value (e.g. false) + * @return true if argument gets set, false if it already had a value + */ +bool SoftSetArg(const std::string& strArg, bool fValue); @@ -624,7 +645,10 @@ inline pthread_t CreateThread(void(*pfn)(void*), void* parg, bool fWantHandle=fa return (pthread_t)0; } if (!fWantHandle) + { + pthread_detach(hthread); return (pthread_t)-1; + } return hthread; } @@ -649,7 +673,7 @@ inline bool TerminateThread(pthread_t hthread, unsigned int nExitCode) return (pthread_cancel(hthread) == 0); } -inline void ExitThread(unsigned int nExitCode) +inline void ExitThread(size_t nExitCode) { pthread_exit((void*)nExitCode); } @@ -663,8 +687,8 @@ inline bool AffinityBugWorkaround(void(*pfn)(void*)) { #ifdef __WXMSW__ // Sometimes after a few hours affinity gets stuck on one processor - DWORD dwProcessAffinityMask = -1; - DWORD dwSystemAffinityMask = -1; + DWORD_PTR dwProcessAffinityMask = -1; + DWORD_PTR dwSystemAffinityMask = -1; GetProcessAffinityMask(GetCurrentProcess(), &dwProcessAffinityMask, &dwSystemAffinityMask); DWORD dwPrev1 = SetThreadAffinityMask(GetCurrentThread(), dwProcessAffinityMask); DWORD dwPrev2 = SetThreadAffinityMask(GetCurrentThread(), dwProcessAffinityMask);