osaf/libs/core/cplusplus/base/unix_client_socket.cc | 28 ++++-------
osaf/libs/core/cplusplus/base/unix_client_socket.h | 2 +-
osaf/libs/core/cplusplus/base/unix_server_socket.cc | 19 +------
osaf/libs/core/cplusplus/base/unix_server_socket.h | 4 +-
osaf/libs/core/cplusplus/base/unix_socket.cc | 49 ++++++++++++++++++---
osaf/libs/core/cplusplus/base/unix_socket.h | 22 ++++++---
6 files changed, 74 insertions(+), 50 deletions(-)
Make the UnixSocket class thread-safe by protecting Open() and Close() with a
mutex.
diff --git a/osaf/libs/core/cplusplus/base/unix_client_socket.cc
b/osaf/libs/core/cplusplus/base/unix_client_socket.cc
--- a/osaf/libs/core/cplusplus/base/unix_client_socket.cc
+++ b/osaf/libs/core/cplusplus/base/unix_client_socket.cc
@@ -29,24 +29,18 @@ UnixClientSocket::UnixClientSocket(const
UnixClientSocket::~UnixClientSocket() {
}
-void UnixClientSocket::Open() {
- if (fd() < 0) {
- UnixSocket::Open();
- if (fd() >= 0) {
- int result;
- int e;
- do {
- result = connect(fd(), addr(), addrlen());
- e = errno;
- if (result != 0 && (e == EALREADY || e == EINPROGRESS)) {
- struct timespec delay{0, 10000000};
- clock_nanosleep(CLOCK_MONOTONIC, 0, &delay, nullptr);
- }
- } while (result != 0 && (e == EINTR || e == EALREADY
- || e == EINPROGRESS));
- if (result != 0) Close();
+bool UnixClientSocket::OpenHook(int sock) {
+ int result;
+ int e;
+ do {
+ result = connect(sock, addr(), addrlen());
+ e = errno;
+ if (result != 0 && (e == EALREADY || e == EINPROGRESS)) {
+ struct timespec delay{0, 10000000};
+ clock_nanosleep(CLOCK_MONOTONIC, 0, &delay, nullptr);
}
- }
+ } while (result != 0 && (e == EINTR || e == EALREADY || e == EINPROGRESS));
+ return result == 0;
}
} // namespace base
diff --git a/osaf/libs/core/cplusplus/base/unix_client_socket.h
b/osaf/libs/core/cplusplus/base/unix_client_socket.h
--- a/osaf/libs/core/cplusplus/base/unix_client_socket.h
+++ b/osaf/libs/core/cplusplus/base/unix_client_socket.h
@@ -33,7 +33,7 @@ class UnixClientSocket : public UnixSock
// from the file system.
virtual ~UnixClientSocket();
protected:
- virtual void Open();
+ virtual bool OpenHook(int sock);
};
} // namespace base
diff --git a/osaf/libs/core/cplusplus/base/unix_server_socket.cc
b/osaf/libs/core/cplusplus/base/unix_server_socket.cc
--- a/osaf/libs/core/cplusplus/base/unix_server_socket.cc
+++ b/osaf/libs/core/cplusplus/base/unix_server_socket.cc
@@ -29,23 +29,12 @@ UnixServerSocket::UnixServerSocket(const
UnixServerSocket::~UnixServerSocket() {
}
-void UnixServerSocket::Open() {
- if (fd() < 0) {
- UnixSocket::Open();
- if (fd() >= 0) {
- int result = bind(fd(), addr(), addrlen());
- if (result != 0) Close();
- }
- }
+bool UnixServerSocket::OpenHook(int sock) {
+ return bind(sock, addr(), addrlen()) == 0;
}
-void UnixServerSocket::Close() {
- if (fd() >= 0) {
- int e = errno;
- UnixSocket::Close();
- unlink(path());
- errno = e;
- }
+void UnixServerSocket::CloseHook() {
+ unlink(path());
}
} // namespace base
diff --git a/osaf/libs/core/cplusplus/base/unix_server_socket.h
b/osaf/libs/core/cplusplus/base/unix_server_socket.h
--- a/osaf/libs/core/cplusplus/base/unix_server_socket.h
+++ b/osaf/libs/core/cplusplus/base/unix_server_socket.h
@@ -33,8 +33,8 @@ class UnixServerSocket : public UnixSock
// file system.
virtual ~UnixServerSocket();
protected:
- virtual void Open();
- virtual void Close();
+ virtual bool OpenHook(int sock);
+ virtual void CloseHook();
};
} // namespace base
diff --git a/osaf/libs/core/cplusplus/base/unix_socket.cc
b/osaf/libs/core/cplusplus/base/unix_socket.cc
--- a/osaf/libs/core/cplusplus/base/unix_socket.cc
+++ b/osaf/libs/core/cplusplus/base/unix_socket.cc
@@ -19,40 +19,75 @@
#include <sys/socket.h>
#include <unistd.h>
#include <cstring>
+#include "osaf/libs/core/common/include/osaf_utility.h"
namespace base {
UnixSocket::UnixSocket(const std::string& path) :
fd_{-1},
- addr_{AF_UNIX, {}} {
+ addr_{AF_UNIX, {}},
+ mutex_{} {
if (path.size() < sizeof(addr_.sun_path)) {
memcpy(addr_.sun_path, path.c_str(), path.size() + 1);
} else {
addr_.sun_path[0] = '\0';
}
+ pthread_mutexattr_t attr;
+ int result = pthread_mutexattr_init(&attr);
+ if (result != 0) osaf_abort(result);
+ result = pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
+ if (result != 0) osaf_abort(result);
+ result = pthread_mutex_init(&mutex_, &attr);
+ if (result != 0) osaf_abort(result);
+ result = pthread_mutexattr_destroy(&attr);
+ if (result != 0) osaf_abort(result);
}
-void UnixSocket::Open() {
- if (fd_ < 0) {
+int UnixSocket::Open() {
+ osaf_mutex_lock_ordie(&mutex_);
+ int sock = fd_;
+ if (sock < 0) {
if (addr_.sun_path[0] != '\0') {
- fd_ = socket(AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
+ sock = socket(AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
+ if (sock >= 0 && !OpenHook(sock)) {
+ int e = errno;
+ close(sock);
+ sock = -1;
+ errno = e;
+ }
+ fd_ = sock;
} else {
errno = ENAMETOOLONG;
}
}
+ osaf_mutex_unlock_ordie(&mutex_);
+ return sock;
}
UnixSocket::~UnixSocket() {
Close();
+ int result = pthread_mutex_destroy(&mutex_);
+ if (result != 0) osaf_abort(result);
}
void UnixSocket::Close() {
- if (fd_ >= 0) {
+ osaf_mutex_lock_ordie(&mutex_);
+ int sock = fd_;
+ if (sock >= 0) {
int e = errno;
- close(fd_);
+ close(sock);
+ fd_ = -1;
+ CloseHook();
errno = e;
- fd_ = -1;
}
+ osaf_mutex_unlock_ordie(&mutex_);
+}
+
+bool UnixSocket::OpenHook(int) {
+ return true;
+}
+
+void UnixSocket::CloseHook() {
}
} // namespace base
diff --git a/osaf/libs/core/cplusplus/base/unix_socket.h
b/osaf/libs/core/cplusplus/base/unix_socket.h
--- a/osaf/libs/core/cplusplus/base/unix_socket.h
+++ b/osaf/libs/core/cplusplus/base/unix_socket.h
@@ -18,6 +18,7 @@
#ifndef OSAF_LIBS_CORE_CPLUSPLUS_BASE_UNIX_SOCKET_H_
#define OSAF_LIBS_CORE_CPLUSPLUS_BASE_UNIX_SOCKET_H_
+#include <pthread.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <cerrno>
@@ -36,11 +37,12 @@ class UnixSocket {
// handled by retrying the send() call in a loop. In case of other errors,
the
// socket will be closed.
ssize_t Send(const void* buffer, size_t length) {
- if (fd_ < 0) Open();
+ int sock = fd_;
+ if (sock < 0) sock = Open();
ssize_t result = -1;
- if (fd_ >= 0) {
+ if (sock >= 0) {
do {
- result = send(fd_, buffer, length, MSG_NOSIGNAL);
+ result = send(sock, buffer, length, MSG_NOSIGNAL);
} while (result < 0 && errno == EINTR);
if (result < 0 && errno != EAGAIN && errno != EWOULDBLOCK) Close();
}
@@ -51,11 +53,12 @@ class UnixSocket {
// is handled by retrying the recv() call in a loop. In case of other errors,
// the socket will be closed.
ssize_t Recv(void* buffer, size_t length) {
- if (fd_ < 0) Open();
+ int sock = fd_;
+ if (sock < 0) sock = Open();
ssize_t result = -1;
- if (fd_ >= 0) {
+ if (sock >= 0) {
do {
- result = recv(fd_, buffer, length, 0);
+ result = recv(sock, buffer, length, 0);
} while (result < 0 && errno == EINTR);
if (result < 0 && errno != EAGAIN && errno != EWOULDBLOCK) Close();
}
@@ -69,8 +72,10 @@ class UnixSocket {
protected:
explicit UnixSocket(const std::string& path);
- virtual void Open();
- virtual void Close();
+ int Open();
+ void Close();
+ virtual bool OpenHook(int sock);
+ virtual void CloseHook();
const struct sockaddr* addr() const {
return reinterpret_cast<const struct sockaddr*>(&addr_);
}
@@ -80,6 +85,7 @@ class UnixSocket {
private:
int fd_;
struct sockaddr_un addr_;
+ pthread_mutex_t mutex_;
DELETE_COPY_AND_MOVE_OPERATORS(UnixSocket);
};
------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors
Access to Intel Xeon Phi processor-based developer platforms.
With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today. http://sdm.link/xeonphi
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel