return ret;
}
-
-string strprintf(const char* format, ...)
+string strprintf(const std::string &format, ...)
{
char buffer[50000];
char* p = buffer;
{
va_list arg_ptr;
va_start(arg_ptr, format);
- ret = _vsnprintf(p, limit, format, arg_ptr);
+ ret = _vsnprintf(p, limit, format.c_str(), arg_ptr);
va_end(arg_ptr);
if (ret >= 0 && ret < limit)
break;
return str;
}
-
-bool error(const char* format, ...)
+bool error(const std::string &format, ...)
{
char buffer[50000];
int limit = sizeof(buffer);
va_list arg_ptr;
va_start(arg_ptr, format);
- int ret = _vsnprintf(buffer, limit, format, arg_ptr);
+ int ret = _vsnprintf(buffer, limit, format.c_str(), arg_ptr);
va_end(arg_ptr);
if (ret < 0 || ret >= limit)
{
}
-const char* wxGetTranslation(const char* pszEnglish)
-{
-#ifdef GUI
- // Wrapper of wxGetTranslation returning the same const char* type as was passed in
- static CCriticalSection cs;
- CRITICAL_BLOCK(cs)
- {
- // Look in cache
- static map<string, char*> mapCache;
- map<string, char*>::iterator mi = mapCache.find(pszEnglish);
- if (mi != mapCache.end())
- return (*mi).second;
-
- // wxWidgets translation
- wxString strTranslated = wxGetTranslation(wxString(pszEnglish, wxConvUTF8));
-
- // We don't cache unknown strings because caller might be passing in a
- // dynamic string and we would keep allocating memory for each variation.
- if (strcmp(pszEnglish, strTranslated.utf8_str()) == 0)
- return pszEnglish;
-
- // Add to cache, memory doesn't need to be freed. We only cache because
- // we must pass back a pointer to permanently allocated memory.
- char* pszCached = new char[strlen(strTranslated.utf8_str())+1];
- strcpy(pszCached, strTranslated.utf8_str());
- mapCache[pszEnglish] = pszCached;
- return pszCached;
- }
- return NULL;
-#else
- return pszEnglish;
-#endif
-}
-
bool WildcardMatch(const char* psz, const char* mask)
{
printf("\n\n************************\n%s\n", pszMessage);
fprintf(stderr, "\n\n************************\n%s\n", pszMessage);
strMiscWarning = pszMessage;
-#ifdef GUI
- if (wxTheApp && !fDaemon)
- MyMessageBox(pszMessage, "Bitcoin", wxOK | wxICON_ERROR);
-#endif
throw;
}
printf("\n\n************************\n%s\n", pszMessage);
fprintf(stderr, "\n\n************************\n%s\n", pszMessage);
strMiscWarning = pszMessage;
-#ifdef GUI
- if (wxTheApp && !fDaemon)
- boost::thread(boost::bind(ThreadOneMessageBox, string(pszMessage)));
-#endif
}
// - Median of other nodes's clocks
// - The user (asking the user to fix the system clock if the first two disagree)
//
+static int64 nMockTime = 0; // For unit testing
+
int64 GetTime()
{
+ if (nMockTime) return nMockTime;
+
return time(NULL);
}
+void SetMockTime(int64 nMockTimeIn)
+{
+ nMockTime = nMockTimeIn;
+}
+
static int64 nTimeOffset = 0;
int64 GetAdjustedTime()
struct CLockLocation
{
- std::string mutexName;
- std::string sourceFile;
- int sourceLine;
-
CLockLocation(const char* pszName, const char* pszFile, int nLine)
{
mutexName = pszName;
sourceFile = pszFile;
sourceLine = nLine;
}
+
+ std::string ToString() const
+ {
+ return mutexName+" "+sourceFile+":"+itostr(sourceLine);
+ }
+
+private:
+ std::string mutexName;
+ std::string sourceFile;
+ int sourceLine;
};
typedef std::vector< std::pair<CCriticalSection*, CLockLocation> > LockStack;
static boost::thread_specific_ptr<LockStack> lockstack;
-static void potential_deadlock_detected(const LockStack& s1, const LockStack& s2)
+static void potential_deadlock_detected(const std::pair<CCriticalSection*, CCriticalSection*>& mismatch, const LockStack& s1, const LockStack& s2)
{
printf("POTENTIAL DEADLOCK DETECTED\n");
printf("Previous lock order was:\n");
BOOST_FOREACH(const PAIRTYPE(CCriticalSection*, CLockLocation)& i, s2)
{
- printf(" %s %s:%d\n", i.second.mutexName.c_str(), i.second.sourceFile.c_str(), i.second.sourceLine);
+ if (i.first == mismatch.first) printf(" (1)");
+ if (i.first == mismatch.second) printf(" (2)");
+ printf(" %s\n", i.second.ToString().c_str());
}
printf("Current lock order is:\n");
BOOST_FOREACH(const PAIRTYPE(CCriticalSection*, CLockLocation)& i, s1)
{
- printf(" %s %s:%d\n", i.second.mutexName.c_str(), i.second.sourceFile.c_str(), i.second.sourceLine);
+ if (i.first == mismatch.first) printf(" (1)");
+ if (i.first == mismatch.second) printf(" (2)");
+ printf(" %s\n", i.second.ToString().c_str());
}
}
if (lockstack.get() == NULL)
lockstack.reset(new LockStack);
+ if (fDebug) printf("Locking: %s\n", locklocation.ToString().c_str());
dd_mutex.lock();
(*lockstack).push_back(std::make_pair(c, locklocation));
std::pair<CCriticalSection*, CCriticalSection*> p2 = std::make_pair(c, i.first);
if (lockorders.count(p2))
{
- potential_deadlock_detected(lockorders[p2], lockorders[p1]);
+ potential_deadlock_detected(p1, lockorders[p2], lockorders[p1]);
break;
}
}
static void pop_lock()
{
+ if (fDebug)
+ {
+ const CLockLocation& locklocation = (*lockstack).rbegin()->second;
+ printf("Unlocked: %s\n", locklocation.ToString().c_str());
+ }
+ dd_mutex.lock();
(*lockstack).pop_back();
+ dd_mutex.unlock();
}
void CCriticalSection::Enter(const char* pszName, const char* pszFile, int nLine)