Merge pull request #7302
3968922
c++11: fix libbdb build against libc++ in c++11 mode (Cory Fields)57d2f62
c++11: CAccountingEntry must be defined before use in a list (Cory Fields)89f71c6
c++11: don't throw from the reverselock destructor (Cory Fields)76ac35f
c++11: detect and correct for boost builds with an incompatible abi (Cory Fields)
This commit is contained in:
commit
41f1a3e99b
6 changed files with 123 additions and 96 deletions
25
configure.ac
25
configure.ac
|
@ -619,6 +619,31 @@ if test x$use_boost = xyes; then
|
|||
|
||||
BOOST_LIBS="$BOOST_LDFLAGS $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB $BOOST_PROGRAM_OPTIONS_LIB $BOOST_THREAD_LIB $BOOST_CHRONO_LIB"
|
||||
|
||||
TEMP_LIBS="$LIBS"
|
||||
LIBS="$BOOST_LIBS $LIBS"
|
||||
TEMP_CPPFLAGS="$CPPFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
|
||||
AC_MSG_CHECKING([for mismatched boost c++11 scoped enums])
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
||||
#include "boost/config.hpp"
|
||||
#include "boost/version.hpp"
|
||||
#if !defined(BOOST_NO_SCOPED_ENUMS) && !defined(BOOST_NO_CXX11_SCOPED_ENUMS) && BOOST_VERSION < 105700
|
||||
#define BOOST_NO_SCOPED_ENUMS
|
||||
#define BOOST_NO_CXX11_SCOPED_ENUMS
|
||||
#define CHECK
|
||||
#endif
|
||||
#include "boost/filesystem.hpp"
|
||||
]],[[
|
||||
#if defined(CHECK)
|
||||
boost::filesystem::copy_file("foo", "bar");
|
||||
#else
|
||||
choke;
|
||||
#endif
|
||||
]])],
|
||||
[AC_MSG_RESULT(mismatched); AC_DEFINE(FORCE_BOOST_EMULATED_SCOPED_ENUMS, 1, [Define this symbol if boost scoped enums are emulated])], [AC_MSG_RESULT(ok)])
|
||||
LIBS="$TEMP_LIBS"
|
||||
CPPFLAGS="$TEMP_CPPFLAGS"
|
||||
|
||||
dnl Boost >= 1.50 uses sleep_for rather than the now-deprecated sleep, however
|
||||
dnl it was broken from 1.50 to 1.52 when backed by nanosleep. Use sleep_for if
|
||||
dnl a working version is available, else fall back to sleep. sleep was removed
|
||||
|
|
|
@ -12,7 +12,8 @@ $(package)_config_opts_linux=--with-pic
|
|||
endef
|
||||
|
||||
define $(package)_preprocess_cmds
|
||||
sed -i.old 's/__atomic_compare_exchange/__atomic_compare_exchange_db/' dbinc/atomic.h
|
||||
sed -i.old 's/__atomic_compare_exchange/__atomic_compare_exchange_db/' dbinc/atomic.h && \
|
||||
sed -i.old 's/atomic_init/atomic_init_db/' dbinc/atomic.h mp/mp_region.c mp/mp_mvcc.c mp/mp_fget.c mutex/mut_method.c mutex/mut_tas.c
|
||||
endef
|
||||
|
||||
define $(package)_config_cmds
|
||||
|
|
|
@ -15,10 +15,12 @@ public:
|
|||
|
||||
explicit reverse_lock(Lock& lock) : lock(lock) {
|
||||
lock.unlock();
|
||||
lock.swap(templock);
|
||||
}
|
||||
|
||||
~reverse_lock() {
|
||||
lock.lock();
|
||||
templock.lock();
|
||||
templock.swap(lock);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -26,6 +28,7 @@ private:
|
|||
reverse_lock& operator=(reverse_lock const&);
|
||||
|
||||
Lock& lock;
|
||||
Lock templock;
|
||||
};
|
||||
|
||||
#endif // BITCOIN_REVERSELOCK_H
|
||||
|
|
|
@ -42,22 +42,18 @@ BOOST_AUTO_TEST_CASE(reverselock_errors)
|
|||
BOOST_CHECK(failed);
|
||||
BOOST_CHECK(!lock.owns_lock());
|
||||
|
||||
// Make sure trying to lock a lock after it has been reverse locked fails
|
||||
failed = false;
|
||||
bool locked = false;
|
||||
// Locking the original lock after it has been taken by a reverse lock
|
||||
// makes no sense. Ensure that the original lock no longer owns the lock
|
||||
// after giving it to a reverse one.
|
||||
|
||||
lock.lock();
|
||||
BOOST_CHECK(lock.owns_lock());
|
||||
|
||||
try {
|
||||
{
|
||||
reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock);
|
||||
lock.lock();
|
||||
locked = true;
|
||||
} catch(...) {
|
||||
failed = true;
|
||||
BOOST_CHECK(!lock.owns_lock());
|
||||
}
|
||||
|
||||
BOOST_CHECK(locked && failed);
|
||||
BOOST_CHECK(failed);
|
||||
BOOST_CHECK(lock.owns_lock());
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,6 @@ static const CAmount nHighTransactionMaxFeeWarning = 100 * nHighTransactionFeeWa
|
|||
static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000;
|
||||
static const bool DEFAULT_WALLETBROADCAST = true;
|
||||
|
||||
class CAccountingEntry;
|
||||
class CBlockIndex;
|
||||
class CCoinControl;
|
||||
class COutput;
|
||||
|
@ -445,6 +444,86 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal transfers.
|
||||
* Database key is acentry<account><counter>.
|
||||
*/
|
||||
class CAccountingEntry
|
||||
{
|
||||
public:
|
||||
std::string strAccount;
|
||||
CAmount nCreditDebit;
|
||||
int64_t nTime;
|
||||
std::string strOtherAccount;
|
||||
std::string strComment;
|
||||
mapValue_t mapValue;
|
||||
int64_t nOrderPos; //! position in ordered transaction list
|
||||
uint64_t nEntryNo;
|
||||
|
||||
CAccountingEntry()
|
||||
{
|
||||
SetNull();
|
||||
}
|
||||
|
||||
void SetNull()
|
||||
{
|
||||
nCreditDebit = 0;
|
||||
nTime = 0;
|
||||
strAccount.clear();
|
||||
strOtherAccount.clear();
|
||||
strComment.clear();
|
||||
nOrderPos = -1;
|
||||
nEntryNo = 0;
|
||||
}
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||
if (!(nType & SER_GETHASH))
|
||||
READWRITE(nVersion);
|
||||
//! Note: strAccount is serialized as part of the key, not here.
|
||||
READWRITE(nCreditDebit);
|
||||
READWRITE(nTime);
|
||||
READWRITE(LIMITED_STRING(strOtherAccount, 65536));
|
||||
|
||||
if (!ser_action.ForRead())
|
||||
{
|
||||
WriteOrderPos(nOrderPos, mapValue);
|
||||
|
||||
if (!(mapValue.empty() && _ssExtra.empty()))
|
||||
{
|
||||
CDataStream ss(nType, nVersion);
|
||||
ss.insert(ss.begin(), '\0');
|
||||
ss << mapValue;
|
||||
ss.insert(ss.end(), _ssExtra.begin(), _ssExtra.end());
|
||||
strComment.append(ss.str());
|
||||
}
|
||||
}
|
||||
|
||||
READWRITE(LIMITED_STRING(strComment, 65536));
|
||||
|
||||
size_t nSepPos = strComment.find("\0", 0, 1);
|
||||
if (ser_action.ForRead())
|
||||
{
|
||||
mapValue.clear();
|
||||
if (std::string::npos != nSepPos)
|
||||
{
|
||||
CDataStream ss(std::vector<char>(strComment.begin() + nSepPos + 1, strComment.end()), nType, nVersion);
|
||||
ss >> mapValue;
|
||||
_ssExtra = std::vector<char>(ss.begin(), ss.end());
|
||||
}
|
||||
ReadOrderPos(nOrderPos, mapValue);
|
||||
}
|
||||
if (std::string::npos != nSepPos)
|
||||
strComment.erase(nSepPos);
|
||||
|
||||
mapValue.erase("n");
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<char> _ssExtra;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
|
@ -840,87 +919,4 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Internal transfers.
|
||||
* Database key is acentry<account><counter>.
|
||||
*/
|
||||
class CAccountingEntry
|
||||
{
|
||||
public:
|
||||
std::string strAccount;
|
||||
CAmount nCreditDebit;
|
||||
int64_t nTime;
|
||||
std::string strOtherAccount;
|
||||
std::string strComment;
|
||||
mapValue_t mapValue;
|
||||
int64_t nOrderPos; //! position in ordered transaction list
|
||||
uint64_t nEntryNo;
|
||||
|
||||
CAccountingEntry()
|
||||
{
|
||||
SetNull();
|
||||
}
|
||||
|
||||
void SetNull()
|
||||
{
|
||||
nCreditDebit = 0;
|
||||
nTime = 0;
|
||||
strAccount.clear();
|
||||
strOtherAccount.clear();
|
||||
strComment.clear();
|
||||
nOrderPos = -1;
|
||||
nEntryNo = 0;
|
||||
}
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||
if (!(nType & SER_GETHASH))
|
||||
READWRITE(nVersion);
|
||||
//! Note: strAccount is serialized as part of the key, not here.
|
||||
READWRITE(nCreditDebit);
|
||||
READWRITE(nTime);
|
||||
READWRITE(LIMITED_STRING(strOtherAccount, 65536));
|
||||
|
||||
if (!ser_action.ForRead())
|
||||
{
|
||||
WriteOrderPos(nOrderPos, mapValue);
|
||||
|
||||
if (!(mapValue.empty() && _ssExtra.empty()))
|
||||
{
|
||||
CDataStream ss(nType, nVersion);
|
||||
ss.insert(ss.begin(), '\0');
|
||||
ss << mapValue;
|
||||
ss.insert(ss.end(), _ssExtra.begin(), _ssExtra.end());
|
||||
strComment.append(ss.str());
|
||||
}
|
||||
}
|
||||
|
||||
READWRITE(LIMITED_STRING(strComment, 65536));
|
||||
|
||||
size_t nSepPos = strComment.find("\0", 0, 1);
|
||||
if (ser_action.ForRead())
|
||||
{
|
||||
mapValue.clear();
|
||||
if (std::string::npos != nSepPos)
|
||||
{
|
||||
CDataStream ss(std::vector<char>(strComment.begin() + nSepPos + 1, strComment.end()), nType, nVersion);
|
||||
ss >> mapValue;
|
||||
_ssExtra = std::vector<char>(ss.begin(), ss.end());
|
||||
}
|
||||
ReadOrderPos(nOrderPos, mapValue);
|
||||
}
|
||||
if (std::string::npos != nSepPos)
|
||||
strComment.erase(nSepPos);
|
||||
|
||||
mapValue.erase("n");
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<char> _ssExtra;
|
||||
};
|
||||
|
||||
#endif // BITCOIN_WALLET_WALLET_H
|
||||
|
|
|
@ -15,6 +15,12 @@
|
|||
#include "utiltime.h"
|
||||
#include "wallet/wallet.h"
|
||||
|
||||
#if defined(FORCE_BOOST_EMULATED_SCOPED_ENUMS)
|
||||
#define BOOST_NO_SCOPED_ENUMS
|
||||
#define BOOST_NO_CXX11_SCOPED_ENUMS
|
||||
#endif
|
||||
|
||||
#include <boost/version.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
|
Loading…
Reference in a new issue