Ack.

Thanks,
Ramesh.

On 11/8/2016 8:50 PM, Anders Widell wrote:
>   osaf/libs/core/cplusplus/base/Makefile.am           |   4 +
>   osaf/libs/core/cplusplus/base/condition_variable.cc |  39 ++++++++
>   osaf/libs/core/cplusplus/base/condition_variable.h  |  95 
> +++++++++++++++++++++
>   osaf/libs/core/cplusplus/base/mutex.cc              |  46 ++++++++++
>   osaf/libs/core/cplusplus/base/mutex.h               |  82 ++++++++++++++++++
>   5 files changed, 266 insertions(+), 0 deletions(-)
>
>
> Add classes for Mutex, Lock and ConditionVariable - similar to std::mutex,
> std::unique_lock and std::condition_variable. One reason for adding these to
> OpenSAF is that the C++ standard library casses are unapproved by the Google 
> C++
> Style Guide. Another reason is that we can integrate them better into OpenSAF:
> we select the appropriate options when creating the mutex and condition
> variable, and we call osaf_abort() in case an unexpected error is
> encountered. Also, we will use an error checking mutex when the ENABLE_DEBUG
> preprocessor macro is defined - paving the way for special OpenSAF debug 
> builds.
>
> diff --git a/osaf/libs/core/cplusplus/base/Makefile.am 
> b/osaf/libs/core/cplusplus/base/Makefile.am
> --- a/osaf/libs/core/cplusplus/base/Makefile.am
> +++ b/osaf/libs/core/cplusplus/base/Makefile.am
> @@ -28,6 +28,8 @@ noinst_HEADERS = \
>       getenv.h \
>       log_message.h \
>       macros.h \
> +     mutex.h \
> +     condition_variable.h \
>       process.h \
>       time.h \
>       unix_client_socket.h \
> @@ -48,6 +50,8 @@ libbase_la_SOURCES = \
>       getenv.cc \
>       log_message.cc \
>       process.cc \
> +     mutex.cc \
> +     condition_variable.cc \
>       unix_client_socket.cc \
>       unix_server_socket.cc \
>       unix_socket.cc
> diff --git a/osaf/libs/core/cplusplus/base/condition_variable.cc 
> b/osaf/libs/core/cplusplus/base/condition_variable.cc
> new file mode 100644
> --- /dev/null
> +++ b/osaf/libs/core/cplusplus/base/condition_variable.cc
> @@ -0,0 +1,39 @@
> +/*      -*- OpenSAF  -*-
> + *
> + * (C) Copyright 2016 The OpenSAF Foundation
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
> + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
> + * under the GNU Lesser General Public License Version 2.1, February 1999.
> + * The complete license can be accessed from the following location:
> + * http://opensource.org/licenses/lgpl-license.php
> + * See the Copying file included with the OpenSAF distribution for full
> + * licensing terms.
> + *
> + * Author(s): Ericsson AB
> + *
> + */
> +
> +#include "osaf/libs/core/cplusplus/base/condition_variable.h"
> +
> +namespace base {
> +
> +ConditionVariable::ConditionVariable() : condition_variable_{} {
> +  pthread_condattr_t attr;
> +  int result = pthread_condattr_init(&attr);
> +  if (result != 0) osaf_abort(result);
> +  result = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
> +  if (result != 0) osaf_abort(result);
> +  result = pthread_cond_init(&condition_variable_, &attr);
> +  if (result != 0) osaf_abort(result);
> +  result = pthread_condattr_destroy(&attr);
> +  if (result != 0) osaf_abort(result);
> +}
> +
> +ConditionVariable::~ConditionVariable() {
> +  int result = pthread_cond_destroy(&condition_variable_);
> +  if (result != 0) osaf_abort(result);
> +}
> +
> +}  // namespace base
> diff --git a/osaf/libs/core/cplusplus/base/condition_variable.h 
> b/osaf/libs/core/cplusplus/base/condition_variable.h
> new file mode 100644
> --- /dev/null
> +++ b/osaf/libs/core/cplusplus/base/condition_variable.h
> @@ -0,0 +1,95 @@
> +/*      -*- OpenSAF  -*-
> + *
> + * (C) Copyright 2016 The OpenSAF Foundation
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
> + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
> + * under the GNU Lesser General Public License Version 2.1, February 1999.
> + * The complete license can be accessed from the following location:
> + * http://opensource.org/licenses/lgpl-license.php
> + * See the Copying file included with the OpenSAF distribution for full
> + * licensing terms.
> + *
> + * Author(s): Ericsson AB
> + *
> + */
> +
> +#ifndef OSAF_LIBS_CORE_CPLUSPLUS_BASE_CONDITION_VARIABLE_H_
> +#define OSAF_LIBS_CORE_CPLUSPLUS_BASE_CONDITION_VARIABLE_H_
> +
> +#include <pthread.h>
> +#include <cerrno>
> +#include "osaf/libs/core/common/include/osaf_utility.h"
> +#include "osaf/libs/core/cplusplus/base/macros.h"
> +#include "osaf/libs/core/cplusplus/base/mutex.h"
> +#include "osaf/libs/core/cplusplus/base/time.h"
> +
> +namespace base {
> +
> +enum class CvStatus { kNoTimeout, kTimeout };
> +
> +// A condition variable, with an API similar to std::condition_variable. The
> +// timed methods always use the monotonic clock (clock id CLOCK_MONOTONIC).
> +class ConditionVariable {
> + public:
> +  ConditionVariable();
> +  ~ConditionVariable();
> +  void Wait(Lock* lock) {
> +    int result = pthread_cond_wait(&condition_variable_,
> +                                   lock->mutex()->native_handle());
> +    if (result != 0) osaf_abort(result);
> +  }
> +  template <typename Predicate>
> +  void Wait(Lock* lock, Predicate predicate) {
> +    while (!predicate()) Wait(lock);
> +  }
> +  CvStatus WaitUntil(Lock* lock, const struct timespec& absolute_time) {
> +    int result = pthread_cond_timedwait(&condition_variable_,
> +                                        lock->mutex()->native_handle(),
> +                                        &absolute_time);
> +    if (result == 0) {
> +      return CvStatus::kNoTimeout;
> +    } else if (result == ETIMEDOUT) {
> +      return CvStatus::kTimeout;
> +    } else {
> +      osaf_abort(result);
> +    }
> +  }
> +  template <typename Predicate>
> +  bool WaitUntil(Lock* lock, const struct timespec& absolute_time,
> +                 Predicate predicate) {
> +    while (!predicate()) {
> +      if (WaitUntil(lock, absolute_time) == CvStatus::kTimeout) {
> +        return predicate();
> +      }
> +    }
> +    return true;
> +  }
> +  CvStatus WaitFor(Lock* lock, const struct timespec& relative_time) {
> +    struct timespec absolute_time = base::ReadMonotonicClock() + 
> relative_time;
> +    return WaitUntil(lock, absolute_time);
> +  }
> +  template <typename Predicate>
> +  bool WaitFor(Lock* lock, const struct timespec& relative_time,
> +               Predicate predicate) {
> +    struct timespec absolute_time = base::ReadMonotonicClock() + 
> relative_time;
> +    return WaitUntil(lock, absolute_time, predicate);
> +  }
> +  void NotifyOne() {
> +    int result = pthread_cond_signal(&condition_variable_);
> +    if (result != 0) osaf_abort(result);
> +  }
> +  void NotifyAll() {
> +    int result = pthread_cond_broadcast(&condition_variable_);
> +    if (result != 0) osaf_abort(result);
> +  }
> +
> + private:
> +  pthread_cond_t condition_variable_;
> +  DELETE_COPY_AND_MOVE_OPERATORS(ConditionVariable);
> +};
> +
> +}  // namespace base
> +
> +#endif  // OSAF_LIBS_CORE_CPLUSPLUS_BASE_CONDITION_VARIABLE_H_
> diff --git a/osaf/libs/core/cplusplus/base/mutex.cc 
> b/osaf/libs/core/cplusplus/base/mutex.cc
> new file mode 100644
> --- /dev/null
> +++ b/osaf/libs/core/cplusplus/base/mutex.cc
> @@ -0,0 +1,46 @@
> +/*      -*- OpenSAF  -*-
> + *
> + * (C) Copyright 2016 The OpenSAF Foundation
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
> + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
> + * under the GNU Lesser General Public License Version 2.1, February 1999.
> + * The complete license can be accessed from the following location:
> + * http://opensource.org/licenses/lgpl-license.php
> + * See the Copying file included with the OpenSAF distribution for full
> + * licensing terms.
> + *
> + * Author(s): Ericsson AB
> + *
> + */
> +
> +#include "osaf/libs/core/cplusplus/base/mutex.h"
> +#include "./config.h"
> +
> +namespace base {
> +
> +Mutex::Mutex() : mutex_{} {
> +  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);
> +#ifdef ENABLE_DEBUG
> +  result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
> +  if (result != 0) osaf_abort(result);
> +  result = pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST);
> +  if (result != 0) osaf_abort(result);
> +#endif
> +  result = pthread_mutex_init(&mutex_, &attr);
> +  if (result != 0) osaf_abort(result);
> +  result = pthread_mutexattr_destroy(&attr);
> +  if (result != 0) osaf_abort(result);
> +}
> +
> +Mutex::~Mutex() {
> +  int result = pthread_mutex_destroy(&mutex_);
> +  if (result != 0) osaf_abort(result);
> +}
> +
> +}  // namespace base
> diff --git a/osaf/libs/core/cplusplus/base/mutex.h 
> b/osaf/libs/core/cplusplus/base/mutex.h
> new file mode 100644
> --- /dev/null
> +++ b/osaf/libs/core/cplusplus/base/mutex.h
> @@ -0,0 +1,82 @@
> +/*      -*- OpenSAF  -*-
> + *
> + * (C) Copyright 2016 The OpenSAF Foundation
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
> + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
> + * under the GNU Lesser General Public License Version 2.1, February 1999.
> + * The complete license can be accessed from the following location:
> + * http://opensource.org/licenses/lgpl-license.php
> + * See the Copying file included with the OpenSAF distribution for full
> + * licensing terms.
> + *
> + * Author(s): Ericsson AB
> + *
> + */
> +
> +#ifndef OSAF_LIBS_CORE_CPLUSPLUS_BASE_MUTEX_H_
> +#define OSAF_LIBS_CORE_CPLUSPLUS_BASE_MUTEX_H_
> +
> +#include <pthread.h>
> +#include <cerrno>
> +#include "osaf/libs/core/common/include/osaf_utility.h"
> +#include "osaf/libs/core/cplusplus/base/macros.h"
> +
> +namespace base {
> +
> +// A mutex, with an API compatible with std::mutex. When built with the
> +// preprocessor macro ENABLE_DEBUG defined, the mutex will be created with 
> error
> +// checking enabled.
> +class Mutex {
> + public:
> +  using NativeHandleType = pthread_mutex_t*;
> +  Mutex();
> +  ~Mutex();
> +  void Lock() {
> +    int result = pthread_mutex_lock(&mutex_);
> +    if (result != 0) osaf_abort(result);
> +  }
> +  bool TryLock() {
> +    int result = pthread_mutex_trylock(&mutex_);
> +    if (result == 0) {
> +      return true;
> +    } else if (result == EBUSY) {
> +      return false;
> +    } else {
> +      osaf_abort(result);
> +    }
> +  }
> +  void Unlock() {
> +    int result = pthread_mutex_unlock(&mutex_);
> +    if (result != 0) osaf_abort(result);
> +  }
> +  NativeHandleType native_handle() { return &mutex_; }
> +
> + private:
> +  pthread_mutex_t mutex_;
> +  DELETE_COPY_AND_MOVE_OPERATORS(Mutex);
> +};
> +
> +// A lock manager, with an API similar to std::unique_lock, but simplified so
> +// that the mutex is always held during the lifetime of the lock object - 
> i.e.
> +// this class enforces the RAAI idiom.
> +class Lock {
> + public:
> +  explicit Lock(Mutex& mutex) : mutex_{&mutex} { mutex_->Lock(); }
> +  ~Lock() { mutex_->Unlock(); }
> +  void Swap(Lock& lock) {
> +    Mutex* tmp = mutex_;
> +    mutex_ = lock.mutex_;
> +    lock.mutex_ = tmp;
> +  }
> +  Mutex* mutex() const { return mutex_; }
> +
> + private:
> +  Mutex* mutex_;
> +  DELETE_COPY_AND_MOVE_OPERATORS(Lock);
> +};
> +
> +}  // namespace base
> +
> +#endif  // OSAF_LIBS_CORE_CPLUSPLUS_BASE_MUTEX_H_


------------------------------------------------------------------------------
_______________________________________________
Opensaf-devel mailing list
Opensaf-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to