ChimeraTK-DeviceAccess 03.28.00
Loading...
Searching...
No Matches
Connection.cc
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
2// SPDX-License-Identifier: LGPL-3.0-or-later
3
4#include "Connection.h"
5
6#include "Exception.h"
7
8#include <utility>
9namespace ChimeraTK::Rebot {
10
11 using Error = boost::system::error_code;
12
13 Connection::Connection(std::string address, std::string port, uint32_t connectionTimeout_sec)
14 : address_(std::move(address)), port_(std::move(port)), s_(ioContext_), disconnectTimer_(ioContext_),
15 connectionTimeout_(boost::posix_time::seconds(connectionTimeout_sec)) {}
16
18 try {
19 disconnectionTimerStart();
20 boost::asio::ip::tcp::resolver r(ioContext_);
21 boost::asio::async_connect(
22 s_, r.resolve(address_, port_), [&](const Error ec, auto) { disconnectionTimerCancel(ec); });
23
24 ioContext_.restart();
25 ioContext_.run();
26 }
27 catch(const boost::exception&) {
28 throw ChimeraTK::runtime_error("RebotBackend exception: Host unreachable:");
29 }
30 }
31
32 std::vector<uint32_t> Connection::read(uint32_t numWords) {
33 std::vector<uint32_t> d(numWords);
34 disconnectionTimerStart();
35 boost::asio::async_read(s_, boost::asio::buffer(d), [&](Error ec, std::size_t) { disconnectionTimerCancel(ec); });
36
37 ioContext_.restart();
38 ioContext_.run();
39 return d;
40 }
41
42 void Connection::write(const std::vector<uint32_t>& d) {
43 disconnectionTimerStart();
44 boost::asio::async_write(s_, boost::asio::buffer(d), [&](Error ec, std::size_t) { disconnectionTimerCancel(ec); });
45
46 ioContext_.restart();
47 ioContext_.run();
48 }
49
51 std::unique_lock lock{_closeMutex, std::defer_lock};
52 if(!lock.try_lock()) {
53 // Mutex already taken! Another thread is handling the close. Returning immediately.
54 return;
55 }
56
57 if(s_.is_open()) {
58 s_.cancel();
59 s_.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
60 s_.close();
61 }
62 }
63
65 return s_.is_open();
66 }
67
68 void Connection::disconnectionTimerStart() {
69 disconnectTimer_.expires_from_now(connectionTimeout_);
70 disconnectTimer_.async_wait([&](const Error& ec) {
71 if(ec == boost::asio::error::operation_aborted) {
72 // you have this error code when the timer was cancelled before expiry
73 return;
74 }
75 close();
76 });
77 }
78
79 void Connection::disconnectionTimerCancel(const Error& ec) {
80 disconnectTimer_.cancel();
81 if(ec) {
82 close();
83 throw ChimeraTK::runtime_error("Rebot connection timed out");
84 }
85 }
86
87} // namespace ChimeraTK::Rebot
void close()
Closes a connection with the device.
Definition Connection.cc:50
void write(const std::vector< uint32_t > &data)
Sends a std::vector of bytes to the socket.
Definition Connection.cc:42
bool isOpen()
Get the connection state.
Definition Connection.cc:64
Connection(std::string address, std::string port, uint32_t connectionTimeout_sec)
Gets an IP address and port of the device but does not open the connection.
Definition Connection.cc:13
void open()
Opens a connection to the device.
Definition Connection.cc:17
std::vector< uint32_t > read(uint32_t numWordsToRead)
Receives uint32_t words from the socket.
Definition Connection.cc:32
Exception thrown when a runtime error has occured.
Definition Exception.h:18
boost::system::error_code Error
Definition Connection.cc:11
STL namespace.