artdaq  v3_01_00
TCPSocketTransfer.hh
1 #ifndef TCPSocketTransfer_hh
2 #define TCPSocketTransfer_hh
3 // This file (TCPSocketTransfer.hh) was created by Ron Rechenmacher <ron@fnal.gov> on
4 // Sep 14, 2016. "TERMS AND CONDITIONS" governing this file are in the README
5 // or COPYING file. If you do not have such a file, one can be obtained by
6 // contacting Ron or Fermi Lab in Batavia IL, 60510, phone: 630-840-3000.
7 // $RCSfile: .emacs.gnu,v $
8 // rev="$Revision: 1.30 $$Date: 2016/03/01 14:27:27 $";
9 
10 // C Includes
11 #include <stdint.h> // uint64_t
12 #include <sys/uio.h> // iovec
13 
14 // C++ Includes
15 #include <condition_variable>
16 #include <boost/thread.hpp>
17 
18 // Products includes
19 #include "fhiclcpp/fwd.h"
20 
21 // artdaq Includes
22 #include "artdaq/TransferPlugins/TransferInterface.hh"
23 #include "artdaq/TransferPlugins/detail/SRSockets.hh"
24 #include "artdaq/TransferPlugins/detail/Timeout.hh" // Timeout
25 #include "artdaq-core/Data/Fragment.hh"
26 #include "artdaq/TransferPlugins/detail/HostMap.hh"
27 
28 namespace artdaq
29 {
30  class TCPSocketTransfer;
31 }
32 
37 {
38 public:
57  TCPSocketTransfer(fhicl::ParameterSet const& ps, Role role);
58 
59  virtual ~TCPSocketTransfer() noexcept;
60 
67  int receiveFragmentHeader(detail::RawFragmentHeader& header, size_t receiveTimeout) override;
68 
75  int receiveFragmentData(RawDataType* destination, size_t wordCount) override;
76 
83  CopyStatus copyFragment(Fragment& frag, size_t timeout_usec) override { return sendFragment_(std::move(frag), timeout_usec); }
84 
90  CopyStatus moveFragment(Fragment&& frag) override { return sendFragment_(std::move(frag), 0); }
91 
92 
93 private:
94  static std::atomic<int> listen_thread_refcount_;
95  static std::mutex listen_thread_mutex_;
96  static std::unique_ptr<boost::thread> listen_thread_;
97  static std::map<int, std::set<int>> connected_fds_;
98  int send_fd_;
99  int active_receive_fd_;
100  int last_active_receive_fd_;
101 
102  union
103  {
104  MessHead mh;
105  uint8_t mha[sizeof(MessHead)];
106  };
107 
108  enum class SocketState
109  {
110  Metadata,
111  Data
112  };
113 
114  size_t rcvbuf_;
115  size_t sndbuf_;
116  size_t send_retry_timeout_us_;
117 
118  hostMap_t hostMap_;
119 
120  volatile unsigned connect_state : 1; // 0=not "connected" (initial msg not sent)
121  unsigned blocking : 1; // compatible with bool (true/false)
122 
123 
124  Timeout tmo_;
125  bool stats_connect_stop_;
126  boost::thread stats_connect_thread_;
127  std::condition_variable stopstatscv_;
128  std::mutex stopstatscvm_; // protects 'stopcv'
129 
130  bool timeoutMessageArmed_; // don't repeatedly print about the send fd not being open...
131  size_t not_connected_count_; // Number of times returned RECV_TIMEOUT because no receive sockets open
132  size_t receive_err_threshold_; // Number of times TO print RECV_TIMEOUT before starting to return DATA_END
133  size_t receive_err_wait_us_; // Amount of time to wait if there are no connected receive sockets
134 
135 private: // methods
136  CopyStatus sendFragment_(Fragment&& frag, size_t timeout_usec);
137 
138  CopyStatus sendData_(const void* buf, size_t bytes, size_t tmo);
139 
140  CopyStatus sendData_(const struct iovec* iov, int iovcnt, size_t tmo);
141 
142  // Thread to drive reconnect_ requests
143  void stats_connect_();
144 
145  // Sender is responsible for connecting to receiver
146  void connect_();
147 
148  void reconnect_();
149 
150  // Receiver should listen for connections
151  void start_listen_thread_();
152  void listen_();
153 
154  int calculate_port_() const {
155  return destination_rank() + ((partition_number_ % 22) * 1000) + 10000;
156  }
157 };
158 
159 #endif // TCPSocketTransfer_hh
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...
The Timeout class performs registered actions at specified intervals.
Definition: Timeout.hh:22
const short partition_number_
The partition number of the DAQ.
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.
virtual int destination_rank() const
Get the destination rank for this TransferInterface instance.
TransferInterface implementation plugin that sends data using TCP sockets.
This header is sent by the TCPSocket_transfer to allow for more efficient writev calls.
Definition: SRSockets.hh:15
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.