artdaq  v2_02_03
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Pages
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 <sys/types.h> // size_t
12 #include <stdint.h> // uint64_t
13 #include <sys/uio.h> // iovec
14 #include <poll.h> // struct pollfd
15 
16 // C++ Includes
17 #include <vector>
18 #include <map>
19 #include <set>
20 #include <vector>
21 #include <thread> // std::thread
22 #include <condition_variable>
23 
24 // Products includes
25 #include <fhiclcpp/fwd.h>
26 
27 // artdaq Includes
28 #include "artdaq/TransferPlugins/TransferInterface.hh"
29 #include "artdaq/TransferPlugins/detail/SRSockets.hh"
30 #include "artdaq/TransferPlugins/detail/Timeout.hh" // Timeout
31 #include "artdaq-core/Data/Fragment.hh"
32 
33 namespace artdaq
34 {
35  class TCPSocketTransfer;
36 }
37 
42 {
43 public:
61  TCPSocketTransfer(fhicl::ParameterSet const& ps, Role role);
62 
63  virtual ~TCPSocketTransfer();
64 
71  int receiveFragment(Fragment& frag, size_t timeout_usec = 0) override;
72 
79  CopyStatus copyFragment(Fragment& frag, size_t timeout_usec) override { return sendFragment_(std::move(frag), timeout_usec); }
80 
87  CopyStatus moveFragment(Fragment&& frag, size_t timeout_usec) override { return sendFragment_(std::move(frag), timeout_usec); }
88 
89 private:
90 
91  int fd_;
92  int listen_fd_;
93 
94  union
95  {
96  MessHead mh;
97  uint8_t mha[sizeof(MessHead)];
98  };
99 
100  enum class SocketState
101  {
102  Metadata,
103  Data
104  };
105 
106  SocketState state_;
107 
108  Fragment frag;
109  uint8_t* buffer;
110  size_t offset;
111  int target_bytes;
112  size_t rcvbuf_;
113  size_t sndbuf_;
114 
115  struct DestinationInfo
116  {
117  std::string hostname;
118  int portOffset;
119  };
120 
121  std::unordered_map<size_t, DestinationInfo> hostMap_;
122 
123  volatile unsigned connect_state : 1; // 0=not "connected" (initial msg not sent)
124  unsigned blocking : 1; // compatible with bool (true/false)
125 
126 
127  Timeout tmo_;
128  bool stats_connect_stop_;
129  std::thread stats_connect_thread_;
130  std::condition_variable stopstatscv_;
131  std::mutex stopstatscvm_; // protects 'stopcv'
132 
133  bool timeoutMessageArmed_; // don't repeatedly print about the send fd not being open...
134 
135 private: // methods
136  CopyStatus sendFragment_(Fragment&& frag, size_t timeout_usec);
137 
138  CopyStatus sendFragment_(const void* buf, size_t bytes, size_t tmo);
139 
140  CopyStatus sendFragment_(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 listen_();
152 
153  int calculate_port_() const { return (hostMap_.at(destination_rank())).portOffset + source_rank(); }
154 };
155 
156 #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
int destination_rank() const
Get the destination rank for this TransferInterface instance.
int source_rank() const
Get the source rank for this TransferInterface instance.
TCPSocketTransfer(fhicl::ParameterSet const &ps, Role role)
TCPSocketTransfer Constructor.
int receiveFragment(Fragment &frag, size_t timeout_usec=0) override
Receive a Fragment using TCP.
Role
Used to determine if a TransferInterface is a Sender or Receiver.
CopyStatus moveFragment(Fragment &&frag, size_t timeout_usec) 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.
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.