+ }
+
+ 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();
+ }