Skip to content

Commit

Permalink
Added RecursiveLock
Browse files Browse the repository at this point in the history
Added also Lock interface (implemented by RecursiveLock and Mutex).
LockGuard moved to used the generic Lock object instead of the Mutex
  • Loading branch information
francesco-romano committed Mar 21, 2015
1 parent d1acfa0 commit b94cde8
Show file tree
Hide file tree
Showing 13 changed files with 388 additions and 15 deletions.
10 changes: 9 additions & 1 deletion src/libYARP_OS/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ set(YARP_OS_HDRS include/yarp/os/AbstractCarrier.h
include/yarp/os/InputProtocol.h
include/yarp/os/InputStream.h
include/yarp/os/LocalReader.h
include/yarp/os/Lock.h
include/yarp/os/LockGuard.h
include/yarp/os/Log.h
include/yarp/os/LogStream.h
Expand Down Expand Up @@ -77,6 +78,7 @@ set(YARP_OS_HDRS include/yarp/os/AbstractCarrier.h
include/yarp/os/Publisher.h
include/yarp/os/Random.h
include/yarp/os/RateThread.h
include/yarp/os/RecursiveLock.h
include/yarp/os/ResourceFinder.h
include/yarp/os/ResourceFinderOptions.h
include/yarp/os/RFModule.h
Expand Down Expand Up @@ -131,12 +133,14 @@ set(YARP_OS_IDL_HDRS include/yarp/os/idl/BareStyle.h
include/yarp/os/idl/WireVocab.h
include/yarp/os/idl/WireWriter.h)

set(YARP_OS_IMPL_HDRS include/yarp/os/impl/ACESemaphoreImpl.h
set(YARP_OS_IMPL_HDRS include/yarp/os/impl/ACELockImpl.h
include/yarp/os/impl/ACESemaphoreImpl.h
include/yarp/os/impl/AuthHMAC.h
include/yarp/os/impl/BottleImpl.h
include/yarp/os/impl/BufferedConnectionWriter.h
include/yarp/os/impl/Carriers.h
include/yarp/os/impl/Companion.h
include/yarp/os/impl/CXX11LockImpl.h
include/yarp/os/impl/CXX11SemaphoreImpl.h
include/yarp/os/impl/DgramTwoWayStream.h
include/yarp/os/impl/Dispatcher.h
Expand All @@ -149,6 +153,7 @@ set(YARP_OS_IMPL_HDRS include/yarp/os/impl/ACESemaphoreImpl.h
include/yarp/os/impl/HttpCarrier.h
include/yarp/os/impl/IOException.h
include/yarp/os/impl/LocalCarrier.h
include/yarp/os/impl/LockImpl.h
include/yarp/os/impl/Logger.h
include/yarp/os/impl/LogImpl.h
include/yarp/os/impl/LogForwarder.h
Expand Down Expand Up @@ -177,6 +182,7 @@ set(YARP_OS_IMPL_HDRS include/yarp/os/impl/ACESemaphoreImpl.h
include/yarp/os/impl/PortCorePackets.h
include/yarp/os/impl/PortCoreUnit.h
include/yarp/os/impl/PortManager.h
include/yarp/os/impl/POSIXLockImpl.h
include/yarp/os/impl/POSIXSemaphoreImpl.h
include/yarp/os/impl/Protocol.h
include/yarp/os/impl/RunCheckpoints.h
Expand Down Expand Up @@ -233,6 +239,7 @@ set(YARP_OS_SRCS src/AbstractCarrier.cpp
src/IConfig.cpp
src/InputStream.cpp
src/LocalCarrier.cpp
src/Lock.cpp
src/LockGuard.cpp
src/Log.cpp
src/Logger.cpp
Expand Down Expand Up @@ -286,6 +293,7 @@ set(YARP_OS_SRCS src/AbstractCarrier.cpp
src/Protocol.cpp
src/Random.cpp
src/RateThread.cpp
src/RecursiveLock.cpp
src/ResourceFinder.cpp
src/ResourceFinderOptions.cpp
src/RFModule.cpp
Expand Down
61 changes: 61 additions & 0 deletions src/libYARP_OS/include/yarp/os/Lock.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*-

/*
* Copyright (C) 2015 Robotics and Cognitive Sciences Department. IIT
* Authors: Francesco Romano
* CopyPolicy: Released under the terms of the LGPLv2.1 or later, see LGPL.TXT
*
*/

#ifndef YARP_LOCK_H
#define YARP_LOCK_H

#include <yarp/os/api.h>

namespace yarp {
namespace os {
class Lock;
}
}
/**
* This interface defines the Lock object.
* A Lock is a synchronization primitive that can be used to protect shared data from being
* simultaneously accessed by multiple threads.
*
*
*/
class YARP_OS_API yarp::os::Lock
{
public:
virtual ~Lock();

/**
* @brief Lock the associated resource, waiting if the resource is busy.
*
* See the actual implementation documentation for the correct use
*/
virtual void lock() = 0;

/**
* @brief Lock the associated resource if it is free.
*
* If the lock is successfully taken returns true, otherwise returns false
* and no lock is taken.
* See the actual implementation documentation for the correct use
*
* @return true if the associated resource was successfully locked.
*
*/
virtual bool tryLock() = 0;

/**
* @brief Unlock the associated resource thus freeing waiting threads.
*
* See the actual implementation documentation for the correct use
*
*/
virtual void unlock() = 0;
};


#endif /* end of include guard: YARP_LOCK_H */
6 changes: 3 additions & 3 deletions src/libYARP_OS/include/yarp/os/LockGuard.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

namespace yarp {
namespace os {
class Mutex;
class Lock;
class LockGuard;
}
}
Expand All @@ -34,7 +34,7 @@ class YARP_OS_API yarp::os::LockGuard {
* The behavior is undefined if _mutex is destroyed before the LockGuard object is.
* @param _mutex the mutex which will be locked
*/
explicit LockGuard(yarp::os::Mutex& _mutex);
explicit LockGuard(yarp::os::Lock& _lock);

/**
* destructs the LockGuard object, unlocks the underlying mutex
Expand All @@ -49,7 +49,7 @@ class YARP_OS_API yarp::os::LockGuard {
/** Assignment operator is disabled */
LockGuard& operator=(const LockGuard&);

yarp::os::Mutex& mutex; /*!< underlining mutex */
yarp::os::Lock& lock; /*!< underlining mutex */
};

#endif
11 changes: 6 additions & 5 deletions src/libYARP_OS/include/yarp/os/Mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#define _YARP2_MUTEX_

#include <yarp/os/api.h>
#include <yarp/os/Lock.h>

namespace yarp {
namespace os {
Expand All @@ -25,7 +26,7 @@ namespace yarp {
* C++11, for eventual replacement by that class.
*
*/
class YARP_OS_API yarp::os::Mutex {
class YARP_OS_API yarp::os::Mutex : public yarp::os::Lock {
public:

/**
Expand All @@ -40,7 +41,7 @@ class YARP_OS_API yarp::os::Mutex {
* Destructor.
*
*/
~Mutex();
virtual ~Mutex();

/**
*
Expand All @@ -49,7 +50,7 @@ class YARP_OS_API yarp::os::Mutex {
* the resource.
*
*/
void lock();
virtual void lock();

/**
*
Expand All @@ -60,7 +61,7 @@ class YARP_OS_API yarp::os::Mutex {
* @return true if the associated resource was successfully locked.
*
*/
bool tryLock();
virtual bool tryLock();

/**
*
Expand All @@ -69,7 +70,7 @@ class YARP_OS_API yarp::os::Mutex {
* the behavior is undefined.
*
*/
void unlock();
virtual void unlock();
private:
void *implementation;
};
Expand Down
82 changes: 82 additions & 0 deletions src/libYARP_OS/include/yarp/os/RecursiveLock.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*-

/*
* Copyright (C) 2015 Robotics and Cognitive Sciences Department. IIT
* Authors: Francesco Romano
* CopyPolicy: Released under the terms of the LGPLv2.1 or later, see LGPL.TXT
*
*/

#ifndef YARP_RECURSIVELOCK_H
#define YARP_RECURSIVELOCK_H

#include "Lock.h"

namespace yarp {
namespace os {
class RecursiveLock;
}
}

/**
* RecursiveLock offers exclusive, recursive ownership semantics:
* - A calling thread owns a RecursiveLock for a period of time that starts when it successfully calls either lock or tryLock. During this period, the thread may make additional calls to lock or tryLock. The period of ownership ends when the thread makes a matching number of calls to unlock.
* - When a thread owns a RecursiveLock, all other threads will block (for calls to lock) or receive a false return value (for tryLock) if they attempt to claim ownership of the RecursiveLock.
* The behavior of a program is undefined if a RecursiveLock is destroyed while still owned by some thread.
* The behavior of a program is undefined if a RecursiveLock is unlocked by a thread which is not
* currently owning the RecursiveLock
*
*/
class YARP_OS_API yarp::os::RecursiveLock : public yarp::os::Lock {
public:

/**
*
* Constructor.
*
*/
RecursiveLock();

/**
*
* Destructor.
*
*/
virtual ~RecursiveLock();

/**
* @brief Lock the associated resource, waiting if the resource is busy.
*
* If the thread which is currently owning the resource calls
* this function, it will not block, and a reference count will be increased
* Thu number of calls to lock() must be balanced by the same number of
* calls to unlock()
*
*/
virtual void lock();

/**
* @brief Lock the associated resource if it is free.
*
* @see RecursiveLock#lock() for more detailed description
* @return true if the associated resource was successfully locked. False otherwise
*
*/
virtual bool tryLock();

/**
* @brief Unlock the associated resource thus freeing waiting threads.
*
* If the resource is not currently locked by the calling thread,
* the behavior is undefined.
*
*/
virtual void unlock();

private:
void *implementation;
};


#endif /* end of include guard: YARP_RECURSIVELOCK_H */

2 changes: 2 additions & 0 deletions src/libYARP_OS/include/yarp/os/all.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
#include <yarp/os/Semaphore.h>
#include <yarp/os/Subscriber.h>
#include <yarp/os/Mutex.h>
#include <yarp/os/RecursiveLock.h>
#include <yarp/os/Lock.h>
#include <yarp/os/LockGuard.h>
#include <yarp/os/Event.h>
#include <yarp/os/Thread.h>
Expand Down
44 changes: 44 additions & 0 deletions src/libYARP_OS/include/yarp/os/impl/ACELockImpl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*-

/*
* Copyright (C) 2015 Robotics and Cognitive Sciences Department. IIT
* Authors: Francesco Romano
* CopyPolicy: Released under the terms of the LGPLv2.1 or later, see LGPL.TXT
*
*/

#ifndef YARP_ACELOCKIMPL_H
#define YARP_ACELOCKIMPL_H

#include <ace/Recursive_Thread_Mutex.h>
#include <yarp/os/LogStream.h>

class YARP_OS_impl_API yarp::os::impl::RecursiveLockImpl {
public:
void lock() {
int result = mutex.acquire();
if (result != -1) return;
yError("Mutex lock failed (errno %d)", ACE_OS::last_error());
}

bool tryLock() {
int result = mutex.tryacquire();
if (result != -1) return true;
//if errno is EBUSY this is a "clean" failure: lock is busy
if (ACE_OS::last_error() == EBUSY) return false;
//different error: return false and print error
yError("Mutex tryLock failed (errno %d)", ACE_OS::last_error());
return false;

}

// unlock
void unlock() {
mutex.release();
}

private:
ACE_Recursive_Thread_Mutex mutex;
};

#endif /* end of include guard: YARP_ACELOCKIMPL_H */
38 changes: 38 additions & 0 deletions src/libYARP_OS/include/yarp/os/impl/CXX11LockImpl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*-

/*
* Copyright (C) 2015 Robotics and Cognitive Sciences Department. IIT
* Authors: Francesco Romano
* CopyPolicy: Released under the terms of the LGPLv2.1 or later, see LGPL.TXT
*
*/

#ifndef YARP_CXX11LOCKIMPL_H
#define YARP_CXX11LOCKIMPL_H

#include <mutex>

class YARP_OS_impl_API yarp::os::impl::RecursiveLockImpl {
public:
RecursiveLockImpl() {}
RecursiveLockImpl(RecursiveLockImpl&) = delete;
RecursiveLockImpl& operator= (RecursiveLockImpl&) = delete;

void lock() {
mutex.lock();
}

bool tryLock() {
return mutex.try_lock();
}

// increment
void unlock() {
mutex.unlock();
}

private:
std::recursive_mutex mutex;
};

#endif /* end of include guard: YARP_CXX11LOCKIMPL_H */

0 comments on commit b94cde8

Please sign in to comment.