mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-16 10:19:47 +02:00
78 lines
1.2 KiB
C++
78 lines
1.2 KiB
C++
|
/*
|
||
|
* ConditionalWait.h, part of VCMI engine
|
||
|
*
|
||
|
* Authors: listed in file AUTHORS in main folder
|
||
|
*
|
||
|
* License: GNU General Public License v2.0 or later
|
||
|
* Full text of license available in license.txt file, in main folder
|
||
|
*
|
||
|
*/
|
||
|
#pragma once
|
||
|
|
||
|
#include <condition_variable>
|
||
|
|
||
|
VCMI_LIB_NAMESPACE_BEGIN
|
||
|
|
||
|
class TerminationRequestedException : public std::exception
|
||
|
{
|
||
|
public:
|
||
|
using exception::exception;
|
||
|
|
||
|
const char* what() const noexcept override
|
||
|
{
|
||
|
return "Thread termination requested";
|
||
|
}
|
||
|
};
|
||
|
|
||
|
class ConditionalWait
|
||
|
{
|
||
|
bool isBusyValue = false;
|
||
|
bool isTerminating = false;
|
||
|
std::condition_variable cond;
|
||
|
std::mutex mx;
|
||
|
|
||
|
void set(bool value)
|
||
|
{
|
||
|
boost::unique_lock<std::mutex> lock(mx);
|
||
|
isBusyValue = value;
|
||
|
}
|
||
|
|
||
|
public:
|
||
|
ConditionalWait() = default;
|
||
|
|
||
|
void setBusy()
|
||
|
{
|
||
|
set(true);
|
||
|
}
|
||
|
|
||
|
void setFree()
|
||
|
{
|
||
|
set(false);
|
||
|
cond.notify_all();
|
||
|
}
|
||
|
|
||
|
void requestTermination()
|
||
|
{
|
||
|
isTerminating = true;
|
||
|
setFree();
|
||
|
}
|
||
|
|
||
|
bool isBusy()
|
||
|
{
|
||
|
std::unique_lock<std::mutex> lock(mx);
|
||
|
return isBusyValue;
|
||
|
}
|
||
|
|
||
|
void waitWhileBusy()
|
||
|
{
|
||
|
std::unique_lock<std::mutex> un(mx);
|
||
|
while(isBusyValue)
|
||
|
cond.wait(un);
|
||
|
|
||
|
if (isTerminating)
|
||
|
throw TerminationRequestedException();
|
||
|
}
|
||
|
};
|
||
|
|
||
|
VCMI_LIB_NAMESPACE_END
|