70 lines
1.6 KiB
C++
70 lines
1.6 KiB
C++
/*
|
||
* ShadowGuard.h
|
||
*
|
||
* Created on: 10 мая 2017 г.
|
||
* Author: titov
|
||
*/
|
||
|
||
#ifndef SOURCES_COMMON_SHADOWGUARD_H_
|
||
#define SOURCES_COMMON_SHADOWGUARD_H_
|
||
|
||
//!Класс для передачи данных между потоками.
|
||
/*!Класс гарантирует безопасную передачу данных в случае если функция update не будет прервана функцией operator =.
|
||
*
|
||
*/
|
||
|
||
template<typename V>
|
||
class ShadowGuard : public V {
|
||
private:
|
||
V shadow_value;
|
||
bool upd;
|
||
|
||
public:
|
||
ShadowGuard(const V &);
|
||
|
||
//!Безопасное присваивание в прерываемом потоке.
|
||
void operator=(const V & new_value);
|
||
|
||
//!Безопасное обновление в прерывающем потоке.
|
||
void update();
|
||
};
|
||
|
||
template<typename V>
|
||
inline void ShadowGuard<V>::operator =(const V & new_value) {
|
||
upd = false; shadow_value = new_value; upd = true;
|
||
}
|
||
|
||
template<typename V>
|
||
inline ShadowGuard<V>::ShadowGuard(const V & rv) :
|
||
V(rv), shadow_value(rv), upd(false) {}
|
||
|
||
template<typename V>
|
||
inline void ShadowGuard<V>::update() {
|
||
if(upd) {
|
||
|
||
volatile V new_value = shadow_value;
|
||
|
||
// do {
|
||
// new_value = shadow_value;
|
||
// } while( new_value != shadow_value );
|
||
|
||
*static_cast<V *>(this) = shadow_value;
|
||
upd = false;
|
||
}
|
||
}
|
||
|
||
template<typename V>
|
||
V read_from_fast( volatile const V * value ) {
|
||
|
||
V * fast_value = const_cast<V *>(value);
|
||
V temp(*fast_value);
|
||
|
||
do {
|
||
temp = *fast_value;
|
||
} while( temp != *fast_value );
|
||
|
||
return temp;
|
||
}
|
||
|
||
#endif /* SOURCES_COMMON_SHADOWGUARD_H_ */
|