X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Flib%2Fplatform%2Fsockets%2Fsocket.h;h=388bb2d8a0d2fd13e2500207f13481ce31dfbbf9;hb=996665192725398172263999b88c63663d11db04;hp=2e8acdbdca4de00fb7b76822b0ed36214c870d9f;hpb=4478bc797f871f631399ab8008d3b2787ded07c2;p=deb_libcec.git diff --git a/src/lib/platform/sockets/socket.h b/src/lib/platform/sockets/socket.h index 2e8acdb..388bb2d 100644 --- a/src/lib/platform/sockets/socket.h +++ b/src/lib/platform/sockets/socket.h @@ -44,65 +44,191 @@ namespace PLATFORM { - class CSocket : public PreventCopy + class ISocket : public PreventCopy { - public: - CSocket(void) : - m_socket(INVALID_SOCKET), - m_iError(0) {}; + public: + ISocket(void) {}; + virtual ~ISocket(void) {} - virtual ~CSocket(void) - { - Close(); - } + virtual bool Open(uint64_t iTimeoutMs = 0) = 0; + virtual void Close(void) = 0; + virtual void Shutdown(void) = 0; + virtual bool IsOpen(void) = 0; + virtual ssize_t Write(void* data, size_t len) = 0; + virtual ssize_t Read(void* data, size_t len, uint64_t iTimeoutMs = 0) = 0; + virtual CStdString GetError(void) = 0; + virtual int GetErrorNumber(void) = 0; + virtual CStdString GetName(void) = 0; + }; - virtual bool IsOpen(void) - { - CLockObject lock(m_mutex); - return m_socket != INVALID_SOCKET && - m_socket != SOCKET_ERROR; - } + template + class CCommonSocket : public ISocket + { + public: + CCommonSocket(_SType initialSocketValue, const CStdString &strName) : + m_socket(initialSocketValue), + m_strName(strName), + m_iError(0) {} - virtual void Close(void) - { - CLockObject lock(m_mutex); - SocketClose(m_socket); - m_socket = INVALID_SOCKET; - m_strError = ""; - } + virtual ~CCommonSocket(void) {} - virtual int64_t Write(uint8_t* data, uint32_t len) - { - CLockObject lock(m_mutex); - int64_t iReturn = SocketWrite(m_socket, &m_iError, data, len); - m_strError = strerror(m_iError); - return iReturn; - } + virtual CStdString GetError(void) + { + CStdString strError; + strError = m_strError.IsEmpty() && m_iError != 0 ? strerror(m_iError) : m_strError; + return strError; + } + + virtual int GetErrorNumber(void) + { + return m_iError; + } + + virtual CStdString GetName(void) + { + CStdString strName; + strName = m_strName; + return strName; + } + + protected: + _SType m_socket; + CStdString m_strError; + CStdString m_strName; + int m_iError; + CMutex m_mutex; + }; + + template + class CProtectedSocket : public ISocket + { + public: + CProtectedSocket(_Socket *socket) : + m_socket(socket), + m_iUseCount(0) {} + + virtual ~CProtectedSocket(void) + { + Close(); + delete m_socket; + } - virtual int32_t Read(uint8_t* data, uint32_t len, uint64_t iTimeoutMs = 0) + virtual bool Open(uint64_t iTimeoutMs = 0) + { + bool bReturn(false); + if (m_socket && WaitReady()) { - CLockObject lock(m_mutex); - int32_t iReturn = SocketRead(m_socket, &m_iError, data, len, iTimeoutMs); - m_strError = strerror(m_iError); - return iReturn; + bReturn = m_socket->Open(iTimeoutMs); + MarkReady(); } + return bReturn; + } - virtual CStdString GetError(void) const + virtual void Close(void) + { + if (m_socket && WaitReady()) { - CStdString strReturn; - strReturn = m_strError; - return strReturn; + m_socket->Close(); + MarkReady(); } + } - virtual int GetErrorNumber(void) const + virtual void Shutdown(void) + { + if (m_socket && WaitReady()) { - return m_iError; + m_socket->Shutdown(); + MarkReady(); } + } + + virtual bool IsOpen(void) + { + CLockObject lock(m_mutex); + return m_socket && m_socket->IsOpen(); + } + + virtual bool IsBusy(void) + { + CLockObject lock(m_mutex); + return m_socket && m_iUseCount > 0; + } + + virtual int GetUseCount(void) + { + CLockObject lock(m_mutex); + return m_iUseCount; + } + + virtual ssize_t Write(void* data, size_t len) + { + if (!m_socket || !WaitReady()) + return EINVAL; + + ssize_t iReturn = m_socket->Write(data, len); + MarkReady(); + + return iReturn; + } + + virtual ssize_t Read(void* data, size_t len, uint64_t iTimeoutMs = 0) + { + if (!m_socket || !WaitReady()) + return EINVAL; + + ssize_t iReturn = m_socket->Read(data, len, iTimeoutMs); + MarkReady(); + + return iReturn; + } + + virtual CStdString GetError(void) + { + CStdString strError; + CLockObject lock(m_mutex); + strError = m_socket ? m_socket->GetError() : ""; + return strError; + } + + virtual int GetErrorNumber(void) + { + CLockObject lock(m_mutex); + return m_socket ? m_socket->GetErrorNumber() : EINVAL; + } + + virtual CStdString GetName(void) + { + CStdString strName; + CLockObject lock(m_mutex); + strName = m_socket ? m_socket->GetName() : ""; + return strName; + } + + private: + bool WaitReady(void) + { + CLockObject lock(m_mutex); + if (m_iUseCount > 0) + m_condition.Wait(m_mutex); + + if (m_iUseCount > 0) + return false; + + ++m_iUseCount; + return true; + } + + void MarkReady(void) + { + CLockObject lock(m_mutex); + if (m_iUseCount > 0) + --m_iUseCount; + m_condition.Broadcast(); + } - protected: - socket_t m_socket; - CStdString m_strError; - int m_iError; - CMutex m_mutex; + _Socket *m_socket; + CMutex m_mutex; + CCondition m_condition; + int m_iUseCount; }; };