Commit 20b3449d authored by Pavel Vainerman's avatar Pavel Vainerman

(TCPCheck): переделал класс на использование condition

parent d5b8a3d2
......@@ -38,32 +38,30 @@ class TCPCheck
* \param _ip - ip проверяемого узла
* \param _port - порт для проверяемого узла
* \param tout - таймаут на попытку
* \param sleep_msec - пауза между проверками результата
*
* Для проверки идёт попытка открыть соединение, но данные не посылаются, а соединение сразу закрывается.
* \note Нужно быть уверенным, что сервис не зависнет от таких попыток "соединений"
*/
bool check( const std::string& _ip, int _port, timeout_t tout, timeout_t sleep_msec = 50 );
bool check( const std::string& _ip, int _port, timeout_t tout );
/*! \param iaddr - 'ip:port' */
bool check( const std::string& iaddr, timeout_t tout, timeout_t sleep_msec = 50);
bool check( const std::string& iaddr, timeout_t tout );
/*! Проверка связи с узлом командой ping
* \note Вызывается через system()! Это может быть опасно с точки зрения безопасности..
* \todo Возможно стоит написать свою реализацию ping
*/
bool ping( const std::string& _ip, timeout_t tout = 1000, timeout_t sleep_msec = 200, const std::string& ping_argc = "-c 1 -w 0.1 -q -n" );
bool ping(const std::string& _ip, timeout_t tout = 1000, const std::string& ping_argc = "-c 1 -w 0.1 -q -n" );
protected:
void check_thread();
void ping_thread();
void setResult( bool s )
{
result = s;
}
std::condition_variable thr_event;
std::mutex thr_mutex;
std::atomic_bool thr_finished = { false };
std::atomic_bool result = {false};
std::string ip = {""};
......
......@@ -18,7 +18,6 @@
#include <sstream>
#include <cstdlib>
#include "UniSetTypes.h"
#include "PassiveTimer.h"
#include "ThreadCreator.h"
#include "TCPCheck.h"
#include "UTCPStream.h"
......@@ -38,102 +37,99 @@ TCPCheck::~TCPCheck() noexcept
}
// -----------------------------------------------------------------------------
bool TCPCheck::check( const std::string& _iaddr, timeout_t tout, timeout_t sleep_msec )
bool TCPCheck::check( const std::string& _iaddr, timeout_t tout )
{
auto v = uniset::explode_str(_iaddr, ':');
if( v.size() < 2 )
return false;
return check( v[0], uniset::uni_atoi(v[1]), tout, sleep_msec );
return check( v[0], uniset::uni_atoi(v[1]), tout );
}
// -----------------------------------------------------------------------------
bool TCPCheck::check( const std::string& _ip, int _port, timeout_t tout, timeout_t sleep_msec )
template<typename T>
class TGuard
{
ip = _ip;
port = _port;
tout_msec = tout;
setResult(false);
public:
ThreadCreator<TCPCheck> t(this, &TCPCheck::check_thread);
// t.setCancel(ost::Thread::cancelDeferred);
TGuard( T* m, typename ThreadCreator<T>::Action a ):
t(m, a)
{
t.start();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
~TGuard()
{
if( t.isRunning() )
t.stop();
}
PassiveTimer pt(tout);
protected:
ThreadCreator<T> t;
};
// -----------------------------------------------------------------------------
bool TCPCheck::check( const std::string& _ip, int _port, timeout_t tout )
{
ip = _ip;
port = _port;
tout_msec = tout;
thr_finished = false;
result = false;
while( !pt.checkTime() && t.isRunning() )
msleep(sleep_msec);
TGuard<TCPCheck> t(this, &TCPCheck::check_thread);
if( t.isRunning() ) // !getResult() )
t.stop();
std::unique_lock<std::mutex> lock(thr_mutex);
thr_event.wait_for(lock,std::chrono::milliseconds(tout), [=]()
{
return ( thr_finished == true );
} );
return result;
}
// -----------------------------------------------------------------------------
void TCPCheck::check_thread()
{
setResult(false);
thr_finished = false;
result = false;
try
{
UTCPStream t;
t.create(ip, port, tout_msec);
t.setKeepAliveParams( (tout_msec > 1000 ? tout_msec / 1000 : 1) );
setResult(true);
result = true;
t.disconnect();
}
catch( ... ) {}
}
// -----------------------------------------------------------------------------
template<typename T>
class TGuard
{
public:
TGuard( T* m, typename ThreadCreator<T>::Action a ):
t(m, a)
{
t.start();
}
~TGuard()
{
if( t.isRunning() )
t.stop();
}
inline bool isRunning()
{
return t.isRunning();
}
protected:
ThreadCreator<T> t;
};
thr_finished = true;
}
// -----------------------------------------------------------------------------
bool TCPCheck::ping( const std::string& _ip, timeout_t tout, timeout_t sleep_msec, const std::string& _ping_args )
bool TCPCheck::ping( const std::string& _ip, timeout_t tout, const std::string& _ping_args )
{
ip = _ip;
tout_msec = tout;
ping_args = _ping_args;
thr_finished = false;
result = false;
setResult(false);
TGuard<TCPCheck> t(this, &TCPCheck::ping_thread);
PassiveTimer pt(tout);
while( !pt.checkTime() && t.isRunning() )
msleep(sleep_msec);
std::unique_lock<std::mutex> lock(thr_mutex);
thr_event.wait_for(lock,std::chrono::milliseconds(tout), [=]()
{
return ( thr_finished == true );
} );
return result;
}
// -----------------------------------------------------------------------------
void TCPCheck::ping_thread()
{
setResult(false);
thr_finished = false;
result = false;
ostringstream cmd;
cmd << "ping " << ping_args << " " << ip << " 2>/dev/null 1>/dev/null";
......@@ -141,7 +137,8 @@ void TCPCheck::ping_thread()
int ret = system(cmd.str().c_str());
int res = WEXITSTATUS(ret);
setResult((res == 0));
result = (res == 0);
thr_finished = true;
}
// -----------------------------------------------------------------------------
} // end of namespace uniset
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment