Merge pull request #2570 from oneandonlydean/fix/libc-future-result-exception-2540
fix(libc): release future results' exceptions through libc on Windows
This commit is contained in:
commit
6284b64fa5
|
|
@ -1,12 +1,23 @@
|
|||
#include <exception>
|
||||
|
||||
#ifndef _LIBCPP_VERSION
|
||||
#include <future>
|
||||
|
||||
extern "C" {
|
||||
void ExceptionPointerAddref(std::exception_ptr* self) noexcept asm("_ZNSt15__exception_ptr13exception_ptr9_M_addrefEv");
|
||||
void ExceptionPointerRelease(std::exception_ptr* self) noexcept asm("_ZNSt15__exception_ptr13exception_ptr10_M_releaseEv");
|
||||
void* ExceptionPointerGet(const std::exception_ptr* self) noexcept asm("_ZNKSt15__exception_ptr13exception_ptr6_M_getEv");
|
||||
void ExceptionPointerConstruct(std::exception_ptr* self, void* exception) noexcept asm("_ZNSt15__exception_ptr13exception_ptrC1EPv");
|
||||
const std::type_info* ExceptionPointerType(const std::exception_ptr* self) noexcept asm("_ZNKSt15__exception_ptr13exception_ptr20__cxa_exception_typeEv");
|
||||
void FutureResultDestroy(std::__future_base::_Result_base* self) noexcept asm("_ZNSt13__future_base12_Result_baseD2Ev");
|
||||
|
||||
void FutureResultDestroy(std::__future_base::_Result_base* self) noexcept {
|
||||
self->_M_error.~exception_ptr();
|
||||
}
|
||||
|
||||
void APS5_VABI _ZNSt13__future_base12_Result_baseD2Ev_nid_postfix(std::__future_base::_Result_base* self) noexcept {
|
||||
FutureResultDestroy(self);
|
||||
}
|
||||
|
||||
void APS5_VABI _ZNSt15__exception_ptr13exception_ptr9_M_addrefEv_nid_postfix(std::exception_ptr* self) noexcept {
|
||||
ExceptionPointerAddref(self);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include <atomic>
|
||||
#include <array>
|
||||
#include <exception>
|
||||
#include <future>
|
||||
#include <thread>
|
||||
#include <cstddef>
|
||||
#include <typeinfo>
|
||||
|
|
@ -105,9 +106,30 @@ static void testExceptionPointer() {
|
|||
if (std::current_exception()) throw std::runtime_error("stale current exception");
|
||||
}
|
||||
|
||||
static void testFutureException() {
|
||||
std::atomic<int> count{0};
|
||||
{
|
||||
std::promise<void> promise;
|
||||
auto future = promise.get_future();
|
||||
try {
|
||||
throw TrackedError(&count);
|
||||
} catch (const TrackedError&) {
|
||||
promise.set_exception(std::current_exception());
|
||||
}
|
||||
try {
|
||||
future.get();
|
||||
throw std::runtime_error("future did not rethrow");
|
||||
} catch (const TrackedError& error) {
|
||||
if (std::strcmp(error.what(), "retained error")) throw std::runtime_error("future rethrew another error");
|
||||
}
|
||||
}
|
||||
if (count != 1) throw std::runtime_error("future result destroyed its exception an incorrect number of times");
|
||||
}
|
||||
|
||||
int main() {
|
||||
TestTypeInfoVtables();
|
||||
testExceptionPointer();
|
||||
testFutureException();
|
||||
try {
|
||||
Rethrow();
|
||||
return 1;
|
||||
|
|
|
|||
Loading…
Reference in New Issue