blob: 025ed1f62c7dae562a4e6cd8741c8886da9462cc [file] [log] [blame]
// Copyright 2021 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "dawn_platform/WorkerThread.h"
#include <condition_variable>
#include <functional>
#include <thread>
#include "common/Assert.h"
namespace {
class AsyncWaitableEventImpl {
public:
AsyncWaitableEventImpl() : mIsComplete(false) {
}
void Wait() {
std::unique_lock<std::mutex> lock(mMutex);
mCondition.wait(lock, [this] { return mIsComplete; });
}
bool IsComplete() {
std::lock_guard<std::mutex> lock(mMutex);
return mIsComplete;
}
void MarkAsComplete() {
{
std::lock_guard<std::mutex> lock(mMutex);
mIsComplete = true;
}
mCondition.notify_all();
}
private:
std::mutex mMutex;
std::condition_variable mCondition;
bool mIsComplete;
};
class AsyncWaitableEvent final : public dawn_platform::WaitableEvent {
public:
explicit AsyncWaitableEvent()
: mWaitableEventImpl(std::make_shared<AsyncWaitableEventImpl>()) {
}
void Wait() override {
mWaitableEventImpl->Wait();
}
bool IsComplete() override {
return mWaitableEventImpl->IsComplete();
}
std::shared_ptr<AsyncWaitableEventImpl> GetWaitableEventImpl() const {
return mWaitableEventImpl;
}
private:
std::shared_ptr<AsyncWaitableEventImpl> mWaitableEventImpl;
};
} // anonymous namespace
namespace dawn_platform {
std::unique_ptr<dawn_platform::WaitableEvent> AsyncWorkerThreadPool::PostWorkerTask(
dawn_platform::PostWorkerTaskCallback callback,
void* userdata) {
std::unique_ptr<AsyncWaitableEvent> waitableEvent = std::make_unique<AsyncWaitableEvent>();
std::function<void()> doTask =
[callback, userdata, waitableEventImpl = waitableEvent->GetWaitableEventImpl()]() {
callback(userdata);
waitableEventImpl->MarkAsComplete();
};
std::thread thread(doTask);
thread.detach();
return waitableEvent;
}
} // namespace dawn_platform