]> Git Repo - VerusCoin.git/blob - src/asyncrpcoperation.h
Merge pull request #97 from miketout/dev
[VerusCoin.git] / src / asyncrpcoperation.h
1 // Copyright (c) 2016 The Zcash developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or https://www.opensource.org/licenses/mit-license.php .
4
5
6 #ifndef ASYNCRPCOPERATION_H
7 #define ASYNCRPCOPERATION_H
8
9 #include <string>
10 #include <atomic>
11 #include <map>
12 #include <chrono>
13 #include <memory>
14 #include <thread>
15 #include <utility>
16 #include <future>
17
18 #include <univalue.h>
19
20 using namespace std;
21
22 /**
23  * AsyncRPCOperation objects are submitted to the AsyncRPCQueue for processing.
24  * 
25  * To subclass AsyncRPCOperation, implement the main() method.
26  * Update the operation status as work is underway and completes.
27  * If main() can be interrupted, implement the cancel() method.
28  */
29
30 typedef std::string AsyncRPCOperationId;
31
32 typedef enum class operationStateEnum {
33     READY = 0,
34     EXECUTING,
35     CANCELLED,
36     FAILED,
37     SUCCESS
38 } OperationStatus;
39
40 class AsyncRPCOperation {
41 public:
42     AsyncRPCOperation();
43     virtual ~AsyncRPCOperation();
44
45     // You must implement this method in your subclass.
46     virtual void main();
47
48     // Override this method if you can interrupt execution of main() in your subclass.
49     void cancel();
50     
51     // Getters and setters
52
53     OperationStatus getState() const {
54         return state_.load();
55     }
56         
57     AsyncRPCOperationId getId() const {
58         return id_;
59     }
60    
61     int64_t getCreationTime() const {
62         return creation_time_;
63     }
64
65     // Override this method to add data to the default status object.
66     virtual UniValue getStatus() const;
67
68     UniValue getError() const;
69     
70     UniValue getResult() const;
71
72     std::string getStateAsString() const;
73     
74     int getErrorCode() const {
75         std::lock_guard<std::mutex> guard(lock_);
76         return error_code_;
77     }
78
79     std::string getErrorMessage() const {
80         std::lock_guard<std::mutex> guard(lock_);
81         return error_message_;
82     }
83
84     bool isCancelled() const {
85         return OperationStatus::CANCELLED == getState();
86     }
87
88     bool isExecuting() const {
89         return OperationStatus::EXECUTING == getState();
90     }
91
92     bool isReady() const {
93         return OperationStatus::READY == getState();
94     }
95
96     bool isFailed() const {
97         return OperationStatus::FAILED == getState();
98     }
99     
100     bool isSuccess() const {
101         return OperationStatus::SUCCESS == getState();
102     }
103
104 protected:
105     // The state_ is atomic because only it can be mutated externally.
106     // For example, the user initiates a shut down of the application, which closes
107     // the AsyncRPCQueue, which in turn invokes cancel() on all operations.
108     // The member variables below are protected rather than private in order to
109     // allow subclasses of AsyncRPCOperation the ability to access and update
110     // internal state.  Currently, all operations are executed in a single-thread
111     // by a single worker.
112     mutable std::mutex lock_;   // lock on this when read/writing non-atomics
113     UniValue result_;
114     int error_code_;
115     std::string error_message_;
116     std::atomic<OperationStatus> state_;
117     std::chrono::time_point<std::chrono::system_clock> start_time_, end_time_;  
118
119     void start_execution_clock();
120     void stop_execution_clock();
121
122     void set_state(OperationStatus state) {
123         this->state_.store(state);
124     }
125
126     void set_error_code(int errorCode) {
127         std::lock_guard<std::mutex> guard(lock_);
128         this->error_code_ = errorCode;
129     }
130
131     void set_error_message(std::string errorMessage) {
132         std::lock_guard<std::mutex> guard(lock_);
133         this->error_message_ = errorMessage;
134     }
135     
136     void set_result(UniValue v) {
137         std::lock_guard<std::mutex> guard(lock_);
138         this->result_ = v;
139     }
140     
141 private:
142
143     // Derived classes should write their own copy constructor and assignment operators
144     AsyncRPCOperation(const AsyncRPCOperation& orig);
145     AsyncRPCOperation& operator=( const AsyncRPCOperation& other );
146
147     // Initialized in the operation constructor, never to be modified again.
148     AsyncRPCOperationId id_;
149     int64_t creation_time_;
150 };
151
152 #endif /* ASYNCRPCOPERATION_H */
153
This page took 0.031893 seconds and 4 git commands to generate.