improve Synchronized LockedPtr class, and add new lock() APIs
authorAdam Simpkins <simpkins@fb.com>
Tue, 12 Jul 2016 01:36:00 +0000 (18:36 -0700)
committerFacebook Github Bot 5 <facebook-github-bot-5-bot@fb.com>
Tue, 12 Jul 2016 01:38:55 +0000 (18:38 -0700)
commit50f4f92c284492f4bb87f3735c82e180a0e49327
tree85b4cd641e953269ea35760b5b677e23b0292c31
parent594f18f7ba21543612b02b97c3abdff7dd40aa3a
improve Synchronized LockedPtr class, and add new lock() APIs

Summary:
This refactors the Synchronized::LockedPtr class, and adds new
lock()/wlock()/rlock() APIs to Synchronized.

The LockedPtr changes include:

- Consolidate code so a single template class can be used for both const
  and non-const operation, rather than requiring separate class definitions.
  A LockPolicy template parameter controls if the lock should be acquired in
  exclusive or shared mode, and a SynchronizedType parameter controls whether
  or not the internal data is const or not.

- Specialize LockedPtr for std::mutex, so it uses std::unique_lock<std::mutex>
  internally.  This requires slightly more storage space internally, but it
  allows Synchronized<T, std::mutex> to be used with std::condition_variable.

- Implement operator*() to dereference the pointer and retrieve a reference to
  the locked data.

- Implement operator!() and provide an isValid() method to check the validity
  of the LockedPtr.  These are needed to tell if a timed acquire operation
  succeeded or timed out.

- Drop the LockedPtr copy constructor.  Previously the copy constructor
  acquired the lock a second time.  If anyone needs the ability to hold a
  shared lock a second time solely via a LockedPtr (and not via the original
  Synchronized object), I think we should add back a much more explicit API to
  do this.

Furthermore, this adds lock(), wlock(), and rlock() methods to Synchronized to
explicitly obtain a LockedPtr.  These APIs behave similar to operator->(), but
are more explicit, and require the caller to make a concious choice about
whether or not an exclusive or shared lock should be acquired.  The lock()
method is present only on Synchronized instantiations using an exclusive mutex,
and the wlock() and rlock() methods are present only on Synchronized
instantiations that use a shared mutex.

I plan to deprecate the existing Synchronized::operator->() method and the
various SYNCHRONIZED macros in upcoming diffs.  For now this adds comments
directing users to the new methods, but does not start any of the technical
deprecation changes yet.

Reviewed By: yfeldblum

Differential Revision: D3526489

fbshipit-source-id: 8a96a09b68656ff9215dcdfdf32ecd2bfbb1727f
folly/LockTraits.h
folly/Synchronized.h
folly/test/SynchronizedTest.cpp
folly/test/SynchronizedTestLib-inl.h
folly/test/SynchronizedTestLib.h