Path: blob/main_old/src/tests/test_utils/MultiThreadSteps.h
1693 views
//1// Copyright 2021 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//5// EGLMultiContextTest.cpp:6// Synchronization help for tests that use multiple threads.78#include <atomic>9#include <condition_variable>10#include <mutex>11#include <thread>1213namespace14{1516// The following class is used by tests that need multiple threads that coordinate their actions17// via an enum of "steps". This enum is the template type E. The enum must have at least the18// following values:19//20// - Finish This value indicates that one thread has finished its last step and is cleaning up.21// The other thread waits for this before it does its last step and cleans up.22// - Abort This value indicates that one thread encountered a GL error and has exited. This23// will cause the other thread (that is waiting for a different step) to also abort.24//25// This class is RAII. It is declared at the top of a thread, and will be deconstructed at the end26// of the thread's outer block. If the thread encounters a GL error, the deconstructor will abort27// the other thread using the E:Abort step.28template <typename E>29class ThreadSynchronization30{31public:32ThreadSynchronization(E *currentStep, std::mutex *mutex, std::condition_variable *condVar)33: mCurrentStep(currentStep), mMutex(mutex), mCondVar(condVar)34{}35~ThreadSynchronization()36{37bool isAborting = false;38{39// If the other thread isn't finished, cause it to abort.40std::unique_lock<std::mutex> lock(*mMutex);41isAborting = *mCurrentStep != E::Finish;4243if (isAborting)44{45*mCurrentStep = E::Abort;46}47}48mCondVar->notify_all();49}5051// Helper functions to synchronize the threads so that the operations are executed in the52// specific order the test is written for.53bool waitForStep(E waitStep)54{55std::unique_lock<std::mutex> lock(*mMutex);56while (*mCurrentStep != waitStep)57{58// If necessary, abort execution as the other thread has encountered a GL error.59if (*mCurrentStep == E::Abort)60{61return false;62}63mCondVar->wait(lock);64}6566return true;67}6869void nextStep(E newStep)70{71{72std::unique_lock<std::mutex> lock(*mMutex);73*mCurrentStep = newStep;74}75mCondVar->notify_one();76}7778private:79E *mCurrentStep;80std::mutex *mMutex;81std::condition_variable *mCondVar;82};83} // anonymous namespace848586