2016-09-02 19:21:42 -07:00
|
|
|
// Copyright (c) 2016 The Zcash developers
|
2016-08-16 10:33:04 -07:00
|
|
|
// Distributed under the MIT software license, see the accompanying
|
2019-07-18 07:16:09 -07:00
|
|
|
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
|
2016-08-16 10:33:04 -07:00
|
|
|
|
|
|
|
#ifndef ASYNCRPCQUEUE_H
|
|
|
|
#define ASYNCRPCQUEUE_H
|
|
|
|
|
|
|
|
#include "asyncrpcoperation.h"
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
#include <string>
|
|
|
|
#include <chrono>
|
|
|
|
#include <queue>
|
|
|
|
#include <unordered_map>
|
|
|
|
#include <vector>
|
|
|
|
#include <future>
|
|
|
|
#include <thread>
|
|
|
|
#include <utility>
|
|
|
|
#include <memory>
|
|
|
|
|
|
|
|
|
|
|
|
typedef std::unordered_map<AsyncRPCOperationId, std::shared_ptr<AsyncRPCOperation> > AsyncRPCOperationMap;
|
|
|
|
|
|
|
|
|
|
|
|
class AsyncRPCQueue {
|
|
|
|
public:
|
2016-09-04 08:12:46 -07:00
|
|
|
static shared_ptr<AsyncRPCQueue> sharedInstance();
|
|
|
|
|
2016-08-16 10:33:04 -07:00
|
|
|
AsyncRPCQueue();
|
|
|
|
virtual ~AsyncRPCQueue();
|
|
|
|
|
|
|
|
// We don't want queue to be copied or moved around
|
|
|
|
AsyncRPCQueue(AsyncRPCQueue const&) = delete; // Copy construct
|
|
|
|
AsyncRPCQueue(AsyncRPCQueue&&) = delete; // Move construct
|
|
|
|
AsyncRPCQueue& operator=(AsyncRPCQueue const&) = delete; // Copy assign
|
|
|
|
AsyncRPCQueue& operator=(AsyncRPCQueue &&) = delete; // Move assign
|
|
|
|
|
|
|
|
void addWorker();
|
2016-08-28 19:50:39 -07:00
|
|
|
size_t getNumberOfWorkers() const;
|
|
|
|
bool isClosed() const;
|
2016-09-02 19:21:42 -07:00
|
|
|
bool isFinishing() const;
|
|
|
|
void close(); // close queue and cancel all operations
|
|
|
|
void finish(); // close queue but finishing existing operations
|
|
|
|
void closeAndWait(); // block thread until all threads have terminated.
|
|
|
|
void finishAndWait(); // block thread until existing operations have finished, threads terminated
|
|
|
|
void cancelAllOperations(); // mark all operations in the queue as cancelled
|
2016-08-28 19:50:39 -07:00
|
|
|
size_t getOperationCount() const;
|
|
|
|
std::shared_ptr<AsyncRPCOperation> getOperationForId(AsyncRPCOperationId) const;
|
2016-08-16 10:33:04 -07:00
|
|
|
std::shared_ptr<AsyncRPCOperation> popOperationForId(AsyncRPCOperationId);
|
|
|
|
void addOperation(const std::shared_ptr<AsyncRPCOperation> &ptrOperation);
|
2016-08-28 19:50:39 -07:00
|
|
|
std::vector<AsyncRPCOperationId> getAllOperationIds() const;
|
2016-08-16 10:33:04 -07:00
|
|
|
|
|
|
|
private:
|
2016-09-02 19:21:42 -07:00
|
|
|
// addWorker() will spawn a new thread on run())
|
2016-08-28 19:50:39 -07:00
|
|
|
void run(size_t workerId);
|
2016-09-02 19:21:42 -07:00
|
|
|
void wait_for_worker_threads();
|
2016-08-28 19:50:39 -07:00
|
|
|
|
|
|
|
// Why this is not a recursive lock: http://www.zaval.org/resources/library/butenhof1.html
|
|
|
|
mutable std::mutex lock_;
|
|
|
|
std::condition_variable condition_;
|
2016-09-02 19:21:42 -07:00
|
|
|
std::atomic<bool> closed_;
|
|
|
|
std::atomic<bool> finish_;
|
2016-08-28 19:50:39 -07:00
|
|
|
AsyncRPCOperationMap operation_map_;
|
|
|
|
std::queue <AsyncRPCOperationId> operation_id_queue_;
|
|
|
|
std::vector<std::thread> workers_;
|
2016-08-16 10:33:04 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|