00001 #ifndef TCPSocketTransfer_hh
00002 #define TCPSocketTransfer_hh
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <stdint.h>
00012 #include <sys/uio.h>
00013
00014
00015 #include <condition_variable>
00016 #include <boost/thread.hpp>
00017
00018
00019 #include "fhiclcpp/fwd.h"
00020
00021
00022 #include "artdaq/TransferPlugins/TransferInterface.hh"
00023 #include "artdaq/TransferPlugins/detail/SRSockets.hh"
00024 #include "artdaq/TransferPlugins/detail/Timeout.hh"
00025 #include "artdaq-core/Data/Fragment.hh"
00026 #include "artdaq/TransferPlugins/detail/HostMap.hh"
00027
00028 namespace artdaq
00029 {
00030 class TCPSocketTransfer;
00031 }
00032
00036 class artdaq::TCPSocketTransfer : public TransferInterface
00037 {
00038 public:
00057 TCPSocketTransfer(fhicl::ParameterSet const& ps, Role role);
00058
00059 virtual ~TCPSocketTransfer() noexcept;
00060
00067 int receiveFragmentHeader(detail::RawFragmentHeader& header, size_t receiveTimeout) override;
00068
00075 int receiveFragmentData(RawDataType* destination, size_t wordCount) override;
00076
00083 CopyStatus copyFragment(Fragment& frag, size_t timeout_usec) override { return sendFragment_(std::move(frag), timeout_usec); }
00084
00090 CopyStatus moveFragment(Fragment&& frag) override { return sendFragment_(std::move(frag), 0); }
00091
00092
00093 private:
00094 static std::atomic<int> listen_thread_refcount_;
00095 static std::mutex listen_thread_mutex_;
00096 static std::unique_ptr<boost::thread> listen_thread_;
00097 static std::map<int, std::set<int>> connected_fds_;
00098 int send_fd_;
00099 int active_receive_fd_;
00100 int last_active_receive_fd_;
00101
00102 union
00103 {
00104 MessHead mh;
00105 uint8_t mha[sizeof(MessHead)];
00106 };
00107
00108 enum class SocketState
00109 {
00110 Metadata,
00111 Data
00112 };
00113
00114 size_t rcvbuf_;
00115 size_t sndbuf_;
00116 size_t send_retry_timeout_us_;
00117
00118 hostMap_t hostMap_;
00119
00120 volatile unsigned connect_state : 1;
00121 unsigned blocking : 1;
00122
00123
00124 Timeout tmo_;
00125 bool stats_connect_stop_;
00126 boost::thread stats_connect_thread_;
00127 std::condition_variable stopstatscv_;
00128 std::mutex stopstatscvm_;
00129
00130 bool timeoutMessageArmed_;
00131 size_t not_connected_count_;
00132 size_t receive_err_threshold_;
00133 size_t receive_err_wait_us_;
00134
00135 private:
00136 CopyStatus sendFragment_(Fragment&& frag, size_t timeout_usec);
00137
00138 CopyStatus sendData_(const void* buf, size_t bytes, size_t tmo);
00139
00140 CopyStatus sendData_(const struct iovec* iov, int iovcnt, size_t tmo);
00141
00142
00143 void stats_connect_();
00144
00145
00146 void connect_();
00147
00148 void reconnect_();
00149
00150
00151 void start_listen_thread_();
00152 void listen_();
00153
00154 int calculate_port_() const {
00155 return destination_rank() + ((partition_number_ % 22) * 1000) + 10000;
00156 }
00157 };
00158
00159 #endif // TCPSocketTransfer_hh