#pragma once // //primary header for work with asio // #include #include #include #include #include #include #include #include #include //#define DEBUG_ASIO class TContIOVector; namespace NAsio { class TErrorCode { public: inline TErrorCode(int val = 0) noexcept : Val_(val) { } typedef void (*TUnspecifiedBoolType)(); static void UnspecifiedBoolTrue() { } //safe cast to bool value operator TUnspecifiedBoolType() const noexcept { // true if error return Val_ == 0 ? nullptr : UnspecifiedBoolTrue; } bool operator!() const noexcept { return Val_ == 0; } void Assign(int val) noexcept { Val_ = val; } int Value() const noexcept { return Val_; } TString Text() const { if (!Val_) { return TString(); } return LastSystemErrorText(Val_); } void Check() { if (Val_) { throw TSystemError(Val_); } } private: int Val_; }; //wrapper for TInstant, for enabling use TDuration (+TInstant::Now()) as deadline class TDeadline: public TInstant { public: TDeadline() : TInstant(TInstant::Max()) { } TDeadline(const TInstant& t) : TInstant(t) { } TDeadline(const TDuration& d) : TInstant(TInstant::Now() + d) { } }; class IHandlingContext { public: virtual ~IHandlingContext() { } //if handler throw exception, call this function be ignored virtual void ContinueUseHandler(TDeadline deadline = TDeadline()) = 0; }; typedef std::function TCompletionHandler; class TIOService: public TNonCopyable { public: TIOService(); ~TIOService(); void Run(); void Post(TCompletionHandler); //call handler in Run() thread-executor void Abort(); //in Run() all exist async i/o operations + timers receive error = ECANCELED, Run() exited // not const since internal queue is lockfree and needs to increment and decrement its reference counters size_t GetOpQueueSize() noexcept; //counterpart boost::asio::io_service::work class TWork { public: TWork(TWork&); TWork(TIOService&); ~TWork(); private: void operator=(const TWork&); //disable TIOService& Srv_; }; class TImpl; TImpl& GetImpl() noexcept { return *Impl_; } private: THolder Impl_; }; class TDeadlineTimer: public TNonCopyable { public: typedef std::function THandler; TDeadlineTimer(TIOService&) noexcept; ~TDeadlineTimer(); void AsyncWaitExpireAt(TDeadline, THandler); void Cancel(); TIOService& GetIOService() const noexcept { return Srv_; } class TImpl; private: TIOService& Srv_; TImpl* Impl_; }; class TTcpSocket: public TNonCopyable { public: class IBuffers { public: virtual ~IBuffers() { } virtual TContIOVector* GetIOvec() = 0; }; typedef TAutoPtr TSendedData; typedef std::function THandler; typedef THandler TConnectHandler; typedef std::function TWriteHandler; typedef std::function TReadHandler; typedef THandler TPollHandler; enum TShutdownMode { ShutdownReceive = SHUT_RD, ShutdownSend = SHUT_WR, ShutdownBoth = SHUT_RDWR }; TTcpSocket(TIOService&) noexcept; ~TTcpSocket(); void AsyncConnect(const TEndpoint& ep, TConnectHandler, TDeadline deadline = TDeadline()); void AsyncWrite(TSendedData&, TWriteHandler, TDeadline deadline = TDeadline()); void AsyncWrite(TContIOVector* buff, TWriteHandler, TDeadline deadline = TDeadline()); void AsyncWrite(const void* buff, size_t size, TWriteHandler, TDeadline deadline = TDeadline()); void AsyncRead(void* buff, size_t size, TReadHandler, TDeadline deadline = TDeadline()); void AsyncReadSome(void* buff, size_t size, TReadHandler, TDeadline deadline = TDeadline()); void AsyncPollWrite(TPollHandler, TDeadline deadline = TDeadline()); void AsyncPollRead(TPollHandler, TDeadline deadline = TDeadline()); void AsyncCancel(); //sync, but non blocked methods size_t WriteSome(TContIOVector&, TErrorCode&) noexcept; size_t WriteSome(const void* buff, size_t size, TErrorCode&) noexcept; size_t ReadSome(void* buff, size_t size, TErrorCode&) noexcept; bool IsOpen() const noexcept; void Shutdown(TShutdownMode mode, TErrorCode& ec); TIOService& GetIOService() const noexcept { return Srv_; } SOCKET Native() const noexcept; TEndpoint RemoteEndpoint() const; inline size_t WriteSome(TContIOVector& v) { TErrorCode ec; size_t n = WriteSome(v, ec); ec.Check(); return n; } inline size_t WriteSome(const void* buff, size_t size) { TErrorCode ec; size_t n = WriteSome(buff, size, ec); ec.Check(); return n; } inline size_t ReadSome(void* buff, size_t size) { TErrorCode ec; size_t n = ReadSome(buff, size, ec); ec.Check(); return n; } void Shutdown(TShutdownMode mode) { TErrorCode ec; Shutdown(mode, ec); ec.Check(); } class TImpl; TImpl& GetImpl() const noexcept { return *Impl_; } private: TIOService& Srv_; TIntrusivePtr Impl_; }; class TTcpAcceptor: public TNonCopyable { public: typedef std::function TAcceptHandler; TTcpAcceptor(TIOService&) noexcept; ~TTcpAcceptor(); void Bind(TEndpoint&, TErrorCode&) noexcept; void Listen(int backlog, TErrorCode&) noexcept; void AsyncAccept(TTcpSocket&, TAcceptHandler, TDeadline deadline = TDeadline()); void AsyncCancel(); inline void Bind(TEndpoint& ep) { TErrorCode ec; Bind(ep, ec); ec.Check(); } inline void Listen(int backlog) { TErrorCode ec; Listen(backlog, ec); ec.Check(); } TIOService& GetIOService() const noexcept { return Srv_; } class TImpl; TImpl& GetImpl() const noexcept { return *Impl_; } private: TIOService& Srv_; TIntrusivePtr Impl_; }; }