1 #ifndef TCPSocketTransfer_hh
2 #define TCPSocketTransfer_hh
15 #include <condition_variable>
16 #include <boost/thread.hpp>
19 #include "fhiclcpp/fwd.h"
22 #include "artdaq/TransferPlugins/TransferInterface.hh"
23 #include "artdaq/TransferPlugins/detail/SRSockets.hh"
24 #include "artdaq/TransferPlugins/detail/Timeout.hh"
25 #include "artdaq-core/Data/Fragment.hh"
26 #include "artdaq/TransferPlugins/detail/HostMap.hh"
34 class TCPSocketTransfer;
87 CopyStatus copyFragment(Fragment& frag,
size_t timeout_usec)
override {
return sendFragment_(std::move(frag), timeout_usec); }
103 static std::atomic<int> listen_thread_refcount_;
104 static std::mutex listen_thread_mutex_;
105 static std::unique_ptr<boost::thread> listen_thread_;
106 static std::map<int, std::set<int>> connected_fds_;
107 static std::mutex connected_fd_mutex_;
109 int active_receive_fd_;
110 int last_active_receive_fd_;
111 short active_revents_;
119 enum class SocketState
127 size_t send_retry_timeout_us_;
131 volatile unsigned connect_state : 1;
132 unsigned blocking : 1;
134 bool timeoutMessageArmed_;
135 std::chrono::steady_clock::time_point last_recv_time_;
136 double receive_disconnected_wait_s_;
137 size_t receive_err_wait_us_;
138 std::atomic<bool> receive_socket_has_been_connected_;
139 std::atomic<int> send_ack_diff_;
140 std::unique_ptr<boost::thread> ack_listen_thread_;
143 CopyStatus sendFragment_(Fragment&& frag,
size_t timeout_usec);
145 CopyStatus sendData_(
const void* buf,
size_t bytes,
size_t tmo,
bool isHeader =
false);
147 CopyStatus sendData_(
const struct iovec* iov,
int iovcnt,
size_t tmo,
bool isHeader =
false);
150 void receive_acks_();
151 void send_ack_(
int fd);
159 int disconnect_receive_socket_(
int fd, std::string msg =
"");
162 void start_listen_thread_();
163 static void listen_(
int port,
size_t rcvbuf);
167 std::unique_lock<std::mutex> lk(connected_fd_mutex_);
168 return connected_fds_.count(source_rank) ? connected_fds_[
source_rank].size() : 0;
172 #endif // TCPSocketTransfer_hh
bool isRunning() override
Determine whether the TransferInterface plugin is able to send/receive data.
virtual int source_rank() const
Get the source rank for this TransferInterface instance.
Role role() const
Get the TransferInterface::Role of this TransferInterface.
CopyStatus copyFragment(Fragment &frag, size_t timeout_usec) override
Copy a Fragment to the destination. Same implementation as moveFragment, as TCP is always reliable...
int receiveFragmentData(RawDataType *destination, size_t wordCount) override
Receive the body of a Fragment to the given destination pointer.
TCPSocketTransfer(fhicl::ParameterSet const &ps, Role role)
TCPSocketTransfer Constructor.
int receiveFragmentHeader(detail::RawFragmentHeader &header, size_t receiveTimeout) override
Receive a Fragment Header from the transport mechanism.
Role
Used to determine if a TransferInterface is a Sender or Receiver.
CopyStatus moveFragment(Fragment &&frag) override
Move a Fragment to the destination.
This interface defines the functions used to transfer data between artdaq applications.
TransferInterface implementation plugin that sends data using TCP sockets.
This header is sent by the TCPSocket_transfer to allow for more efficient writev calls.
std::map< int, std::string > hostMap_t
The host_map is a map associating ranks with artdaq::DestinationInfo objects.
CopyStatus
Returned from the send functions, this enumeration describes the possible return codes. If an exception occurs, it will be thrown and should be handled normally.