summaryrefslogtreecommitdiff
path: root/sal/osl
diff options
context:
space:
mode:
Diffstat (limited to 'sal/osl')
-rw-r--r--sal/osl/unx/pipe.cxx50
-rw-r--r--sal/osl/unx/sockimpl.hxx2
2 files changed, 38 insertions, 14 deletions
diff --git a/sal/osl/unx/pipe.cxx b/sal/osl/unx/pipe.cxx
index 436f3086ded5..c4420731795d 100644
--- a/sal/osl/unx/pipe.cxx
+++ b/sal/osl/unx/pipe.cxx
@@ -82,12 +82,10 @@ static oslPipeError osl_PipeErrorFromNative(int nativeType)
static oslPipe createPipeImpl()
{
- oslPipe pPipeImpl;
-
- pPipeImpl = static_cast< oslPipe >(calloc(1, sizeof(struct oslPipeImpl)));
- if (!pPipeImpl)
- return nullptr;
+ oslPipe pPipeImpl = new oslPipeImpl;
+ pPipeImpl->m_Socket = 0;
+ pPipeImpl->m_Name[0] = 0;
pPipeImpl->m_nRefCount = 1;
pPipeImpl->m_bClosed = false;
#if defined(CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT)
@@ -100,8 +98,7 @@ static oslPipe createPipeImpl()
static void destroyPipeImpl(oslPipe pImpl)
{
- if (pImpl)
- free(pImpl);
+ delete pImpl;
}
oslPipe SAL_CALL osl_createPipe(rtl_uString *ustrPipeName, oslPipeOptions Options, oslSecurity Security)
@@ -296,8 +293,7 @@ void SAL_CALL osl_releasePipe(oslPipe pPipe)
if (osl_atomic_decrement(&(pPipe->m_nRefCount)) == 0)
{
- if (!pPipe->m_bClosed)
- osl_closePipe(pPipe);
+ osl_closePipe(pPipe);
destroyPipeImpl(pPipe);
}
@@ -311,6 +307,8 @@ void SAL_CALL osl_closePipe(oslPipe pPipe)
if (!pPipe)
return;
+ std::unique_lock aGuard(pPipe->m_Mutex);
+
if (pPipe->m_bClosed)
return;
@@ -373,13 +371,23 @@ oslPipe SAL_CALL osl_acceptPipe(oslPipe pPipe)
if (!pPipe)
return nullptr;
- assert(pPipe->m_Name[0] != '\0'); // you cannot have an empty pipe name
+ int socket;
+ {
+ // dont hold lock while accepting, so it is possible to close a socket blocked in accept
+ std::unique_lock aGuard(pPipe->m_Mutex);
+ assert(pPipe->m_Name[0] != '\0'); // you cannot have an empty pipe name
#if defined(CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT)
- pPipe->m_bIsAccepting = true;
+ pPipe->m_bIsAccepting = true;
#endif
- s = accept(pPipe->m_Socket, nullptr, nullptr);
+ socket = pPipe->m_Socket;
+ }
+
+
+ s = accept(socket, nullptr, nullptr);
+
+ std::unique_lock aGuard(pPipe->m_Mutex);
#if defined(CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT)
pPipe->m_bIsAccepting = false;
@@ -435,7 +443,14 @@ sal_Int32 SAL_CALL osl_receivePipe(oslPipe pPipe,
return -1;
}
- sal_Int32 nRet = recv(pPipe->m_Socket, pBuffer, BytesToRead, 0);
+ int socket;
+ {
+ // dont hold lock while receiving, so it is possible to close a socket blocked in recv
+ std::unique_lock aGuard(pPipe->m_Mutex);
+ socket = pPipe->m_Socket;
+ }
+
+ sal_Int32 nRet = recv(socket, pBuffer, BytesToRead, 0);
SAL_WARN_IF(nRet < 0, "sal.osl.pipe", "recv() failed: " << UnixErrnoString(errno));
@@ -456,7 +471,14 @@ sal_Int32 SAL_CALL osl_sendPipe(oslPipe pPipe,
return -1;
}
- nRet = send(pPipe->m_Socket, pBuffer, BytesToSend, 0);
+ int socket;
+ {
+ // dont hold lock while sending, so it is possible to close a socket blocked in send
+ std::unique_lock aGuard(pPipe->m_Mutex);
+ socket = pPipe->m_Socket;
+ }
+
+ nRet = send(socket, pBuffer, BytesToSend, 0);
if (nRet <= 0)
SAL_WARN("sal.osl.pipe", "send() failed: " << UnixErrnoString(errno));
diff --git a/sal/osl/unx/sockimpl.hxx b/sal/osl/unx/sockimpl.hxx
index dc354db94a42..529aec7ff1eb 100644
--- a/sal/osl/unx/sockimpl.hxx
+++ b/sal/osl/unx/sockimpl.hxx
@@ -24,6 +24,7 @@
#include <sys/socket.h>
#include <sys/un.h>
+#include <mutex>
#if defined(LINUX) || defined(FREEBSD) || defined(NETBSD)
#define CLOSESOCKET_DOESNT_WAKE_UP_ACCEPT 1
@@ -45,6 +46,7 @@ struct oslSocketAddrImpl
};
struct oslPipeImpl {
+ std::mutex m_Mutex;
int m_Socket;
char m_Name[sizeof sockaddr_un::sun_path];
oslInterlockedCount m_nRefCount;