//----------------------------------------------------------------------------- // 一个自动释放句柄的容器 // 在析构时, 自动调用 CloseHandle //----------------------------------------------------------------------------- #pragma once //----------------------------------------------------------------------------- // HandleHolder //----------------------------------------------------------------------------- class HandleHolder { protected: HANDLE m_Handle; public: HandleHolder (HANDLE from) : m_Handle (from) { assert (m_Handle != 0); assert (m_Handle != INVALID_HANDLE_VALUE); } ~HandleHolder () { Close (); } public: HandleHolder (HandleHolder && from) { m_Handle = from.m_Handle; from.m_Handle = 0; } HandleHolder & operator = (HandleHolder && from) { m_Handle = from.m_Handle; from.m_Handle = 0; } private: // 禁止拷贝构造函数, 禁止复制 HandleHolder (const HandleHolder & h) = delete; HandleHolder & operator = (const HandleHolder & h) = delete; public: HANDLE Detach () { auto fd = InterlockedExchange (reinterpret_cast (&m_Handle), 0); return (reinterpret_cast (fd)); } HANDLE Get () { assert (m_Handle != 0); assert (m_Handle != INVALID_HANDLE_VALUE); return m_Handle; } // 返回 -1, 表示读失败 int Read (void * vPtr, int count) { assert (m_Handle != 0); assert (m_Handle != INVALID_HANDLE_VALUE); DWORD nbOfRead = 0; auto rc = ReadFile (m_Handle, vPtr, count, &nbOfRead, nullptr); if (rc) { Tillnow.cbRecv += nbOfRead; Snapshot.cbRecv += nbOfRead; return nbOfRead; } auto ec = GetLastError (); // 0x6D (109), 管道已结束. 作为 SCP 时, 这个错误很常见 return -1; } // 返回 -1, 表示写失败 int Write (const void * vPtr, int count) { assert (m_Handle != 0); assert (m_Handle != INVALID_HANDLE_VALUE); DWORD nbOfWrite = 0; auto rc = WriteFile (m_Handle, vPtr, count, &nbOfWrite, nullptr); if (rc) { Tillnow.cbSend += nbOfWrite; Snapshot.cbSend += nbOfWrite; return nbOfWrite; } auto ec = GetLastError (); // 0x6D (109), 管道已结束. 作为 SCP 时, 这个错误很常见 return -1; } bool IsClosed () const { return m_Handle == 0 || m_Handle == INVALID_HANDLE_VALUE; } void Close () { auto fd = Detach (); if (fd) CloseHandle (fd); } eSTR::DString ToString () const { return eSTR::DString (); } // 用于日志,跟踪等 public: // 获得 auto GetFlowRate () const->std::tuple { return { Tillnow.cbSend, Tillnow.cbRecv }; } // 获得 . // 函数返回后, 我的成员 Snapshot.cbSend, Snapshot.cbRecv 都被置为 0 auto SwapFlowRate ()->std::tuple { auto S = Snapshot.cbSend; auto R = Snapshot.cbRecv; Snapshot.cbSend = 0; Snapshot.cbRecv = 0; return { S, R }; } protected: struct { UINT cbSend = 0; UINT cbRecv = 0; } Tillnow; // 从 Socket 创建到现在的统计量 struct { UINT cbSend = 0; UINT cbRecv = 0; } Snapshot; // 每次调用 SwapFlowRate 后, 返回这两个值 }; class HandleHolderEx : public HandleHolder { using base = HandleHolder; public: HandleHolderEx (HANDLE from, const eSTR::DString & Info) : base (from), m_Info (Info) { m_SeriesNo = InterlockedIncrement (&S_SeriesNo); } public: ULONG GetSeriesNo () const { return m_SeriesNo; } eSTR::DString ToString () const { return m_Info; } eSTR::DString GetAddress () const { return m_Info; } public: DWORD GetWireVersion () const { return m_WireVersion; } void SetWireVersion (DWORD ver) { m_WireVersion = ver; } private: ULONG m_SeriesNo = 0; // 序列号,用于跟踪 DWORD m_WireVersion = 0; // 由使用者维护/引用这个项 eSTR::DString m_Info; inline static long volatile S_SeriesNo = 0; };