Fabcoin Core  0.16.2
P2P Digital Currency
Worker.cpp
Go to the documentation of this file.
1 /*
2  This file is part of cpp-ethereum.
3 
4  cpp-ethereum is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  cpp-ethereum is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
16 */
22 #include "Worker.h"
23 
24 #include <chrono>
25 #include <thread>
26 #include "Log.h"
27 using namespace std;
28 using namespace dev;
29 
30 void Worker::startWorking()
31 {
32 // cnote << "startWorking for thread" << m_name;
33  Guard l(x_work);
34  if (m_work)
35  {
36  WorkerState ex = WorkerState::Stopped;
37  m_state.compare_exchange_strong(ex, WorkerState::Starting);
38  }
39  else
40  {
41  m_state = WorkerState::Starting;
42  m_work.reset(new thread([&]()
43  {
44  setThreadName(m_name.c_str());
45 // cnote << "Thread begins";
46  while (m_state != WorkerState::Killing)
47  {
48  WorkerState ex = WorkerState::Starting;
49  bool ok = m_state.compare_exchange_strong(ex, WorkerState::Started);
50 // cnote << "Trying to set Started: Thread was" << (unsigned)ex << "; " << ok;
51  (void)ok;
52 
53  try
54  {
55  startedWorking();
56  workLoop();
57  doneWorking();
58  }
59  catch (std::exception const& _e)
60  {
61  clog(WarnChannel) << "Exception thrown in Worker thread: " << _e.what();
62  }
63 
64 // ex = WorkerState::Stopping;
65 // m_state.compare_exchange_strong(ex, WorkerState::Stopped);
66 
67  ex = m_state.exchange(WorkerState::Stopped);
68 // cnote << "State: Stopped: Thread was" << (unsigned)ex;
69  if (ex == WorkerState::Killing || ex == WorkerState::Starting)
70  m_state.exchange(ex);
71 
72 // cnote << "Waiting until not Stopped...";
73  DEV_TIMED_ABOVE("Worker stopping", 100)
74  while (m_state == WorkerState::Stopped)
75  this_thread::sleep_for(chrono::milliseconds(20));
76  }
77  }));
78 // cnote << "Spawning" << m_name;
79  }
80  DEV_TIMED_ABOVE("Start worker", 100)
81  while (m_state == WorkerState::Starting)
82  this_thread::sleep_for(chrono::microseconds(20));
83 }
84 
85 void Worker::stopWorking()
86 {
87  DEV_GUARDED(x_work)
88  if (m_work)
89  {
90  WorkerState ex = WorkerState::Started;
91  m_state.compare_exchange_strong(ex, WorkerState::Stopping);
92 
93  DEV_TIMED_ABOVE("Stop worker", 100)
94  while (m_state != WorkerState::Stopped)
95  this_thread::sleep_for(chrono::microseconds(20));
96  }
97 }
98 
99 void Worker::terminate()
100 {
101 // cnote << "stopWorking for thread" << m_name;
102  DEV_GUARDED(x_work)
103  if (m_work)
104  {
105  m_state.exchange(WorkerState::Killing);
106 
107  DEV_TIMED_ABOVE("Terminate worker", 100)
108  m_work->join();
109 
110  m_work.reset();
111  }
112 }
113 
114 void Worker::workLoop()
115 {
116  while (m_state == WorkerState::Started)
117  {
118  if (m_idleWaitMs)
119  this_thread::sleep_for(chrono::milliseconds(m_idleWaitMs));
120  doWork();
121  }
122 }
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
Definition: Arith256.cpp:15
std::hash for asio::adress
Definition: Common.h:323
#define DEV_TIMED_ABOVE(S, MS)
Definition: Common.h:295
#define DEV_GUARDED(MUTEX)
Simple block guard.
Definition: Guards.h:144
WorkerState
Definition: Worker.h:39
std::lock_guard< std::mutex > Guard
Definition: Guards.h:41
void setThreadName(std::string const &_n)
Set the current thread&#39;s log name.
#define clog(X)
Definition: Log.h:295