Hi guys!
I am trying to encapsulate into tasks a C library that has a bunch of callbacks. The real code can't be pasted here, so I'll make a fake example. I would like to encapsulate the async request state in a class together with a task_completion_event. The request object would kill itself when the work is complete.
Please can you help me understand why this race happens and maybe give me any suggestion of alternative designs? I get spurious crashes running the code below.
Thank you very much for the attention!!!
Best regards
Mello
#include <memory>
#include <ppltasks.h>
#include <Windows.h>
using namespace std;
using namespace concurrency;
class Request : public enable_shared_from_this<Request>
{
shared_ptr<Request> m_selfReference;
task_completion_event<void> m_completionSource;
void AcquireSelfReference()
{
m_selfReference = shared_from_this();
}
void ReleaseSelfReference()
{
m_selfReference = nullptr;
}
public:
~Request()
{
//cout << "~Request " << ::GetCurrentThreadId() << endl;
}
task<void> ExecuteAsync()
{
AcquireSelfReference();
// do async work
task<void> t([this]()
{
cout << "async " << GetCurrentThreadId() << endl;
m_completionSource.set();
});
return task<void>(m_completionSource).then([this]
{
ReleaseSelfReference();
});
}
};
task<void> DoAsyncWork()
{
shared_ptr<Request> pRequest(make_shared<Request>());
return pRequest->ExecuteAsync();
}
int main()
{
cout << "start " << GetCurrentThreadId() << endl;
for (int i = 0; i < 10000; i++)
{
DoAsyncWork().get();
}
return 0;
}