/*
|
* =====================================================================================
|
*
|
* Filename: robust.cpp
|
*
|
* Description:
|
*
|
* Version: 1.0
|
* Created: 2021年04月27日 10时04分19秒
|
* Revision: none
|
* Compiler: gcc
|
*
|
* Author: Li Chao (), lichao@aiotlink.com
|
* Organization:
|
*
|
* =====================================================================================
|
*/
|
#include "robust.h"
|
#include <thread>
|
|
using namespace std::chrono;
|
using namespace std::chrono_literals;
|
|
namespace
|
{
|
void yield() { std::this_thread::sleep_for(10us); }
|
} // namespace
|
|
namespace robust
|
{
|
|
bool AtomicReqRep::ClientRequest(const Data request, Data &reply)
|
{
|
auto end_time = now() + 3s;
|
do {
|
Data cur = data_.load();
|
if (GetState(cur) == eStateFree &&
|
DataCas(cur, Encode(request, eStateRequest))) {
|
do {
|
yield();
|
cur = data_.load();
|
if (GetState(cur) == eStateReply) {
|
DataCas(cur, Encode(0, eStateFree));
|
reply = Decode(cur);
|
return true;
|
}
|
} while (now() < end_time);
|
}
|
yield();
|
} while (now() < end_time);
|
return false;
|
}
|
|
bool AtomicReqRep::ServerProcess(Handler onReq)
|
{
|
Data cur = data_.load();
|
switch (GetState(cur)) {
|
case eStateRequest:
|
if (DataCas(cur, Encode(onReq(Decode(cur)), eStateReply))) {
|
timestamp_ = now();
|
return true;
|
}
|
break;
|
case eStateReply:
|
if (timestamp_.load() + 3s < now()) {
|
DataCas(cur, Encode(0, eStateFree));
|
}
|
break;
|
case eStateFree:
|
default: break;
|
}
|
return false;
|
}
|
} // namespace robust
|