|
1 | 1 | /// Copyright (c) RenChu Wang - All Rights Reserved
|
2 | 2 |
|
3 | 3 | #include <cassert>
|
| 4 | +#include <chrono> |
| 5 | +#include <cstdlib> |
| 6 | +#include <exception> |
4 | 7 | #include <iostream>
|
5 | 8 | #include <memory>
|
6 | 9 | #include <numeric>
|
7 | 10 | #include <semaphore>
|
8 | 11 | #include <sstream>
|
| 12 | +#include <thread> |
9 | 13 | #include <vector>
|
10 | 14 |
|
11 | 15 | using namespace std;
|
@@ -33,7 +37,7 @@ class compute : enable_shared_from_this<compute> {
|
33 | 37 |
|
34 | 38 | class scoped_semaphore {
|
35 | 39 | public:
|
36 |
| - scoped_semaphore(counting_semaphore<>& sem, string by) |
| 40 | + scoped_semaphore(counting_semaphore<>& sem, const string& by) |
37 | 41 | : sem_(sem), by_(by) {
|
38 | 42 | cout << "acq(" << by_ << ")\n";
|
39 | 43 | sem_.acquire();
|
@@ -223,6 +227,31 @@ class lazy_summation : public summation, sema {
|
223 | 227 | }
|
224 | 228 | };
|
225 | 229 |
|
| 230 | +void raise_error_on_deadlock(counting_semaphore<>& sem) { |
| 231 | + for (;;) { |
| 232 | + if (!sem.try_acquire()) { |
| 233 | + cout << "--- deadlock! ---\n"; |
| 234 | + abort(); |
| 235 | + } |
| 236 | + |
| 237 | + // Lock is acquired. |
| 238 | + cout << "Acquired in deadlock detection. No deadlock\n"; |
| 239 | + sem.release(); |
| 240 | + this_thread::sleep_for(chrono::seconds(3)); |
| 241 | + } |
| 242 | +} |
| 243 | + |
| 244 | +class scoped_deadlock_detection { |
| 245 | + public: |
| 246 | + scoped_deadlock_detection(counting_semaphore<>& sem) |
| 247 | + : sem_(sem), th_(thread(raise_error_on_deadlock, ref(sem))) {} |
| 248 | + |
| 249 | + ~scoped_deadlock_detection() { th_.join(); } |
| 250 | + |
| 251 | + private: |
| 252 | + counting_semaphore<>& sem_; |
| 253 | + thread th_; |
| 254 | +}; |
226 | 255 | int main() {
|
227 | 256 | using expr = shared_ptr<compute>;
|
228 | 257 | expr one, two, three, sum_six, prod_six, twelve, thrity_six;
|
@@ -264,6 +293,7 @@ int main() {
|
264 | 293 | }
|
265 | 294 |
|
266 | 295 | counting_semaphore<> sem(1);
|
| 296 | + scoped_deadlock_detection sdd(sem); |
267 | 297 | {
|
268 | 298 | one = make_shared<lazy_literal>(1, sem);
|
269 | 299 | two = make_shared<lazy_literal>(2, sem);
|
|
0 commit comments