diff options
Diffstat (limited to 'src/components/include/utils/rwlock.h')
-rw-r--r-- | src/components/include/utils/rwlock.h | 95 |
1 files changed, 84 insertions, 11 deletions
diff --git a/src/components/include/utils/rwlock.h b/src/components/include/utils/rwlock.h index b5042acbfe..1083dbd63f 100644 --- a/src/components/include/utils/rwlock.h +++ b/src/components/include/utils/rwlock.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Ford Motor Company + * Copyright (c) 2015, Ford Motor Company * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,8 +30,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SRC_COMPONENTS_UTILS_INCLUDE_UTILS_RWLOCK_H_ -#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_RWLOCK_H_ +#ifndef SRC_COMPONENTS_INCLUDE_UTILS_RWLOCK_H_ +#define SRC_COMPONENTS_INCLUDE_UTILS_RWLOCK_H_ #if defined(OS_POSIX) #include <pthread.h> @@ -49,21 +49,91 @@ typedef pthread_rwlock_t PlatformRWLock; #endif } // namespace impl +/** + * RW locks wrapper + * Read-write locks permit concurrent reads and exclusive writes to a protected shared resource. + * The read-write lock is a single entity that can be locked in read or write mode. + * To modify a resource, a thread must first acquire the exclusive write lock. + * An exclusive write lock is not permitted until all read locks have been released. + */ + class RWLock { public: RWLock(); ~RWLock(); - void AcquireForReading(); - void AcquireForWriting(); - void Release(); + + /** + * @brief Acqure read-write lock for reading. + * The calling thread acquires the read lock if a writer does not + * hold the lock and there are no writers blocked on the lock. + * It is unspecified whether the calling thread acquires the lock + * when a writer does not hold the lock and there are writers waiting for the lock. + * If a writer holds the lock, the calling thread will not acquire the read lock. + * If the read lock is not acquired, the calling thread blocks + * (that is, it does not return from the AcquireForReading()) until it can acquire the lock. + * Results are undefined if the calling thread holds a write lock on rwlock at the time the call is made. + * A thread can hold multiple concurrent read locks on rwlock + * (that is, successfully call AcquireForReading() n times) + * If so, the thread must perform matching unlocks (that is, it must call Release() n times). + * @returns true if lock was acquired and false if was not + */ + bool AcquireForReading(); + + /** + * @brief try to Acqure read-write lock for reading. + * Applies a read lock as in AcquireForReading() + * with the exception that the function fails if any thread + * holds a write lock on rwlock or there are writers blocked on rwlock. + * But not blocks calling thread. + * @returns true if lock was acquired and false if was not + */ + bool TryAcquireForReading(); + + /** + * @brief Try to Acqure read-write lock for writing. + * Applies a write lock like AcquireForWriting(), with the exception that the + * function fails if any thread currently holds rwlock (for reading or writing) + * Invoke of TryAcquireForWriting will not block calling thread and returns "false" + * @returns true if lock was acquired and false if was not + */ + bool TryAcquireForWriting(); + + /** + * @brief Acqure read-write lock for writing. + * Applies a write lock to the read-write lock. + * The calling thread acquires the write lock if no other thread (reader or writer) + * holds the read-write lock rwlock. Otherwise, the thread blocks + * (that is, does not return from the AcquireForWriting() call) + * until it can acquire the lock. + * Results are undefined if the calling thread holds the read-write lock (whether a read or write lock) + * at the time the call is made. + * The thread must perform matching unlock (that is, it must call Release()). + * @returns true if lock was acquired and false if was not + */ + bool AcquireForWriting(); + + /** + * @brief Release read-write lock. + * Releases a lock held on the read-write lock object. + * Results are undefined if the read-write lock rwlock + * is not held by the calling thread. + * @returns true if lock was released and false if was not + */ + bool Release(); private: impl::PlatformRWLock rwlock_; }; +/** + * @brief Makes auto lock read-write locks for reading + * Please use AutoReadLock to acquire for reading and (automatically) release it + */ + class AutoReadLock { public: - explicit AutoReadLock(RWLock& rwlock) : rwlock_(rwlock) { + explicit AutoReadLock(RWLock& rwlock) + : rwlock_(rwlock) { rwlock_.AcquireForReading(); } ~AutoReadLock() { @@ -72,13 +142,17 @@ class AutoReadLock { private: RWLock& rwlock_; - DISALLOW_COPY_AND_ASSIGN(AutoReadLock); }; +/** + * @brief Makes auto lock read-write locks for writing + * Please use AutoWriteLock to acquire for writing and (automatically) release it + */ class AutoWriteLock { public: - explicit AutoWriteLock(RWLock& rwlock) : rwlock_(rwlock) { + explicit AutoWriteLock(RWLock& rwlock) + : rwlock_(rwlock) { rwlock_.AcquireForWriting(); } ~AutoWriteLock() { @@ -87,10 +161,9 @@ class AutoWriteLock { private: RWLock& rwlock_; - DISALLOW_COPY_AND_ASSIGN(AutoWriteLock); }; } // namespace sync_primitives -#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_RWLOCK_H_ +#endif // SRC_COMPONENTS_INCLUDE_UTILS_RWLOCK_H_ |