Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
U
uniset2
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
UniSet project repositories
uniset2
Commits
9915996b
Commit
9915996b
authored
Jan 07, 2017
by
Pavel Vainerman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
(TCPCheck): переписал на использование future (async)
parent
8fad8103
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
65 additions
and
99 deletions
+65
-99
TCPCheck.h
include/TCPCheck.h
+3
-17
TCPCheck.cc
src/Communications/TCP/TCPCheck.cc
+59
-81
test_tcpcheck.cc
tests/test_tcpcheck.cc
+3
-1
No files found.
include/TCPCheck.h
View file @
9915996b
...
...
@@ -42,33 +42,19 @@ namespace uniset
* Для проверки идёт попытка открыть соединение, но данные не посылаются, а соединение сразу закрывается.
* \note Нужно быть уверенным, что сервис не зависнет от таких попыток "соединений"
*/
bool
check
(
const
std
::
string
&
_ip
,
int
_port
,
timeout_t
tout
)
;
static
bool
check
(
const
std
::
string
&
_ip
,
int
_port
,
timeout_t
tout
)
noexcept
;
/*! \param iaddr - 'ip:port' */
bool
check
(
const
std
::
string
&
iaddr
,
timeout_t
tout
)
;
static
bool
check
(
const
std
::
string
&
iaddr
,
timeout_t
tout
)
noexcept
;
/*! Проверка связи с узлом командой ping
* \note Вызывается через system()! Это может быть опасно с точки зрения безопасности..
* \todo Возможно стоит написать свою реализацию ping
*/
bool
ping
(
const
std
::
string
&
_ip
,
timeout_t
tout
=
1000
,
const
std
::
string
&
ping_argc
=
"-c 1 -w 0.1 -q -n"
)
;
static
bool
ping
(
const
std
::
string
&
_ip
,
timeout_t
tout
=
1000
,
const
std
::
string
&
ping_argc
=
"-c 1 -w 0.1 -q -n"
)
noexcept
;
protected
:
void
check_thread
();
void
ping_thread
();
std
::
condition_variable
thr_event
;
std
::
mutex
thr_mutex
;
std
::
atomic_bool
thr_finished
=
{
false
};
std
::
atomic_bool
result
=
{
false
};
std
::
string
ip
=
{
""
};
int
port
=
{
0
};
int
tout_msec
;
std
::
string
ping_args
=
{
"-c 1 -w 0.1 -q -n"
};
};
// -------------------------------------------------------------------------
}
// end of uniset namespace
...
...
src/Communications/TCP/TCPCheck.cc
View file @
9915996b
...
...
@@ -14,11 +14,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// -----------------------------------------------------------------------------
#include <functional>
#include <sstream>
#include <cstdlib>
#include <iostream>
#include <future>
#include <thread>
#include <chrono>
#include "UniSetTypes.h"
#include "ThreadCreator.h"
#include "TCPCheck.h"
#include "UTCPStream.h"
// -----------------------------------------------------------------------------
...
...
@@ -27,8 +29,7 @@ using namespace std;
namespace
uniset
{
// -----------------------------------------------------------------------------
TCPCheck
::
TCPCheck
()
noexcept
:
tout_msec
(
0
)
TCPCheck
::
TCPCheck
()
noexcept
{
}
// -----------------------------------------------------------------------------
...
...
@@ -37,7 +38,7 @@ namespace uniset
}
// -----------------------------------------------------------------------------
bool
TCPCheck
::
check
(
const
std
::
string
&
_iaddr
,
timeout_t
tout
)
bool
TCPCheck
::
check
(
const
std
::
string
&
_iaddr
,
timeout_t
tout
)
noexcept
{
auto
v
=
uniset
::
explode_str
(
_iaddr
,
':'
);
...
...
@@ -47,100 +48,77 @@ namespace uniset
return
check
(
v
[
0
],
uniset
::
uni_atoi
(
v
[
1
]),
tout
);
}
// -----------------------------------------------------------------------------
template
<
typename
T
>
class
TGuard
bool
TCPCheck
::
check
(
const
std
::
string
&
ip
,
int
port
,
timeout_t
tout_msec
)
noexcept
{
public
:
TGuard
(
T
*
m
,
typename
ThreadCreator
<
T
>::
Action
a
)
:
t
(
m
,
a
)
try
{
std
::
future
<
bool
>
future
=
std
::
async
(
std
::
launch
::
async
,
[
=
]()
{
t
.
start
();
std
::
this_thread
::
sleep_for
(
std
::
chrono
::
milliseconds
(
10
));
}
~
TGuard
()
// Сама проверка...
bool
result
=
false
;
try
{
UTCPStream
t
;
t
.
create
(
ip
,
port
,
tout_msec
);
// если удалось создать соединение, значит OK
result
=
t
.
isConnected
();
t
.
disconnect
();
}
catch
(
...
)
{}
return
result
;
});
std
::
future_status
status
;
do
{
if
(
t
.
isRunning
()
)
t
.
stop
();
t
.
join
();
status
=
future
.
wait_for
(
std
::
chrono
::
milliseconds
(
tout_msec
));
if
(
status
==
std
::
future_status
::
timeout
)
return
false
;
}
while
(
status
!=
std
::
future_status
::
ready
);
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
;
TGuard
<
TCPCheck
>
t
(
this
,
&
TCPCheck
::
check_thread
);
std
::
unique_lock
<
std
::
mutex
>
lock
(
thr_mutex
);
thr_event
.
wait_for
(
lock
,
std
::
chrono
::
milliseconds
(
tout
),
[
=
]()
return
future
.
get
();
}
catch
(
std
::
exception
&
ex
)
{
return
(
thr_finished
==
true
);
}
);
return
result
;
}
return
false
;
}
// -----------------------------------------------------------------------------
void
TCPCheck
::
check_thread
()
bool
TCPCheck
::
ping
(
const
std
::
string
&
ip
,
timeout_t
tout_msec
,
const
std
::
string
&
ping_args
)
noexcept
{
thr_finished
=
false
;
result
=
false
;
try
{
UTCPStream
t
;
t
.
create
(
ip
,
port
,
tout_msec
);
t
.
setKeepAliveParams
(
(
tout_msec
>
1000
?
tout_msec
/
1000
:
1
)
);
result
=
true
;
t
.
disconnect
();
}
catch
(
...
)
{}
thr_finished
=
true
;
}
// -----------------------------------------------------------------------------
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
;
std
::
future
<
bool
>
future
=
std
::
async
(
std
::
launch
::
async
,
[
=
]()
{
// Сама проверка...
ostringstream
cmd
;
cmd
<<
"ping "
<<
ping_args
<<
" "
<<
ip
<<
" 2>/dev/null 1>/dev/null"
;
int
ret
=
system
(
cmd
.
str
().
c_str
());
int
res
=
WEXITSTATUS
(
ret
);
return
(
res
==
0
);
});
TGuard
<
TCPCheck
>
t
(
this
,
&
TCPCheck
::
ping_thread
);
std
::
future_status
status
;
do
{
status
=
future
.
wait_for
(
std
::
chrono
::
milliseconds
(
tout_msec
));
if
(
status
==
std
::
future_status
::
timeout
)
return
false
;
}
while
(
status
!=
std
::
future_status
::
ready
);
std
::
unique_lock
<
std
::
mutex
>
lock
(
thr_mutex
);
thr_event
.
wait_for
(
lock
,
std
::
chrono
::
milliseconds
(
tout
),
[
=
]()
return
future
.
get
();
}
catch
(
std
::
exception
&
ex
)
{
return
(
thr_finished
==
true
);
}
);
return
result
;
}
// -----------------------------------------------------------------------------
void
TCPCheck
::
ping_thread
()
{
thr_finished
=
false
;
result
=
false
;
ostringstream
cmd
;
cmd
<<
"ping "
<<
ping_args
<<
" "
<<
ip
<<
" 2>/dev/null 1>/dev/null"
;
int
ret
=
system
(
cmd
.
str
().
c_str
());
int
res
=
WEXITSTATUS
(
ret
);
}
result
=
(
res
==
0
);
thr_finished
=
true
;
return
false
;
}
// -----------------------------------------------------------------------------
}
// end of namespace uniset
tests/test_tcpcheck.cc
View file @
9915996b
...
...
@@ -79,6 +79,8 @@ TEST_CASE("TCPCheck::ping", "[tcpcheck][tcpcheck_ping]" )
msleep
(
200
);
REQUIRE
(
t
.
ping
(
host
)
);
REQUIRE_FALSE
(
t
.
ping
(
"dummy_host_name"
)
);
// 123.3. - dummy ip
REQUIRE_FALSE
(
t
.
ping
(
"123.3."
)
);
}
// --------------------------------------------------------
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment