Skip to content

Commit

Permalink
Merge bitcoin#10866: Fix -Wthread-safety-analysis warnings. Compile w…
Browse files Browse the repository at this point in the history
…ith -Wthread-safety-analysis if available.

76ea17c Add mutex requirement for AddToCompactExtraTransactions(…) (practicalswift)
4616c82 Use -Wthread-safety-analysis if available (+ -Werror=thread-safety-analysis if --enable-werror) (practicalswift)
7e319d6 Fix -Wthread-safety-analysis warnings. Change the sync.h primitives to std from boost. (Matt Corallo)

Pull request description:

  * Add mutex requirement for `AddToCompactExtraTransactions(…)`.
  * Use `-Wthread-safety-analysis` if available.
  * Rebased on top of https://github.com/TheBlueMatt/bitcoin/commits/2017-08-test-10923 - now includes: Fix -Wthread-safety-analysis warnings. Change the sync.h primitives to std from boost.

Tree-SHA512: fb7365f85daa2741c276a1c899228181a8d46af51db7fbbdffceeaff121a3eb2ab74d7c8bf5e7de879bcc5042d00d24cb4649c312d51caba45a3f6135fd8b38f
  • Loading branch information
sipa authored and PastaPastaPasta committed Feb 4, 2020
1 parent 72571c2 commit 9c33eef
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 30 deletions.
2 changes: 2 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ if test "x$enable_werror" = "xyes"; then
AC_MSG_ERROR("enable-werror set but -Werror is not usable")
fi
AX_CHECK_COMPILE_FLAG([-Werror=vla],[ERROR_CXXFLAGS="$ERROR_CXXFLAGS -Werror=vla"],,[[$CXXFLAG_WERROR]])
AX_CHECK_COMPILE_FLAG([-Werror=thread-safety-analysis],[ERROR_CXXFLAGS="$ERROR_CXXFLAGS -Werror=thread-safety-analysis"],,[[$CXXFLAG_WERROR]])
fi

if test "x$CXXFLAGS_overridden" = "xno"; then
Expand All @@ -293,6 +294,7 @@ if test "x$CXXFLAGS_overridden" = "xno"; then
AX_CHECK_COMPILE_FLAG([-Wformat],[CXXFLAGS="$CXXFLAGS -Wformat"],,[[$CXXFLAG_WERROR]])
AX_CHECK_COMPILE_FLAG([-Wvla],[CXXFLAGS="$CXXFLAGS -Wvla"],,[[$CXXFLAG_WERROR]])
AX_CHECK_COMPILE_FLAG([-Wformat-security],[CXXFLAGS="$CXXFLAGS -Wformat-security"],,[[$CXXFLAG_WERROR]])
AX_CHECK_COMPILE_FLAG([-Wthread-safety-analysis],[CXXFLAGS="$CXXFLAGS -Wthread-safety-analysis"],,[[$CXXFLAG_WERROR]])

## Some compilers (gcc) ignore unknown -Wno-* options, but warn about all
## unknown options if any other warning is produced. Test the -Wfoo case, and
Expand Down
6 changes: 3 additions & 3 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -677,14 +677,14 @@ static void BlockNotifyCallback(bool initialSync, const CBlockIndex *pBlockIndex
}

static bool fHaveGenesis = false;
static boost::mutex cs_GenesisWait;
static CWaitableCriticalSection cs_GenesisWait;
static CConditionVariable condvar_GenesisWait;

