Skip to content

Commit

Permalink
Merge pull request #21 from CryptoManiac/master
Browse files Browse the repository at this point in the history
Recent updates
  • Loading branch information
0xDEADFACE committed Jul 24, 2014
2 parents 5ddff22 + 4e7a581 commit 11e2717
Show file tree
Hide file tree
Showing 44 changed files with 1,291 additions and 605 deletions.
1 change: 1 addition & 0 deletions novacoin-qt.pro
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ HEADERS += src/qt/bitcoingui.h \
src/sync.h \
src/util.h \
src/timestamps.h \
src/hash.h \
src/uint256.h \
src/kernel.h \
src/scrypt.h \
Expand Down
1 change: 1 addition & 0 deletions src/addrman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "addrman.h"
#include "hash.h"

using namespace std;

Expand Down
8 changes: 4 additions & 4 deletions src/bitcoinrpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,6 @@ static const CRPCCommand vRPCCommands[] =
{ "getsubsidy", &getsubsidy, true, false },
{ "getmininginfo", &getmininginfo, true, false },
{ "getnewaddress", &getnewaddress, true, false },
{ "getnewpubkey", &getnewpubkey, true, false },
{ "getaccountaddress", &getaccountaddress, true, false },
{ "setaccount", &setaccount, true, false },
{ "getaccount", &getaccount, false, false },
Expand All @@ -265,7 +264,6 @@ static const CRPCCommand vRPCCommands[] =
{ "walletlock", &walletlock, true, false },
{ "encryptwallet", &encryptwallet, false, false },
{ "validateaddress", &validateaddress, true, false },
{ "validatepubkey", &validatepubkey, true, false },
{ "getbalance", &getbalance, false, false },
{ "move", &movecmd, false, false },
{ "sendfrom", &sendfrom, false, false },
Expand All @@ -292,6 +290,7 @@ static const CRPCCommand vRPCCommands[] =
{ "dumpwallet", &dumpwallet, true, false },
{ "importwallet", &importwallet, false, false },
{ "importprivkey", &importprivkey, false, false },
{ "importaddress", &importaddress, false, true },
{ "listunspent", &listunspent, false, false },
{ "getrawtransaction", &getrawtransaction, false, false },
{ "createrawtransaction", &createrawtransaction, false, false },
Expand Down Expand Up @@ -668,7 +667,7 @@ class AcceptedConnectionImpl : public AcceptedConnection
void ThreadRPCServer(void* parg)
{
// Make this thread recognisable as the RPC listener
RenameThread("bitcoin-rpclist");
RenameThread("novacoin-rpclist");

try
{
Expand Down Expand Up @@ -968,7 +967,7 @@ static CCriticalSection cs_THREAD_RPCHANDLER;
void ThreadRPCServer3(void* parg)
{
// Make this thread recognisable as the RPC handler
RenameThread("bitcoin-rpchand");
RenameThread("novacoin-rpchand");

{
LOCK(cs_THREAD_RPCHANDLER);
Expand Down Expand Up @@ -1229,6 +1228,7 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector<std::stri
if (strMethod == "signrawtransaction" && n > 1) ConvertTo<Array>(params[1], true);
if (strMethod == "signrawtransaction" && n > 2) ConvertTo<Array>(params[2], true);
if (strMethod == "keypoolrefill" && n > 0) ConvertTo<boost::int64_t>(params[0]);
if (strMethod == "importaddress" && n > 2) ConvertTo<bool>(params[2]);

return params;
}
Expand Down
3 changes: 1 addition & 2 deletions src/bitcoinrpc.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ extern json_spirit::Value dumpwallet(const json_spirit::Array& params, bool fHel
extern json_spirit::Value importwallet(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value dumpprivkey(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp
extern json_spirit::Value importprivkey(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value importaddress(const json_spirit::Array& params, bool fHelp);

extern json_spirit::Value sendalert(const json_spirit::Array& params, bool fHelp);

Expand Down Expand Up @@ -196,8 +197,6 @@ extern json_spirit::Value checkwallet(const json_spirit::Array& params, bool fHe
extern json_spirit::Value repairwallet(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value resendtx(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value makekeypair(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value validatepubkey(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getnewpubkey(const json_spirit::Array& params, bool fHelp);

extern json_spirit::Value getrawtransaction(const json_spirit::Array& params, bool fHelp); // in rcprawtransaction.cpp
extern json_spirit::Value listunspent(const json_spirit::Array& params, bool fHelp);
Expand Down
208 changes: 208 additions & 0 deletions src/checkqueue.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
// Copyright (c) 2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef CHECKQUEUE_H
#define CHECKQUEUE_H

#include <algorithm>
#include <vector>

#include <boost/foreach.hpp>
#include <boost/thread/condition_variable.hpp>
#include <boost/thread/locks.hpp>
#include <boost/thread/mutex.hpp>

template<typename T> class CCheckQueueControl;

/** Queue for verifications that have to be performed.
* The verifications are represented by a type T, which must provide an
* operator(), returning a bool.
*
* One thread (the master) is assumed to push batches of verifications
* onto the queue, where they are processed by N-1 worker threads. When
* the master is done adding work, it temporarily joins the worker pool
* as an N'th worker, until all jobs are done.
*/
template<typename T> class CCheckQueue {
private:
// Mutex to protect the inner state
boost::mutex mutex;

// Worker threads block on this when out of work
boost::condition_variable condWorker;

// Master thread blocks on this when out of work
boost::condition_variable condMaster;

// Quit method blocks on this until all workers are gone
boost::condition_variable condQuit;

// The queue of elements to be processed.
// As the order of booleans doesn't matter, it is used as a LIFO (stack)
std::vector<T> queue;

// The number of workers (including the master) that are idle.
int nIdle;

// The total number of workers (including the master).
int nTotal;

// The temporary evaluation result.
bool fAllOk;

// Number of verifications that haven't completed yet.
// This includes elements that are not anymore in queue, but still in
// worker's own batches.
unsigned int nTodo;

// Whether we're shutting down.
bool fQuit;

// The maximum number of elements to be processed in one batch
unsigned int nBatchSize;

// Internal function that does bulk of the verification work.
bool Loop(bool fMaster = false) {
boost::condition_variable &cond = fMaster ? condMaster : condWorker;
std::vector<T> vChecks;
vChecks.reserve(nBatchSize);
unsigned int nNow = 0;
bool fOk = true;
do {
{
boost::unique_lock<boost::mutex> lock(mutex);
// first do the clean-up of the previous loop run (allowing us to do it in the same critsect)
if (nNow) {
fAllOk &= fOk;
nTodo -= nNow;
if (nTodo == 0 && !fMaster)
// We processed the last element; inform the master he can exit and return the result
condMaster.notify_one();
} else {
// first iteration
nTotal++;
}
// logically, the do loop starts here
while (queue.empty()) {
if ((fMaster || fQuit) && nTodo == 0) {
nTotal--;
if (nTotal==0)
condQuit.notify_one();
bool fRet = fAllOk;
// reset the status for new work later
if (fMaster)
fAllOk = true;
// return the current status
return fRet;
}
nIdle++;
cond.wait(lock); // wait
nIdle--;
}
// Decide how many work units to process now.
// * Do not try to do everything at once, but aim for increasingly smaller batches so
// all workers finish approximately simultaneously.
// * Try to account for idle jobs which will instantly start helping.
// * Don't do batches smaller than 1 (duh), or larger than nBatchSize.
nNow = std::max(1U, std::min(nBatchSize, (unsigned int)queue.size() / (nTotal + nIdle + 1)));
vChecks.resize(nNow);
for (unsigned int i = 0; i < nNow; i++) {
// We want the lock on the mutex to be as short as possible, so swap jobs from the global
// queue to the local batch vector instead of copying.
vChecks[i].swap(queue.back());
queue.pop_back();
}
// Check whether we need to do work at all
fOk = fAllOk;
}
// execute work
BOOST_FOREACH(T &check, vChecks)
if (fOk)
fOk = check();
vChecks.clear();
} while(true);
}

public:
// Create a new check queue
CCheckQueue(unsigned int nBatchSizeIn) :
nIdle(0), nTotal(0), fAllOk(true), nTodo(0), fQuit(false), nBatchSize(nBatchSizeIn) {}

// Worker thread
void Thread() {
Loop();
}

// Wait until execution finishes, and return whether all evaluations where succesful.
bool Wait() {
return Loop(true);
}

// Add a batch of checks to the queue
void Add(std::vector<T> &vChecks) {
boost::unique_lock<boost::mutex> lock(mutex);
BOOST_FOREACH(T &check, vChecks) {
queue.push_back(T());
check.swap(queue.back());
}
nTodo += vChecks.size();
if (vChecks.size() == 1)
condWorker.notify_one();
else if (vChecks.size() > 1)
condWorker.notify_all();
}

// Shut the queue down
void Quit() {
boost::unique_lock<boost::mutex> lock(mutex);
fQuit = true;
// No need to wake the master, as he will quit automatically when all jobs are
// done.
condWorker.notify_all();

while (nTotal > 0)
condQuit.wait(lock);
}

friend class CCheckQueueControl<T>;
};

/** RAII-style controller object for a CCheckQueue that guarantees the passed
* queue is finished before continuing.
*/
template<typename T> class CCheckQueueControl {
private:
CCheckQueue<T> *pqueue;
bool fDone;

public:
CCheckQueueControl(CCheckQueue<T> *pqueueIn) : pqueue(pqueueIn), fDone(false) {
// passed queue is supposed to be unused, or NULL
if (pqueue != NULL) {
assert(pqueue->nTotal == pqueue->nIdle);
assert(pqueue->nTodo == 0);
assert(pqueue->fAllOk == true);
}
}

bool Wait() {
if (pqueue == NULL)
return true;
bool fRet = pqueue->Wait();
fDone = true;
return fRet;
}

void Add(std::vector<T> &vChecks) {
if (pqueue != NULL)
pqueue->Add(vChecks);
}

~CCheckQueueControl() {
if (!fDone)
Wait();
}
};

#endif
Loading

0 comments on commit 11e2717

Please sign in to comment.