Mailbox: Address feedback

This commit is contained in:
Henrik Rydgård 2021-06-13 11:26:24 +02:00
parent e7b3afbc7a
commit 6d634f0c96
3 changed files with 21 additions and 19 deletions

View file

@ -998,4 +998,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View file

@ -4,12 +4,16 @@
#include "Common/Thread/Channel.h"
#include "Common/Thread/ThreadManager.h"
#include "Common/Log.h"
template<class T>
class PromiseTask : public Task {
public:
PromiseTask() {}
PromiseTask(std::function<T *()> fun, Mailbox<T> *tx) : fun_(fun), tx_(tx) {
tx_->AddRef();
}
~PromiseTask() {
tx_->Release();
}
void Run() override {
@ -22,30 +26,27 @@ public:
};
// Represents pending or actual data.
// Has ownership over the data.
// Single use.
// Has ownership over the data. Single use.
// TODO: Split Mailbox (rx_ and tx_) up into separate proxy objects.
// NOTE: Poll/BlockUntilReady should only be used from one thread.
template<class T>
class Promise {
public:
static Promise<T> *Spawn(ThreadManager *threadman, std::function<T *()> fun, TaskType taskType) {
// std::pair<Rx<T>, Tx<T>> channel = CreateChannel<T>();
Mailbox<T> *mailbox = new Mailbox<T>();
PromiseTask<T> *task = new PromiseTask<T>();
task->fun_ = fun;
task->tx_ = mailbox;
threadman->EnqueueTask(task, taskType);
Promise<T> *promise = new Promise<T>();
promise->rx_ = mailbox;
PromiseTask<T> *task = new PromiseTask<T>(fun, mailbox);
threadman->EnqueueTask(task, taskType);
return promise;
}
~Promise() {
if (rx_) {
rx_->Release();
}
// A promise should have been fulfilled before it's destroyed.
_assert_(ready_);
_assert_(!rx_);
delete data_;
}
@ -55,6 +56,8 @@ public:
return data_;
} else {
if (rx_->Poll(&data_)) {
rx_->Release();
rx_ = nullptr;
ready_ = true;
return data_;
} else {

View file

@ -57,10 +57,6 @@ bool TestParallelLoop(ThreadManager *threadMan) {
}
bool TestThreadManager() {
if (!TestMailbox()) {
return false;
}
ThreadManager manager;
manager.Init(8, 1);
@ -73,11 +69,14 @@ bool TestThreadManager() {
ResultObject *result = object->BlockUntilReady();
if (result) {
// Note that the data is owned by the promise so we don't
// delete it here.
printf("Got result back!");
}
delete object;
if (!TestMailbox()) {
return false;
}
return true;
}