1 #ifndef CONNECT__IMPL__SOCKET_ADDRESS__HPP 2 #define CONNECT__IMPL__SOCKET_ADDRESS__HPP 3 4 /* $Id: connect_misc.hpp 622184 2020-12-21 18:30:13Z ivanov $ 5 * =========================================================================== 6 * 7 * PUBLIC DOMAIN NOTICE 8 * National Center for Biotechnology Information 9 * 10 * This software/database is a "United States Government Work" under the 11 * terms of the United States Copyright Act. It was written as part of 12 * the author's official duties as a United States Government employee and 13 * thus cannot be copyrighted. This software/database is freely available 14 * to the public for use. The National Library of Medicine and the U.S. 15 * Government have not placed any restriction on its use or reproduction. 16 * 17 * Although all reasonable efforts have been taken to ensure the accuracy 18 * and reliability of the software and data, the NLM and the U.S. 19 * Government do not and cannot warrant the performance or results that 20 * may be obtained by using this software or data. The NLM and the U.S. 21 * Government disclaim all warranties, express or implied, including 22 * warranties of performance, merchantability or fitness for any particular 23 * purpose. 24 * 25 * Please cite the author in any work or product based on this material. 26 * 27 * =========================================================================== 28 * 29 * Authors: Rafael Sadyrov 30 * 31 */ 32 33 #include <connect/connect_export.h> 34 35 #include <corelib/ncbistl.hpp> 36 #include <corelib/ncbistr.hpp> 37 38 #include <chrono> 39 #include <memory> 40 #include <mutex> 41 #include <regex> 42 #include <sstream> 43 #include <string> 44 #include <unordered_map> 45 #include <utility> 46 #include <vector> 47 48 BEGIN_NCBI_SCOPE 49 50 struct NCBI_XCONNECT_EXPORT SSocketAddress 51 { 52 unsigned host; 53 unsigned short port; 54 55 struct NCBI_XCONNECT_EXPORT SHost 56 { 57 unsigned host; SHostSSocketAddress::SHost58 SHost(unsigned h) : host(h) {} 59 SHost(const string& h); 60 }; 61 62 struct SPort 63 { 64 unsigned short port; SPortSSocketAddress::SPort65 SPort(unsigned short p) : port(p) {} SPortSSocketAddress::SPort66 SPort(const string& p) : port(NStr::StringToNumeric<unsigned short>(p)) {} SPortSSocketAddress::SPort67 SPort(CTempString p) : port(NStr::StringToNumeric<unsigned short>(p)) {} 68 }; 69 SSocketAddressSSocketAddress70 SSocketAddress(SHost h, SPort p) : host(h.host), port(p.port) {} 71 operator boolSSocketAddress72 explicit operator bool() const { return host && port; } 73 string GetHostName() const; AsStringSSocketAddress74 string AsString() const { return GetHostName() + ':' + NStr::UIntToString(port); } 75 76 static SSocketAddress Parse(const string& address); 77 }; 78 79 NCBI_XCONNECT_EXPORT bool operator==(const SSocketAddress& lhs, const SSocketAddress& rhs); 80 NCBI_XCONNECT_EXPORT bool operator< (const SSocketAddress& lhs, const SSocketAddress& rhs); 81 82 class NCBI_XCONNECT_EXPORT CServiceDiscovery 83 { 84 public: 85 CServiceDiscovery(const string& service_name); 86 87 using TServer = pair<SSocketAddress, double>; 88 using TServers = vector<TServer>; 89 TServers operator()(); 90 GetServiceName() const91 const string& GetServiceName() const { return m_ServiceName; } IsSingleServer() const92 bool IsSingleServer() const { return m_IsSingleServer; } 93 94 static TServers DiscoverImpl(const string&, unsigned, shared_ptr<void>&, pair<string, const char*>, int, unsigned long); 95 96 private: 97 const string m_ServiceName; 98 shared_ptr<void> m_Data; 99 const bool m_IsSingleServer; 100 }; 101 102 template <class TType> 103 struct SThreadSafe 104 { 105 template <class T> 106 struct SLock : private unique_lock<std::mutex> 107 { operator *SThreadSafe::SLock108 T& operator*() { _ASSERT(m_Object); return *m_Object; } operator ->SThreadSafe::SLock109 T* operator->() { _ASSERT(m_Object); return m_Object; } 110 111 // More convenient RAII alternative to explicit scopes or 'unlock' method. 112 // It allows locks to be declared inside 'if' condition. 113 using unique_lock<std::mutex>::operator bool; 114 UnlockSThreadSafe::SLock115 void Unlock() { m_Object = nullptr; unlock(); } 116 117 private: SLockSThreadSafe::SLock118 SLock(T* c, std::mutex& m) : unique_lock(m), m_Object(c) { _ASSERT(m_Object); } 119 120 T* m_Object; 121 122 friend struct SThreadSafe; 123 }; 124 125 template <class... TArgs> SThreadSafeSThreadSafe126 SThreadSafe(TArgs&&... args) : m_Object(forward<TArgs>(args)...) {} 127 GetLockSThreadSafe128 SLock< TType> GetLock() { return { &m_Object, m_Mutex }; } GetLockSThreadSafe129 SLock<const TType> GetLock() const { return { &m_Object, m_Mutex }; } 130 131 // Direct access to the protected object (e.g. to access atomic members). 132 // All thread-safe members must be explicitly marked volatile to be available. GetMTSafeSThreadSafe133 volatile TType& GetMTSafe() { return m_Object; } GetMTSafeSThreadSafe134 const volatile TType& GetMTSafe() const { return m_Object; } 135 136 protected: 137 mutex m_Mutex; 138 139 private: 140 TType m_Object; 141 }; 142 143 class NCBI_XCONNECT_EXPORT CLogLatencies 144 { 145 public: 146 template <size_t SIZE1, size_t SIZE2> CLogLatencies(const char (& s1)[SIZE1],const char (& s2)[SIZE2])147 CLogLatencies(const char (&s1)[SIZE1], const char (&s2)[SIZE2]) : 148 m_Start(s1, SIZE1 - 1), 149 m_Stop(s2, SIZE2 - 1) 150 {} 151 SetDebug(bool debug)152 void SetDebug(bool debug) { m_Debug = debug; } 153 154 using TResult = unordered_map<string, chrono::microseconds>; 155 TResult Parse(istream& is); 156 157 private: 158 regex m_Start; 159 regex m_Stop; 160 bool m_Debug = false; 161 }; 162 163 class NCBI_XCONNECT_EXPORT CLogLatencyReport : public CLogLatencies 164 { 165 public: 166 template <class... TArgs> CLogLatencyReport(TArgs &&...args)167 CLogLatencyReport(TArgs&&... args) : CLogLatencies(forward<TArgs>(args)...) {} 168 169 ~CLogLatencyReport(); 170 171 void Start(); operator bool() const172 explicit operator bool() const { return m_CerrBuf; } 173 174 private: 175 struct SNullBuf : streambuf 176 { overflowCLogLatencyReport::SNullBuf177 int_type overflow(int_type c) override { return traits_type::not_eof(c); } 178 }; 179 180 SNullBuf m_NullBuf; 181 stringstream m_CerrOutput; 182 streambuf* m_CerrBuf = nullptr; 183 }; 184 185 END_NCBI_SCOPE 186 187 #endif 188