1 // Copyright 2018 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef COMPONENTS_SERVICES_STORAGE_INDEXED_DB_SCOPES_SCOPE_LOCK_H_ 6 #define COMPONENTS_SERVICES_STORAGE_INDEXED_DB_SCOPES_SCOPE_LOCK_H_ 7 8 #include <iosfwd> 9 #include <string> 10 11 #include "base/callback.h" 12 #include "base/callback_helpers.h" 13 #include "base/macros.h" 14 #include "components/services/storage/indexed_db/scopes/scope_lock_range.h" 15 #include "third_party/leveldatabase/src/include/leveldb/comparator.h" 16 #include "third_party/leveldatabase/src/include/leveldb/slice.h" 17 18 namespace content { 19 20 // Represents a granted lock in the ScopesLockManager. When this object is 21 // destroyed, the lock is released. Since default construction is supported, 22 // |is_locked()| can be used to inquire locked status. Also, |Release()| can 23 // be called to manually release the lock, which appropriately updates the 24 // |is_locked()| result. 25 class ScopeLock { 26 public: 27 using LockReleasedCallback = 28 base::OnceCallback<void(int level, ScopeLockRange range)>; 29 30 ScopeLock(); 31 ~ScopeLock(); 32 ScopeLock(ScopeLock&&) noexcept; 33 // |lock_released_callback| is called when the lock is released, either by 34 // destruction of this object or by the |Released()| call. It will be called 35 // synchronously on the sequence runner this lock is released on. 36 ScopeLock(ScopeLockRange range, 37 int level, 38 LockReleasedCallback lock_released_callback); 39 // The lock in |other| is not released, and |this| must not be holding a lock. 40 ScopeLock& operator=(ScopeLock&& other) noexcept; 41 42 // Returns true if this object is holding a lock. is_locked()43 bool is_locked() const { return !lock_released_callback_.is_null(); } 44 45 // Explicitly releases the granted lock. 46 // 47 // The lock is also released implicitly when this instance is destroyed. 48 // This method is idempotent, i.e. it's valid to call Release() on an 49 // instance that does not hold a granted lock. 50 void Release(); 51 level()52 int level() const { return level_; } range()53 const ScopeLockRange& range() const { return range_; } 54 55 private: 56 friend std::ostream& operator<<(std::ostream& out, const ScopeLock& range); 57 friend bool operator==(const ScopeLock& x, const ScopeLock& y); 58 friend bool operator<(const ScopeLock& x, const ScopeLock& y); 59 60 ScopeLockRange range_; 61 int level_ = 0; 62 // Closure to run when the lock is released. The lock is held when this is 63 // non-null. 64 LockReleasedCallback lock_released_callback_; 65 66 DISALLOW_COPY_AND_ASSIGN(ScopeLock); 67 }; 68 69 // Logging support. 70 std::ostream& operator<<(std::ostream& out, const ScopeLock& range); 71 72 // Equality doesn't take into account whether the lock 'is_locked()' or not, 73 // only the level and the range. 74 bool operator==(const ScopeLock& x, const ScopeLock& y); 75 bool operator!=(const ScopeLock& x, const ScopeLock& y); 76 // Comparison operator to allow sorting for locking / unlocking order. 77 bool operator<(const ScopeLock& x, const ScopeLock& y); 78 79 } // namespace content 80 81 #endif // COMPONENTS_SERVICES_STORAGE_INDEXED_DB_SCOPES_SCOPE_LOCK_H_ 82