aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac22
-rw-r--r--doc/dependencies.md2
-rw-r--r--doc/release-notes.md5
-rw-r--r--src/init.cpp13
-rw-r--r--src/sync.cpp20
-rw-r--r--src/sync.h16
-rw-r--r--src/test/txvalidation_tests.cpp2
-rw-r--r--src/util.h1
-rwxr-xr-xtest/functional/minchainwork.py2
-rwxr-xr-xtest/functional/multiwallet.py11
-rwxr-xr-xtest/functional/p2p-fingerprint.py1
-rw-r--r--test/functional/test_framework/messages.py15
12 files changed, 64 insertions, 46 deletions
diff --git a/configure.ac b/configure.ac
index 8e5561243a..a05896edea 100644
--- a/configure.ac
+++ b/configure.ac
@@ -659,6 +659,28 @@ AC_LINK_IFELSE([AC_LANG_SOURCE([
]
)
+TEMP_LDFLAGS="$LDFLAGS"
+LDFLAGS="$TEMP_LDFLAGS $PTHREAD_CFLAGS"
+AC_MSG_CHECKING([for thread_local support])
+AC_LINK_IFELSE([AC_LANG_SOURCE([
+ #include <thread>
+ static thread_local int foo = 0;
+ static void run_thread() { foo++;}
+ int main(){
+ for(int i = 0; i < 10; i++) { std::thread(run_thread).detach();}
+ return foo;
+ }
+ ])],
+ [
+ AC_DEFINE(HAVE_THREAD_LOCAL,1,[Define if thread_local is supported.])
+ AC_MSG_RESULT(yes)
+ ],
+ [
+ AC_MSG_RESULT(no)
+ ]
+)
+LDFLAGS="$TEMP_LDFLAGS"
+
# Check for different ways of gathering OS randomness
AC_MSG_CHECKING(for Linux getrandom syscall)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <unistd.h>
diff --git a/doc/dependencies.md b/doc/dependencies.md
index 964c03ba88..6e1d1ee992 100644
--- a/doc/dependencies.md
+++ b/doc/dependencies.md
@@ -13,7 +13,7 @@ These are the dependencies currently used by Bitcoin Core. You can find instruct
| Expat | [2.2.1](https://libexpat.github.io/) | | No | Yes | |
| fontconfig | [2.12.1](https://www.freedesktop.org/software/fontconfig/release/) | | No | Yes | |
| FreeType | [2.7.1](http://download.savannah.gnu.org/releases/freetype) | | No | | |
-| GCC | | [4.7+](https://gcc.gnu.org/) | | | |
+| GCC | | [4.8+](https://gcc.gnu.org/) | | | |
| HarfBuzz-NG | | | | | |
| libevent | [2.1.8-stable](https://github.com/libevent/libevent/releases) | 2.0.22 | No | | |
| libjpeg | | | | | [Yes](https://github.com/bitcoin/bitcoin/blob/master/depends/packages/qt.mk#L75) |
diff --git a/doc/release-notes.md b/doc/release-notes.md
index 32f1bef62c..2c63b1f88e 100644
--- a/doc/release-notes.md
+++ b/doc/release-notes.md
@@ -56,6 +56,11 @@ frequently tested on them.
Notable changes
===============
+GCC 4.8.x
+--------------
+The minimum version of GCC required to compile Bitcoin Core is now 4.8. No effort will be
+made to support older versions of GCC. See discussion in issue #11732 for more information.
+
HD-wallets by default
---------------------
Due to a backward-incompatible change in the wallet database, wallets created
diff --git a/src/init.cpp b/src/init.cpp
index 439eaacfcc..3cc797a17c 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -1030,11 +1030,6 @@ bool AppInitParameterInteraction()
fPruneMode = true;
}
- RegisterAllCoreRPCCommands(tableRPC);
-#ifdef ENABLE_WALLET
- RegisterWalletRPC(tableRPC);
-#endif
-
nConnectTimeout = gArgs.GetArg("-timeout", DEFAULT_CONNECT_TIMEOUT);
if (nConnectTimeout <= 0)
nConnectTimeout = DEFAULT_CONNECT_TIMEOUT;
@@ -1239,6 +1234,14 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
GetMainSignals().RegisterBackgroundSignalScheduler(scheduler);
GetMainSignals().RegisterWithMempoolSignals(mempool);
+ /* Register RPC commands regardless of -server setting so they will be
+ * available in the GUI RPC console even if external calls are disabled.
+ */
+ RegisterAllCoreRPCCommands(tableRPC);
+#ifdef ENABLE_WALLET
+ RegisterWalletRPC(tableRPC);
+#endif
+
/* Start the RPC server already. It will be started in "warmup" mode
* and not really process calls already (but it will signify connections
* that the server is there and will be ready later). Warmup mode will
diff --git a/src/sync.cpp b/src/sync.cpp
index fcc6ddc354..3f51383ea2 100644
--- a/src/sync.cpp
+++ b/src/sync.cpp
@@ -4,14 +4,16 @@
#include <sync.h>
+#include <set>
#include <util.h>
#include <utilstrencodings.h>
#include <stdio.h>
-#include <boost/thread.hpp>
-
#ifdef DEBUG_LOCKCONTENTION
+#if !defined(HAVE_THREAD_LOCAL)
+static_assert(false, "thread_local is not supported");
+#endif
void PrintLockContention(const char* pszName, const char* pszFile, int nLine)
{
LogPrintf("LOCKCONTENTION: %s\n", pszName);
@@ -45,8 +47,8 @@ struct CLockLocation {
return mutexName + " " + sourceFile + ":" + itostr(sourceLine) + (fTry ? " (TRY)" : "");
}
- bool fTry;
private:
+ bool fTry;
std::string mutexName;
std::string sourceFile;
int sourceLine;
@@ -67,10 +69,10 @@ struct LockData {
LockOrders lockorders;
InvLockOrders invlockorders;
- boost::mutex dd_mutex;
+ std::mutex dd_mutex;
} static lockdata;
-boost::thread_specific_ptr<LockStack> lockstack;
+static thread_local std::unique_ptr<LockStack> lockstack;
static void potential_deadlock_detected(const std::pair<void*, void*>& mismatch, const LockStack& s1, const LockStack& s2)
{
@@ -100,12 +102,12 @@ static void potential_deadlock_detected(const std::pair<void*, void*>& mismatch,
static void push_lock(void* c, const CLockLocation& locklocation)
{
- if (lockstack.get() == nullptr)
+ if (!lockstack)
lockstack.reset(new LockStack);
- boost::unique_lock<boost::mutex> lock(lockdata.dd_mutex);
+ std::lock_guard<std::mutex> lock(lockdata.dd_mutex);
- (*lockstack).push_back(std::make_pair(c, locklocation));
+ lockstack->push_back(std::make_pair(c, locklocation));
for (const std::pair<void*, CLockLocation> & i : (*lockstack)) {
if (i.first == c)
@@ -171,7 +173,7 @@ void DeleteLock(void* cs)
// We're already shutting down.
return;
}
- boost::unique_lock<boost::mutex> lock(lockdata.dd_mutex);
+ std::lock_guard<std::mutex> lock(lockdata.dd_mutex);
std::pair<void*, void*> item = std::make_pair(cs, nullptr);
LockOrders::iterator it = lockdata.lockorders.lower_bound(item);
while (it != lockdata.lockorders.end() && it->first.first == cs) {
diff --git a/src/sync.h b/src/sync.h
index b0889be767..3af27c65d0 100644
--- a/src/sync.h
+++ b/src/sync.h
@@ -8,8 +8,6 @@
#include <threadsafety.h>
-#include <boost/thread/condition_variable.hpp>
-#include <boost/thread/mutex.hpp>
#include <condition_variable>
#include <thread>
#include <mutex>
@@ -196,8 +194,8 @@ public:
class CSemaphore
{
private:
- boost::condition_variable condition;
- boost::mutex mutex;
+ std::condition_variable condition;
+ std::mutex mutex;
int value;
public:
@@ -205,16 +203,14 @@ public:
void wait()
{
- boost::unique_lock<boost::mutex> lock(mutex);
- while (value < 1) {
- condition.wait(lock);
- }
+ std::unique_lock<std::mutex> lock(mutex);
+ condition.wait(lock, [&]() { return value >= 1; });
value--;
}
bool try_wait()
{
- boost::unique_lock<boost::mutex> lock(mutex);
+ std::lock_guard<std::mutex> lock(mutex);
if (value < 1)
return false;
value--;
@@ -224,7 +220,7 @@ public:
void post()
{
{
- boost::unique_lock<boost::mutex> lock(mutex);
+ std::lock_guard<std::mutex> lock(mutex);
value++;
}
condition.notify_one();
diff --git a/src/test/txvalidation_tests.cpp b/src/test/txvalidation_tests.cpp
index d6abe3e5a9..2d1eb7b772 100644
--- a/src/test/txvalidation_tests.cpp
+++ b/src/test/txvalidation_tests.cpp
@@ -49,7 +49,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_reject_coinbase, TestChain100Setup)
// Check that the transaction hasn't been added to mempool.
BOOST_CHECK_EQUAL(mempool.size(), initialPoolSize);
- // Check that the validation state reflects the unsuccesful attempt.
+ // Check that the validation state reflects the unsuccessful attempt.
BOOST_CHECK(state.IsInvalid());
BOOST_CHECK_EQUAL(state.GetRejectReason(), "coinbase");
diff --git a/src/util.h b/src/util.h
index be5c99567d..08de43d29f 100644
--- a/src/util.h
+++ b/src/util.h
@@ -28,6 +28,7 @@
#include <vector>
#include <boost/signals2/signal.hpp>
+#include <boost/thread/condition_variable.hpp> // for boost::thread_interrupted
// Application startup time (used for uptime calculation)
int64_t GetStartupTime();
diff --git a/test/functional/minchainwork.py b/test/functional/minchainwork.py
index 35cd7ad141..90a3de0e0d 100755
--- a/test/functional/minchainwork.py
+++ b/test/functional/minchainwork.py
@@ -18,7 +18,7 @@ only succeeds past a given node once its nMinimumChainWork has been exceeded.
import time
from test_framework.test_framework import BitcoinTestFramework
-from test_framework.util import sync_blocks, connect_nodes, assert_equal
+from test_framework.util import connect_nodes, assert_equal
# 2 hashes required per regtest block (with no difficulty adjustment)
REGTEST_WORK_PER_BLOCK = 2
diff --git a/test/functional/multiwallet.py b/test/functional/multiwallet.py
index 4a721d1109..06409b6f31 100755
--- a/test/functional/multiwallet.py
+++ b/test/functional/multiwallet.py
@@ -16,10 +16,10 @@ class MultiWalletTest(BitcoinTestFramework):
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 1
- self.extra_args = [['-wallet=w1', '-wallet=w2', '-wallet=w3']]
+ self.extra_args = [['-wallet=w1', '-wallet=w2', '-wallet=w3', '-wallet=w']]
def run_test(self):
- assert_equal(set(self.nodes[0].listwallets()), {"w1", "w2", "w3"})
+ assert_equal(set(self.nodes[0].listwallets()), {"w1", "w2", "w3", "w"})
self.stop_node(0)
@@ -66,6 +66,7 @@ class MultiWalletTest(BitcoinTestFramework):
w1 = self.nodes[0].get_wallet_rpc("w1")
w2 = self.nodes[0].get_wallet_rpc("w2")
w3 = self.nodes[0].get_wallet_rpc("w3")
+ w4 = self.nodes[0].get_wallet_rpc("w")
wallet_bad = self.nodes[0].get_wallet_rpc("bad")
w1.generate(1)
@@ -91,18 +92,22 @@ class MultiWalletTest(BitcoinTestFramework):
w3_name = w3.getwalletinfo()['walletname']
assert_equal(w3_name, "w3")
- assert_equal({"w1", "w2", "w3"}, {w1_name, w2_name, w3_name})
+ w4_name = w4.getwalletinfo()['walletname']
+ assert_equal(w4_name, "w")
w1.generate(101)
assert_equal(w1.getbalance(), 100)
assert_equal(w2.getbalance(), 0)
assert_equal(w3.getbalance(), 0)
+ assert_equal(w4.getbalance(), 0)
w1.sendtoaddress(w2.getnewaddress(), 1)
w1.sendtoaddress(w3.getnewaddress(), 2)
+ w1.sendtoaddress(w4.getnewaddress(), 3)
w1.generate(1)
assert_equal(w2.getbalance(), 1)
assert_equal(w3.getbalance(), 2)
+ assert_equal(w4.getbalance(), 3)
batch = w1.batch([w1.getblockchaininfo.get_request(), w1.getwalletinfo.get_request()])
assert_equal(batch[0]["result"]["chain"], "regtest")
diff --git a/test/functional/p2p-fingerprint.py b/test/functional/p2p-fingerprint.py
index 4b6446fc5b..a8ce68374c 100755
--- a/test/functional/p2p-fingerprint.py
+++ b/test/functional/p2p-fingerprint.py
@@ -24,7 +24,6 @@ from test_framework.mininode import (
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal,
- p2p_port,
)
class P2PFingerprintTest(BitcoinTestFramework):
diff --git a/test/functional/test_framework/messages.py b/test/functional/test_framework/messages.py
index 40d02f3ee0..eee24910cb 100644
--- a/test/functional/test_framework/messages.py
+++ b/test/functional/test_framework/messages.py
@@ -167,21 +167,6 @@ def ser_string_vector(l):
return r
-def deser_int_vector(f):
- nit = deser_compact_size(f)
- r = []
- for i in range(nit):
- t = struct.unpack("<i", f.read(4))[0]
- r.append(t)
- return r
-
-
-def ser_int_vector(l):
- r = ser_compact_size(len(l))
- for i in l:
- r += struct.pack("<i", i)
- return r
-
# Deserialize from a hex string representation (eg from RPC)
def FromHex(obj, hex_string):
obj.deserialize(BytesIO(hex_str_to_bytes(hex_string)))