123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 |
- #pragma once
- //
- //primary header for work with asio
- //
- #include <util/generic/ptr.h>
- #include <util/generic/string.h>
- #include <util/generic/vector.h>
- #include <util/network/socket.h>
- #include <util/network/endpoint.h>
- #include <util/system/error.h>
- #include <util/stream/output.h>
- #include <functional>
- #include <library/cpp/dns/cache.h>
- //#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<void()> 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<TImpl> Impl_;
- };
- class TDeadlineTimer: public TNonCopyable {
- public:
- typedef std::function<void(const TErrorCode& err, IHandlingContext&)> 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<IBuffers> TSendedData;
- typedef std::function<void(const TErrorCode& err, IHandlingContext&)> THandler;
- typedef THandler TConnectHandler;
- typedef std::function<void(const TErrorCode& err, size_t amount, IHandlingContext&)> TWriteHandler;
- typedef std::function<void(const TErrorCode& err, size_t amount, IHandlingContext&)> 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<TImpl> Impl_;
- };
- class TTcpAcceptor: public TNonCopyable {
- public:
- typedef std::function<void(const TErrorCode& err, IHandlingContext&)> 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<TImpl> Impl_;
- };
- }
|