static void BlockNotifyGenesisWait(bool, const CBlockIndex *pBlockIndex)
{
if (pBlockIndex != nullptr) {
{
boost::unique_lock<boost::mutex> lock_GenesisWait(cs_GenesisWait);
WaitableLock lock_GenesisWait(cs_GenesisWait);
fHaveGenesis = true;
}
condvar_GenesisWait.notify_all();
Expand Down Expand Up @@ -2180,7 +2180,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)

// Wait for genesis block to be processed
{
boost::unique_lock<boost::mutex> lock(cs_GenesisWait);
WaitableLock lock(cs_GenesisWait);
while (!fHaveGenesis) {
condvar_GenesisWait.wait(lock);
}
Expand Down
10 changes: 5 additions & 5 deletions src/rpc/mining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ UniValue getblocktemplate(const JSONRPCRequest& request)
{
// Wait to respond until either the best block changes, OR a minute has passed and there are more transactions
uint256 hashWatchedChain;
boost::system_time checktxtime;
std::chrono::steady_clock::time_point checktxtime;
unsigned int nTransactionsUpdatedLastLP;

if (lpval.isStr())
Expand All @@ -511,17 +511,17 @@ UniValue getblocktemplate(const JSONRPCRequest& request)
// Release the wallet and main lock while waiting
LEAVE_CRITICAL_SECTION(cs_main);
{
checktxtime = boost::get_system_time() + boost::posix_time::minutes(1);
checktxtime = std::chrono::steady_clock::now() + std::chrono::minutes(1);

boost::unique_lock<boost::mutex> lock(csBestBlock);
WaitableLock lock(csBestBlock);
while (chainActive.Tip()->GetBlockHash() == hashWatchedChain && IsRPCRunning())
{
if (!cvBlockChange.timed_wait(lock, checktxtime))
if (cvBlockChange.wait_until(lock, checktxtime) == std::cv_status::timeout)
{
// Timeout: Check transactions for update
if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLastLP)
break;
checktxtime += boost::posix_time::seconds(10);
checktxtime += std::chrono::seconds(10);
}
}
}
Expand Down
46 changes: 24 additions & 22 deletions src/sync.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@

#include <boost/thread/condition_variable.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/recursive_mutex.hpp>
#include <condition_variable>
#include <thread>
#include <mutex>


/////////////////////////////////////////////////
Expand All @@ -21,17 +23,17 @@

/*
CCriticalSection mutex;
boost::recursive_mutex mutex;
std::recursive_mutex mutex;
LOCK(mutex);
boost::unique_lock<boost::recursive_mutex> criticalblock(mutex);
std::unique_lock<std::recursive_mutex> criticalblock(mutex);
LOCK2(mutex1, mutex2);
boost::unique_lock<boost::recursive_mutex> criticalblock1(mutex1);
boost::unique_lock<boost::recursive_mutex> criticalblock2(mutex2);
std::unique_lock<std::recursive_mutex> criticalblock1(mutex1);
std::unique_lock<std::recursive_mutex> criticalblock2(mutex2);
TRY_LOCK(mutex, name);
boost::unique_lock<boost::recursive_mutex> name(mutex, boost::try_to_lock_t);
std::unique_lock<std::recursive_mutex> name(mutex, std::try_to_lock_t);
ENTER_CRITICAL_SECTION(mutex); // no RAII
mutex.lock();
Expand Down Expand Up @@ -88,33 +90,35 @@ void static inline DeleteLock(void* cs) {}
#define AssertLockNotHeld(cs) AssertLockNotHeldInternal(#cs, __FILE__, __LINE__, &cs)

/**
* Wrapped boost mutex: supports recursive locking, but no waiting
* Wrapped mutex: supports recursive locking, but no waiting
* TODO: We should move away from using the recursive lock by default.
*/
class CCriticalSection : public AnnotatedMixin<boost::recursive_mutex>
class CCriticalSection : public AnnotatedMixin<std::recursive_mutex>
{
public:
~CCriticalSection() {
DeleteLock((void*)this);
}
};

/** Wrapped boost mutex: supports waiting but not recursive locking */
typedef AnnotatedMixin<boost::mutex> CWaitableCriticalSection;
/** Wrapped mutex: supports waiting but not recursive locking */
typedef AnnotatedMixin<std::mutex> CWaitableCriticalSection;

/** Just a typedef for boost::condition_variable, can be wrapped later if desired */
typedef boost::condition_variable CConditionVariable;
/** Just a typedef for std::condition_variable, can be wrapped later if desired */
typedef std::condition_variable CConditionVariable;

/** Just a typedef for std::unique_lock, can be wrapped later if desired */
typedef std::unique_lock<std::mutex> WaitableLock;

#ifdef DEBUG_LOCKCONTENTION
void PrintLockContention(const char* pszName, const char* pszFile, int nLine);
#endif

/** Wrapper around boost::unique_lock<Mutex> */
template <typename Mutex>
class SCOPED_LOCKABLE CMutexLock
/** Wrapper around std::unique_lock<CCriticalSection> */
class SCOPED_LOCKABLE CCriticalBlock
{
private:
boost::unique_lock<Mutex> lock;
std::unique_lock<CCriticalSection> lock;

void Enter(const char* pszName, const char* pszFile, int nLine)
{
Expand All @@ -139,26 +143,26 @@ class SCOPED_LOCKABLE CMutexLock
}

public:
CMutexLock(Mutex& mutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) EXCLUSIVE_LOCK_FUNCTION(mutexIn) : lock(mutexIn, boost::defer_lock)
CCriticalBlock(CCriticalSection& mutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) EXCLUSIVE_LOCK_FUNCTION(mutexIn) : lock(mutexIn, std::defer_lock)
{
if (fTry)
TryEnter(pszName, pszFile, nLine);
else
Enter(pszName, pszFile, nLine);
}

CMutexLock(Mutex* pmutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) EXCLUSIVE_LOCK_FUNCTION(pmutexIn)
CCriticalBlock(CCriticalSection* pmutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) EXCLUSIVE_LOCK_FUNCTION(pmutexIn)
{
if (!pmutexIn) return;

lock = boost::unique_lock<Mutex>(*pmutexIn, boost::defer_lock);
lock = std::unique_lock<CCriticalSection>(*pmutexIn, std::defer_lock);
if (fTry)
TryEnter(pszName, pszFile, nLine);
else
Enter(pszName, pszFile, nLine);
}

~CMutexLock() UNLOCK_FUNCTION()
~CCriticalBlock() UNLOCK_FUNCTION()
{
if (lock.owns_lock())
LeaveCritical();
Expand All @@ -170,8 +174,6 @@ class SCOPED_LOCKABLE CMutexLock
}
};

typedef CMutexLock<CCriticalSection> CCriticalBlock;

#define PASTE(x, y) x ## y
#define PASTE2(x, y) PASTE(x, y)

Expand Down

0 comments on commit 9c33eef

Please sign in to comment.