Skip to content

Commit 3a76322

Browse files
committed
add getDefaultUncaughtExceptionHandler; add stop() function for simple_task.
1 parent a848e85 commit 3a76322

File tree

5 files changed

+57
-19
lines changed

5 files changed

+57
-19
lines changed

add_ons/simple_task/simple_task.hpp

+31-7
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include <atomic>
4242
#include <condition_variable>
4343
#include <utility>
44+
#include <stdexcept>
4445
#include "promise-cpp/promise.hpp"
4546

4647

@@ -55,11 +56,13 @@ class Service {
5556
Tasks tasks_;
5657
std::recursive_mutex mutex_;
5758
std::condition_variable_any cond_;
58-
std::atomic<bool> isAutoExit_;
59+
std::atomic<bool> isAutoStop_;
60+
std::atomic<bool> isStop_;
5961

6062
public:
6163
Service()
62-
: isAutoExit_(true) {
64+
: isAutoStop_(true)
65+
, isStop_(false) {
6366
}
6467

6568
// delay for milliseconds
@@ -92,9 +95,9 @@ class Service {
9295
}
9396

9497
// Set if the io thread will auto exist if no waiting tasks and timers.
95-
void setAutoExit(bool isAutoExit) {
98+
void setAutoStop(bool isAutoExit) {
9699
std::lock_guard<std::recursive_mutex> lock(mutex_);
97-
isAutoExit_ = isAutoExit;
100+
isAutoStop_ = isAutoExit;
98101
cond_.notify_one();
99102
}
100103

@@ -103,14 +106,14 @@ class Service {
103106
void run() {
104107
std::unique_lock<std::recursive_mutex> lock(mutex_);
105108

106-
while(!isAutoExit_ || tasks_.size() > 0 || timers_.size() > 0){
109+
while(!isStop_ && (!isAutoStop_ || tasks_.size() > 0 || timers_.size() > 0)) {
107110

108111
if (tasks_.size() == 0 && timers_.size() == 0) {
109112
cond_.wait(lock);
110113
continue;
111114
}
112115

113-
while (timers_.size() > 0) {
116+
while (!isStop_ && timers_.size() > 0) {
114117
TimePoint now = std::chrono::steady_clock::now();
115118
TimePoint time = timers_.begin()->first;
116119
if (time <= now) {
@@ -128,7 +131,7 @@ class Service {
128131
}
129132

130133
// Check fixed size of tasks in this loop, so that timer have a chance to run.
131-
if(tasks_.size() > 0) {
134+
if(!isStop_ && tasks_.size() > 0) {
132135
size_t size = tasks_.size();
133136
for(size_t i = 0; i < size; ++i){
134137
Defer defer = tasks_.front();
@@ -137,6 +140,27 @@ class Service {
137140
}
138141
}
139142
}
143+
144+
// Clear pending timers and tasks
145+
while (timers_.size() > 0 || tasks_.size()) {
146+
while (timers_.size() > 0) {
147+
Defer defer = timers_.begin()->second;
148+
timers_.erase(timers_.begin());
149+
defer.reject(std::runtime_error("service stopped"));
150+
}
151+
while (tasks_.size() > 0) {
152+
Defer defer = tasks_.front();
153+
tasks_.pop_front();
154+
defer.reject(std::runtime_error("service stopped"));
155+
}
156+
}
157+
}
158+
159+
// stop the service loop
160+
void stop() {
161+
std::lock_guard<std::recursive_mutex> lock(mutex_);
162+
isStop_ = true;
163+
cond_.notify_one();
140164
}
141165
};
142166

example/multithread_test.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ int main() {
107107
return test_switch(io, 100);
108108
}).then([&]() {
109109

110-
io.setAutoExit(false);
110+
io.setAutoStop(false);
111111
// Run in new thread
112112
return newPromise([](Defer &defer) {
113113
std::thread([=]() {
@@ -127,7 +127,7 @@ int main() {
127127
});
128128

129129
}).then([&]() {
130-
io.setAutoExit(true);
130+
io.setAutoStop(true);
131131

132132
return test_switch(io, 1000);
133133
}).then([&, loop]() {

example/simple_benchmark_test.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ int main() {
9494
test_switch(io, 1).then([&]() {
9595
return test_switch(io, 1000);
9696
}).then([&]() {
97+
io.stop();
9798
return test_switch(io, 10000);
9899
}).then([&]() {
99100
return test_switch(io, 100000);

include/promise-cpp/promise.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ struct PromiseHolder {
100100

101101
PROMISE_API void dump() const;
102102
PROMISE_API static any *getUncaughtExceptionHandler();
103+
PROMISE_API static any *getDefaultUncaughtExceptionHandler();
103104
PROMISE_API static void onUncaughtException(const any &arg);
104105
PROMISE_API static void handleUncaughtException(const any &onUncaughtException);
105106
};

include/promise-cpp/promise_inl.hpp

+22-10
Original file line numberDiff line numberDiff line change
@@ -402,24 +402,36 @@ PromiseHolder::~PromiseHolder() {
402402
}
403403
}
404404

405+
406+
405407
any *PromiseHolder::getUncaughtExceptionHandler() {
406408
static any onUncaughtException;
407409
return &onUncaughtException;
408410
}
409411

412+
any *PromiseHolder::getDefaultUncaughtExceptionHandler() {
413+
static any defaultUncaughtExceptionHandler = [](Promise &d) {
414+
d.fail([](const std::runtime_error &err) {
415+
fprintf(stderr, "onUncaughtException in line %d, %s\n", __LINE__, err.what());
416+
}).fail([]() {
417+
//go here for all other uncaught parameters.
418+
fprintf(stderr, "onUncaughtException in line %d\n", __LINE__);
419+
});
420+
};
421+
422+
return &defaultUncaughtExceptionHandler;
423+
}
424+
410425
void PromiseHolder::onUncaughtException(const any &arg) {
411426
any *onUncaughtException = getUncaughtExceptionHandler();
412-
if (onUncaughtException != nullptr && !onUncaughtException->empty()) {
413-
try {
414-
onUncaughtException->call(reject(arg));
415-
}
416-
catch (...) {
417-
// std::rethrow_exception(std::current_exception());
418-
fprintf(stderr, "onUncaughtException in line %d\n", __LINE__);
419-
}
427+
if (onUncaughtException == nullptr || onUncaughtException->empty()) {
428+
onUncaughtException = getDefaultUncaughtExceptionHandler();
420429
}
421-
else {
422-
//throw arg;
430+
431+
try {
432+
onUncaughtException->call(reject(arg));
433+
}
434+
catch (...) {
423435
fprintf(stderr, "onUncaughtException in line %d\n", __LINE__);
424436
}
425437
}

0 commit comments

Comments
 (0)