asio.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. #pragma once
  2. //
  3. //primary header for work with asio
  4. //
  5. #include <util/generic/ptr.h>
  6. #include <util/generic/string.h>
  7. #include <util/generic/vector.h>
  8. #include <util/network/socket.h>
  9. #include <util/network/endpoint.h>
  10. #include <util/system/error.h>
  11. #include <util/stream/output.h>
  12. #include <functional>
  13. #include <library/cpp/dns/cache.h>
  14. //#define DEBUG_ASIO
  15. class TContIOVector;
  16. namespace NAsio {
  17. class TErrorCode {
  18. public:
  19. inline TErrorCode(int val = 0) noexcept
  20. : Val_(val)
  21. {
  22. }
  23. typedef void (*TUnspecifiedBoolType)();
  24. static void UnspecifiedBoolTrue() {
  25. }
  26. //safe cast to bool value
  27. operator TUnspecifiedBoolType() const noexcept { // true if error
  28. return Val_ == 0 ? nullptr : UnspecifiedBoolTrue;
  29. }
  30. bool operator!() const noexcept {
  31. return Val_ == 0;
  32. }
  33. void Assign(int val) noexcept {
  34. Val_ = val;
  35. }
  36. int Value() const noexcept {
  37. return Val_;
  38. }
  39. TString Text() const {
  40. if (!Val_) {
  41. return TString();
  42. }
  43. return LastSystemErrorText(Val_);
  44. }
  45. void Check() {
  46. if (Val_) {
  47. throw TSystemError(Val_);
  48. }
  49. }
  50. private:
  51. int Val_;
  52. };
  53. //wrapper for TInstant, for enabling use TDuration (+TInstant::Now()) as deadline
  54. class TDeadline: public TInstant {
  55. public:
  56. TDeadline()
  57. : TInstant(TInstant::Max())
  58. {
  59. }
  60. TDeadline(const TInstant& t)
  61. : TInstant(t)
  62. {
  63. }
  64. TDeadline(const TDuration& d)
  65. : TInstant(TInstant::Now() + d)
  66. {
  67. }
  68. };
  69. class IHandlingContext {
  70. public:
  71. virtual ~IHandlingContext() {
  72. }
  73. //if handler throw exception, call this function be ignored
  74. virtual void ContinueUseHandler(TDeadline deadline = TDeadline()) = 0;
  75. };
  76. typedef std::function<void()> TCompletionHandler;
  77. class TIOService: public TNonCopyable {
  78. public:
  79. TIOService();
  80. ~TIOService();
  81. void Run();
  82. void Post(TCompletionHandler); //call handler in Run() thread-executor
  83. void Abort(); //in Run() all exist async i/o operations + timers receive error = ECANCELED, Run() exited
  84. // not const since internal queue is lockfree and needs to increment and decrement its reference counters
  85. size_t GetOpQueueSize() noexcept;
  86. //counterpart boost::asio::io_service::work
  87. class TWork {
  88. public:
  89. TWork(TWork&);
  90. TWork(TIOService&);
  91. ~TWork();
  92. private:
  93. void operator=(const TWork&); //disable
  94. TIOService& Srv_;
  95. };
  96. class TImpl;
  97. TImpl& GetImpl() noexcept {
  98. return *Impl_;
  99. }
  100. private:
  101. THolder<TImpl> Impl_;
  102. };
  103. class TDeadlineTimer: public TNonCopyable {
  104. public:
  105. typedef std::function<void(const TErrorCode& err, IHandlingContext&)> THandler;
  106. TDeadlineTimer(TIOService&) noexcept;
  107. ~TDeadlineTimer();
  108. void AsyncWaitExpireAt(TDeadline, THandler);
  109. void Cancel();
  110. TIOService& GetIOService() const noexcept {
  111. return Srv_;
  112. }
  113. class TImpl;
  114. private:
  115. TIOService& Srv_;
  116. TImpl* Impl_;
  117. };
  118. class TTcpSocket: public TNonCopyable {
  119. public:
  120. class IBuffers {
  121. public:
  122. virtual ~IBuffers() {
  123. }
  124. virtual TContIOVector* GetIOvec() = 0;
  125. };
  126. typedef TAutoPtr<IBuffers> TSendedData;
  127. typedef std::function<void(const TErrorCode& err, IHandlingContext&)> THandler;
  128. typedef THandler TConnectHandler;
  129. typedef std::function<void(const TErrorCode& err, size_t amount, IHandlingContext&)> TWriteHandler;
  130. typedef std::function<void(const TErrorCode& err, size_t amount, IHandlingContext&)> TReadHandler;
  131. typedef THandler TPollHandler;
  132. enum TShutdownMode {
  133. ShutdownReceive = SHUT_RD,
  134. ShutdownSend = SHUT_WR,
  135. ShutdownBoth = SHUT_RDWR
  136. };
  137. TTcpSocket(TIOService&) noexcept;
  138. ~TTcpSocket();
  139. void AsyncConnect(const TEndpoint& ep, TConnectHandler, TDeadline deadline = TDeadline());
  140. void AsyncWrite(TSendedData&, TWriteHandler, TDeadline deadline = TDeadline());
  141. void AsyncWrite(TContIOVector* buff, TWriteHandler, TDeadline deadline = TDeadline());
  142. void AsyncWrite(const void* buff, size_t size, TWriteHandler, TDeadline deadline = TDeadline());
  143. void AsyncRead(void* buff, size_t size, TReadHandler, TDeadline deadline = TDeadline());
  144. void AsyncReadSome(void* buff, size_t size, TReadHandler, TDeadline deadline = TDeadline());
  145. void AsyncPollWrite(TPollHandler, TDeadline deadline = TDeadline());
  146. void AsyncPollRead(TPollHandler, TDeadline deadline = TDeadline());
  147. void AsyncCancel();
  148. //sync, but non blocked methods
  149. size_t WriteSome(TContIOVector&, TErrorCode&) noexcept;
  150. size_t WriteSome(const void* buff, size_t size, TErrorCode&) noexcept;
  151. size_t ReadSome(void* buff, size_t size, TErrorCode&) noexcept;
  152. bool IsOpen() const noexcept;
  153. void Shutdown(TShutdownMode mode, TErrorCode& ec);
  154. TIOService& GetIOService() const noexcept {
  155. return Srv_;
  156. }
  157. SOCKET Native() const noexcept;
  158. TEndpoint RemoteEndpoint() const;
  159. inline size_t WriteSome(TContIOVector& v) {
  160. TErrorCode ec;
  161. size_t n = WriteSome(v, ec);
  162. ec.Check();
  163. return n;
  164. }
  165. inline size_t WriteSome(const void* buff, size_t size) {
  166. TErrorCode ec;
  167. size_t n = WriteSome(buff, size, ec);
  168. ec.Check();
  169. return n;
  170. }
  171. inline size_t ReadSome(void* buff, size_t size) {
  172. TErrorCode ec;
  173. size_t n = ReadSome(buff, size, ec);
  174. ec.Check();
  175. return n;
  176. }
  177. void Shutdown(TShutdownMode mode) {
  178. TErrorCode ec;
  179. Shutdown(mode, ec);
  180. ec.Check();
  181. }
  182. class TImpl;
  183. TImpl& GetImpl() const noexcept {
  184. return *Impl_;
  185. }
  186. private:
  187. TIOService& Srv_;
  188. TIntrusivePtr<TImpl> Impl_;
  189. };
  190. class TTcpAcceptor: public TNonCopyable {
  191. public:
  192. typedef std::function<void(const TErrorCode& err, IHandlingContext&)> TAcceptHandler;
  193. TTcpAcceptor(TIOService&) noexcept;
  194. ~TTcpAcceptor();
  195. void Bind(TEndpoint&, TErrorCode&) noexcept;
  196. void Listen(int backlog, TErrorCode&) noexcept;
  197. void AsyncAccept(TTcpSocket&, TAcceptHandler, TDeadline deadline = TDeadline());
  198. void AsyncCancel();
  199. inline void Bind(TEndpoint& ep) {
  200. TErrorCode ec;
  201. Bind(ep, ec);
  202. ec.Check();
  203. }
  204. inline void Listen(int backlog) {
  205. TErrorCode ec;
  206. Listen(backlog, ec);
  207. ec.Check();
  208. }
  209. TIOService& GetIOService() const noexcept {
  210. return Srv_;
  211. }
  212. class TImpl;
  213. TImpl& GetImpl() const noexcept {
  214. return *Impl_;
  215. }
  216. private:
  217. TIOService& Srv_;
  218. TIntrusivePtr<TImpl> Impl_;
  219. };
  220. }