Reputation: 115
I run aync job thread for async io_service work.
I want to destroy this resources used for async job.
I manage the singleton object by shared pointer, below code AsyncTraceProcessor. As you know, shared_ptr automatically call the destructor when use count be 0. I want to destroy all resources safe way at that time.
I wrote code below, but there is SIGSEGV error on JVM. (This program is java native library program)
How can I solve it? In my opinion, already queue but not yet executed works throw cause this error. In this case, how can I treat remain works in safety way?
AsyncTraceProcessor::~AsyncTraceProcessor() {
cout << "AsyncTraceProcessor Desructor In, " << instance.use_count() << endl;
_once_flag;
cout <<"++++++++++flag reset success" << endl;
traceMap.clear();
cout <<"++++++++++traceMap reset success" << endl;
timer.cancel();
cout <<"++++++++++timer reset success" << endl;
async_work.~work();
cout <<"++++++++++work reset success" << endl;
async_service.~io_service();
cout <<"++++++++++io_service reset success" << endl;
async_thread.~thread();
cout <<"++++++++++thread reset success" << endl;
instance.reset();
cout <<"++++++++++instance reset success" << endl;
cout << "AsyncTraceProcessor Desructor Out " << endl;
}
Error Log
AsyncTraceProcessor Desructor In, 0
Isn't Null
++++++++++flag reset success
++++++++++traceMap reset success
++++++++++timer reset success
++++++++++work reset success
A fatal error has been detected by the Java Runtime Environment:
++++++++++io_service reset success
++++++++++thread reset success
SIGSEGV
++++++++++instance reset success
AsyncTraceProcessor Desructor Out
Upvotes: 1
Views: 1287
Reputation: 393134
C++ is unlike Java or C# - basically any garbage collecting language runtime. It has deterministic destruction. Lifetimes of object are very tangible and reliable.
async_service.~io_service();
This is explicitly invoking a destructor without deleting the object, or before the lifetime of the automatic-storage variable ends.
The consequence is that the language will still invoke the destructor when the lifetime does end.
This is not what you want.
If you need to clear the work, make it a unique_ptr<io_service::work>
so you can work_p.reset()
instead (which does call its destructor, once).
After that, just wait for the threads to complete io_service::run()
, meaning you should thread::join()
them before the thread object gets destructed.
Member objects of classes have automatic storage duration and will be destructed when leaving the destructor body. They will be destructed in the reverse order in which they are declared.
struct MyDemo {
boost::asio::io_service _ios;
std::unique_ptr<boost::asio::io_service::work> _work_p { new boost::asio::io_service::work(_ios) };
std::thread _thread { [&ios] { ios.run(); } };
~MyDemo() {
_work_p.reset();
if (_thread.joinable())
_thread.join();
} // members are destructed by the language
};
Upvotes: 1