@op-engineering/op-sqlite 2.0.0 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,129 +2,116 @@
2
2
 
3
3
  namespace opsqlite {
4
4
 
5
- ThreadPool::ThreadPool() : done(false)
6
- {
7
- // This returns the number of threads supported by the system. If the
8
- // function can't figure out this information, it returns 0. 0 is not good,
9
- // so we create at least 1
10
- auto numberOfThreads = std::thread::hardware_concurrency();
11
- if (numberOfThreads == 0)
12
- {
13
- numberOfThreads = 1;
14
- }
15
-
16
- for (unsigned i = 0; i < numberOfThreads; ++i)
17
- {
18
- // The threads will execute the private member `doWork`. Note that we need
19
- // to pass a reference to the function (namespaced with the class name) as
20
- // the first argument, and the current object as second argument
21
- threads.push_back(std::thread(&ThreadPool::doWork, this));
22
- }
23
- }
5
+ ThreadPool::ThreadPool() : done(false) {
6
+ // This returns the number of threads supported by the system. If the
7
+ // function can't figure out this information, it returns 0. 0 is not good,
8
+ // so we create at least 1
9
+ auto numberOfThreads = std::thread::hardware_concurrency();
10
+ if (numberOfThreads == 0) {
11
+ numberOfThreads = 1;
12
+ }
24
13
 
25
- // The destructor joins all the threads so the program can exit gracefully.
26
- // This will be executed if there is any exception (e.g. creating the threads)
27
- ThreadPool::~ThreadPool()
28
- {
29
- // So threads know it's time to shut down
30
- done = true;
31
-
32
- // Wake up all the threads, so they can finish and be joined
33
- workQueueConditionVariable.notify_all();
34
-
35
- for (auto &thread : threads)
36
- {
37
- if (thread.joinable())
38
- {
39
- thread.join();
40
- }
41
- }
42
-
43
- threads.clear();
44
- }
14
+ for (unsigned i = 0; i < numberOfThreads; ++i) {
15
+ // The threads will execute the private member `doWork`. Note that we need
16
+ // to pass a reference to the function (namespaced with the class name) as
17
+ // the first argument, and the current object as second argument
18
+ threads.push_back(std::thread(&ThreadPool::doWork, this));
19
+ }
20
+ }
45
21
 
46
- // This function will be called by the server every time there is a request
47
- // that needs to be processed by the thread pool
48
- void ThreadPool::queueWork(std::function<void(void)> task)
49
- {
50
- // Grab the mutex
51
- std::lock_guard<std::mutex> g(workQueueMutex);
52
-
53
- // Push the request to the queue
54
- workQueue.push(task);
55
-
56
- // Notify one thread that there are requests to process
57
- workQueueConditionVariable.notify_one();
22
+ // The destructor joins all the threads so the program can exit gracefully.
23
+ // This will be executed if there is any exception (e.g. creating the threads)
24
+ ThreadPool::~ThreadPool() {
25
+ // So threads know it's time to shut down
26
+ done = true;
27
+
28
+ // Wake up all the threads, so they can finish and be joined
29
+ workQueueConditionVariable.notify_all();
30
+
31
+ for (auto &thread : threads) {
32
+ if (thread.joinable()) {
33
+ thread.join();
58
34
  }
35
+ }
36
+
37
+ threads.clear();
38
+ }
39
+
40
+ // This function will be called by the server every time there is a request
41
+ // that needs to be processed by the thread pool
42
+ void ThreadPool::queueWork(std::function<void(void)> task) {
43
+ // Grab the mutex
44
+ std::lock_guard<std::mutex> g(workQueueMutex);
45
+
46
+ // Push the request to the queue
47
+ workQueue.push(task);
48
+
49
+ // Notify one thread that there are requests to process
50
+ workQueueConditionVariable.notify_one();
51
+ }
52
+
53
+ // Function used by the threads to grab work from the queue
54
+ void ThreadPool::doWork() {
55
+ // Loop while the queue is not destructing
56
+ while (!done) {
57
+ std::function<void(void)> task;
59
58
 
60
- // Function used by the threads to grab work from the queue
61
- void ThreadPool::doWork()
59
+ // Create a scope, so we don't lock the queue for longer than necessary
62
60
  {
63
- // Loop while the queue is not destructing
64
- while (!done)
65
- {
66
- std::function<void(void)> task;
67
-
68
- // Create a scope, so we don't lock the queue for longer than necessary
69
- {
70
- std::unique_lock<std::mutex> g(workQueueMutex);
71
- workQueueConditionVariable.wait(g, [&]
72
- {
73
- // Only wake up if there are elements in the queue or the program is
74
- // shutting down
75
- return !workQueue.empty() || done; });
76
-
77
- // If we are shutting down exit witout trying to process more work
78
- if (done)
79
- {
80
- break;
81
- }
82
-
83
- task = workQueue.front();
84
- workQueue.pop();
85
- }
86
- ++busy;
87
- task();
88
- --busy;
89
- }
90
- }
61
+ std::unique_lock<std::mutex> g(workQueueMutex);
62
+ workQueueConditionVariable.wait(g, [&] {
63
+ // Only wake up if there are elements in the queue or the program is
64
+ // shutting down
65
+ return !workQueue.empty() || done;
66
+ });
67
+
68
+ // If we are shutting down exit witout trying to process more work
69
+ if (done) {
70
+ break;
71
+ }
91
72
 
92
- void ThreadPool::waitFinished() {
93
- std::unique_lock<std::mutex> g(workQueueMutex);
94
- workQueueConditionVariable.wait(g, [&]{ return workQueue.empty() && (busy == 0); });
73
+ task = workQueue.front();
74
+ workQueue.pop();
95
75
  }
76
+ ++busy;
77
+ task();
78
+ --busy;
79
+ }
80
+ }
81
+
82
+ void ThreadPool::waitFinished() {
83
+ std::unique_lock<std::mutex> g(workQueueMutex);
84
+ workQueueConditionVariable.wait(
85
+ g, [&] { return workQueue.empty() && (busy == 0); });
86
+ }
96
87
 
97
- void ThreadPool::restartPool() {
98
- // So threads know it's time to shut down
99
- done = true;
100
-
101
- // Wake up all the threads, so they can finish and be joined
102
- workQueueConditionVariable.notify_all();
103
-
104
- for (auto &thread : threads)
105
- {
106
- if (thread.joinable())
107
- {
108
- thread.join();
109
- }
110
- }
111
-
112
- threads.clear();
113
-
114
- auto numberOfThreads = std::thread::hardware_concurrency();
115
- if (numberOfThreads == 0)
116
- {
117
- numberOfThreads = 1;
118
- }
119
-
120
- for (unsigned i = 0; i < numberOfThreads; ++i)
121
- {
122
- // The threads will execute the private member `doWork`. Note that we need
123
- // to pass a reference to the function (namespaced with the class name) as
124
- // the first argument, and the current object as second argument
125
- threads.push_back(std::thread(&ThreadPool::doWork, this));
126
- }
127
-
128
- done = false;
88
+ void ThreadPool::restartPool() {
89
+ // So threads know it's time to shut down
90
+ done = true;
91
+
92
+ // Wake up all the threads, so they can finish and be joined
93
+ workQueueConditionVariable.notify_all();
94
+
95
+ for (auto &thread : threads) {
96
+ if (thread.joinable()) {
97
+ thread.join();
129
98
  }
99
+ }
100
+
101
+ threads.clear();
102
+
103
+ auto numberOfThreads = std::thread::hardware_concurrency();
104
+ if (numberOfThreads == 0) {
105
+ numberOfThreads = 1;
106
+ }
107
+
108
+ for (unsigned i = 0; i < numberOfThreads; ++i) {
109
+ // The threads will execute the private member `doWork`. Note that we need
110
+ // to pass a reference to the function (namespaced with the class name) as
111
+ // the first argument, and the current object as second argument
112
+ threads.push_back(std::thread(&ThreadPool::doWork, this));
113
+ }
114
+
115
+ done = false;
130
116
  }
117
+ } // namespace opsqlite
package/cpp/ThreadPool.h CHANGED
@@ -13,35 +13,35 @@ namespace opsqlite {
13
13
 
14
14
  class ThreadPool {
15
15
  public:
16
- ThreadPool();
17
- ~ThreadPool();
18
- void queueWork(std::function<void(void)> task);
19
- void waitFinished();
20
- void restartPool();
21
-
16
+ ThreadPool();
17
+ ~ThreadPool();
18
+ void queueWork(std::function<void(void)> task);
19
+ void waitFinished();
20
+ void restartPool();
21
+
22
22
  private:
23
- unsigned int busy;
24
- // This condition variable is used for the threads to wait until there is work
25
- // to do
26
- std::condition_variable_any workQueueConditionVariable;
27
-
28
- // We store the threads in a vector, so we can later stop them gracefully
29
- std::vector<std::thread> threads;
30
-
31
- // Mutex to protect workQueue
32
- std::mutex workQueueMutex;
33
-
34
- // Queue of requests waiting to be processed
35
- std::queue<std::function<void(void)>> workQueue;
36
-
37
- // This will be set to true when the thread pool is shutting down. This tells
38
- // the threads to stop looping and finish
39
- bool done;
40
-
41
- // Function used by the threads to grab work from the queue
42
- void doWork();
23
+ unsigned int busy;
24
+ // This condition variable is used for the threads to wait until there is work
25
+ // to do
26
+ std::condition_variable_any workQueueConditionVariable;
27
+
28
+ // We store the threads in a vector, so we can later stop them gracefully
29
+ std::vector<std::thread> threads;
30
+
31
+ // Mutex to protect workQueue
32
+ std::mutex workQueueMutex;
33
+
34
+ // Queue of requests waiting to be processed
35
+ std::queue<std::function<void(void)>> workQueue;
36
+
37
+ // This will be set to true when the thread pool is shutting down. This tells
38
+ // the threads to stop looping and finish
39
+ bool done;
40
+
41
+ // Function used by the threads to grab work from the queue
42
+ void doWork();
43
43
  };
44
44
 
45
- }
45
+ } // namespace opsqlite
46
46
 
47
47
  #endif /* ThreadPool_h */