Storage Engine API
locker.h
Go to the documentation of this file.
1 
29 #pragma once
30 
31 #include <climits> // For UINT_MAX
32 #include <vector>
33 
36 #include "mongo/db/operation_context.h"
37 #include "mongo/stdx/thread.h"
38 
39 namespace mongo {
40 
47 class Locker {
49 
51 
52 public:
53  virtual ~Locker() {}
54 
63  virtual bool isNoop() const {
64  return false;
65  }
66 
74  static void setGlobalThrottling(class TicketHolder* reading, class TicketHolder* writing);
75 
80 
85  virtual ClientState getClientState() const = 0;
86 
87  virtual LockerId getId() const = 0;
88 
93  virtual stdx::thread::id getThreadId() const = 0;
94 
98  virtual void updateThreadIdToCurrentThread() = 0;
99 
103  virtual void unsetThreadId() = 0;
104 
108  virtual void setSharedLocksShouldTwoPhaseLock(bool sharedLocksShouldTwoPhaseLock) = 0;
109 
124  virtual void setMaxLockTimeout(Milliseconds maxTimeout) = 0;
125 
129  virtual bool hasMaxLockTimeout() = 0;
130 
134  virtual void unsetMaxLockTimeout() = 0;
135 
158  virtual LockResult lockGlobal(OperationContext* opCtx, LockMode mode) = 0;
159  virtual LockResult lockGlobal(LockMode mode) = 0;
160 
169  virtual LockResult lockGlobalBegin(OperationContext* opCtx, LockMode mode, Date_t deadline) = 0;
170  virtual LockResult lockGlobalBegin(LockMode mode, Date_t deadline) = 0;
171 
176  virtual LockResult lockGlobalComplete(OperationContext* opCtx, Date_t deadline) = 0;
177  virtual LockResult lockGlobalComplete(Date_t deadline) = 0;
178 
183  virtual void lockMMAPV1Flush() = 0;
184 
196  virtual bool unlockGlobal() = 0;
197 
206  virtual void downgradeGlobalXtoSForMMAPV1() = 0;
207 
216  virtual void beginWriteUnitOfWork() = 0;
217  virtual void endWriteUnitOfWork() = 0;
218 
219  virtual bool inAWriteUnitOfWork() const = 0;
220 
246  virtual LockResult lock(OperationContext* opCtx,
247  ResourceId resId,
248  LockMode mode,
249  Date_t deadline = Date_t::max(),
250  bool checkDeadlock = false) = 0;
251 
256  virtual LockResult lock(ResourceId resId,
257  LockMode mode,
258  Date_t deadline = Date_t::max(),
259  bool checkDeadlock = false) = 0;
260 
264  virtual void downgrade(ResourceId resId, LockMode newMode) = 0;
265 
273  virtual bool unlock(ResourceId resId) = 0;
274 
282  virtual LockMode getLockMode(ResourceId resId) const = 0;
283  virtual bool isLockHeldForMode(ResourceId resId, LockMode mode) const = 0;
284 
285  // These are shortcut methods for the above calls. They however check that the entire
286  // hierarchy is properly locked and because of this they are very expensive to call.
287  // Do not use them in performance critical code paths.
288  virtual bool isDbLockedForMode(StringData dbName, LockMode mode) const = 0;
289  virtual bool isCollectionLockedForMode(StringData ns, LockMode mode) const = 0;
290 
295  virtual ResourceId getWaitingResource() const = 0;
296 
300  struct OneLock {
301  // What lock resource is held?
303 
304  // In what mode is it held?
306 
307  // Reporting/serialization order is by resourceId, which is the canonical locking order
308  bool operator<(const OneLock& rhs) const {
309  return resourceId < rhs.resourceId;
310  }
311  };
312 
319  struct LockerInfo {
320  // List of high-level locks held by this locker, sorted by ResourceId
321  std::vector<OneLock> locks;
322 
323  // If isValid(), then what lock this particular locker is sleeping on
325 
326  // Lock timing statistics
328  };
329 
330  virtual void getLockerInfo(LockerInfo* lockerInfo) const = 0;
331 
336  virtual boost::optional<LockerInfo> getLockerInfo() const = 0;
337 
342  struct LockSnapshot {
343  // The global lock is handled differently from all other locks.
345 
346  // The non-global non-flush locks held, sorted by granularity. That is, locks[i] is
347  // coarser or as coarse as locks[i + 1].
348  std::vector<OneLock> locks;
349  };
350 
368  virtual bool saveLockStateAndUnlock(LockSnapshot* stateOut) = 0;
369 
374  virtual void restoreLockState(OperationContext* opCtx, const LockSnapshot& stateToRestore) = 0;
375  virtual void restoreLockState(const LockSnapshot& stateToRestore) = 0;
376 
381  virtual void releaseTicket() = 0;
382 
389  virtual void reacquireTicket(OperationContext* opCtx) = 0;
390 
391  //
392  // These methods are legacy from LockerImpl and will eventually go away or be converted to
393  // calls into the Locker methods
394  //
395 
396  virtual void dump() const = 0;
397 
398  virtual bool isW() const = 0;
399  virtual bool isR() const = 0;
400 
401  virtual bool isLocked() const = 0;
402  virtual bool isWriteLocked() const = 0;
403  virtual bool isReadLocked() const = 0;
404  virtual bool isGlobalLockedRecursively() = 0;
405 
410  virtual bool hasLockPending() const = 0;
411 
420  }
423  }
424 
429  void setShouldAcquireTicket(bool newValue) {
430  invariant(!isLocked() || isNoop());
431  _shouldAcquireTicket = newValue;
432  }
433  bool shouldAcquireTicket() const {
434  return _shouldAcquireTicket;
435  }
441  }
442 
443 protected:
444  Locker() {}
445 
453 
459 
460 private:
462  bool _shouldAcquireTicket = true;
463 };
464 
477 public:
478  /*
479  * Accepts a Locker, and increments the _uninterruptibleLocksRequested. Decrements the
480  * counter when destoyed.
481  */
482  explicit UninterruptibleLockGuard(Locker* locker) : _locker(locker) {
483  invariant(_locker);
484  invariant(_locker->_uninterruptibleLocksRequested >= 0);
485  invariant(_locker->_uninterruptibleLocksRequested < std::numeric_limits<int>::max());
486  _locker->_uninterruptibleLocksRequested += 1;
487  }
488 
490  invariant(_locker->_uninterruptibleLocksRequested > 0);
491  _locker->_uninterruptibleLocksRequested -= 1;
492  }
493 
494 private:
495  Locker* const _locker;
496 };
497 
503 
504 public:
506  : _lockState(lockState),
507  _originalShouldConflict(_lockState->shouldConflictWithSecondaryBatchApplication()) {
508  _lockState->setShouldConflictWithSecondaryBatchApplication(false);
509  }
510 
512  _lockState->setShouldConflictWithSecondaryBatchApplication(_originalShouldConflict);
513  }
514 
515 private:
518 };
519 
520 } // namespace mongo
void setShouldConflictWithSecondaryBatchApplication(bool newValue)
If set to false, this opts out of conflicting with replication&#39;s use of the ParallelBatchWriterMode l...
Definition: locker.h:418
SingleThreadedLockStats stats
Definition: locker.h:327
ShouldNotConflictWithSecondaryBatchApplicationBlock(Locker *lockState)
Definition: locker.h:505
virtual void setMaxLockTimeout(Milliseconds maxTimeout)=0
This is useful to ensure that potential deadlocks do not occur.
virtual bool isLocked() const =0
virtual void dump() const =0
Interface for acquiring locks.
Definition: locker.h:47
virtual bool unlockGlobal()=0
Decrements the reference count on the global lock.
Locker *const _lockState
Definition: locker.h:516
virtual void reacquireTicket(OperationContext *opCtx)=0
Reacquires a ticket for the Locker.
Collection *const const NamespaceString & ns
Definition: collection_info_cache_impl.cpp:53
virtual bool isR() const =0
Definition: locker.h:79
Locker()
Definition: locker.h:444
bool operator<(const OneLock &rhs) const
Definition: locker.h:308
~ShouldNotConflictWithSecondaryBatchApplicationBlock()
Definition: locker.h:511
ResourceId resourceId
Definition: locker.h:302
Copyright (C) 2014 MongoDB Inc.
Definition: bson_collection_catalog_entry.cpp:38
ResourceId waitingResource
Definition: locker.h:324
virtual LockResult lockGlobalComplete(OperationContext *opCtx, Date_t deadline)=0
Calling lockGlobalComplete without an OperationContext does not allow the lock acquisition to be inte...
virtual LockMode getLockMode(ResourceId resId) const =0
Retrieves the mode in which a lock is held or checks whether the lock held for a particular resource ...
UninterruptibleLockGuard(Locker *locker)
Definition: locker.h:482
uint64_t LockerId
Definition: lock_manager_defs.h:246
bool shouldConflictWithSecondaryBatchApplication() const
Definition: locker.h:421
virtual void lockMMAPV1Flush()=0
This method is used only in the MMAP V1 storage engine, otherwise it is a no-op.
virtual void beginWriteUnitOfWork()=0
beginWriteUnitOfWork/endWriteUnitOfWork are called at the start and end of WriteUnitOfWorks.
RAII-style class to opt out of replication&#39;s use of ParallelBatchWriterMode.
Definition: locker.h:501
Returns information and locking statistics for this instance of the locker.
Definition: locker.h:319
Definition: locker.h:79
bool _shouldConflictWithSecondaryBatchApplication
Definition: locker.h:461
std::vector< OneLock > locks
Definition: locker.h:348
virtual void setSharedLocksShouldTwoPhaseLock(bool sharedLocksShouldTwoPhaseLock)=0
Indicate that shared locks should participate in two-phase locking for this Locker instance...
LockMode globalMode
Definition: locker.h:344
unsigned _numResourcesToUnlockAtEndUnitOfWork
The number of LockRequests to unlock at the end of this WUOW.
Definition: locker.h:458
void setShouldAcquireTicket(bool newValue)
If set to false, this opts out of the ticket mechanism.
Definition: locker.h:429
virtual boost::optional< LockerInfo > getLockerInfo() const =0
Returns boost::none if this is an instance of LockerNoop, or a populated LockerInfo otherwise...
Uniquely identifies a lockable resource.
Definition: lock_manager_defs.h:176
virtual bool isDbLockedForMode(StringData dbName, LockMode mode) const =0
unsigned numResourcesToUnlockAtEndUnitOfWorkForTest() const
This function is for unit testing only.
Definition: locker.h:439
virtual ClientState getClientState() const =0
Return whether client is holding any locks (active), or is queued on any locks or waiting for a ticke...
virtual LockResult lock(OperationContext *opCtx, ResourceId resId, LockMode mode, Date_t deadline=Date_t::max(), bool checkDeadlock=false)=0
Acquires lock on the specified resource in the specified mode and returns the outcome of the operatio...
Definition: locker.h:79
virtual LockResult lockGlobalBegin(OperationContext *opCtx, LockMode mode, Date_t deadline)=0
Requests the global lock to be acquired in the specified mode.
virtual void releaseTicket()=0
Releases the ticket associated with the Locker.
This class prevents lock acquisitions from being interrupted when it is in scope. ...
Definition: locker.h:476
virtual bool isCollectionLockedForMode(StringData ns, LockMode mode) const =0
virtual LockResult lockGlobal(OperationContext *opCtx, LockMode mode)=0
This should be the first method invoked for a particular Locker object.
virtual void downgradeGlobalXtoSForMMAPV1()=0
This is only necessary for the MMAP V1 engine and in particular, the fsyncLock command which needs to...
LockResult
Return values for the locking functions of the lock manager.
Definition: lock_manager_defs.h:99
LockMode
Lock modes.
Definition: lock_manager_defs.h:59
MONGO_DISALLOW_COPYING(Locker)
static void setGlobalThrottling(class TicketHolder *reading, class TicketHolder *writing)
Require global lock attempts to obtain tickets from &#39;reading&#39; (for MODE_S and MODE_IS), and from &#39;writing&#39; (for MODE_IX), which must have static lifetimes.
Definition: lock_state.cpp:254
virtual void restoreLockState(OperationContext *opCtx, const LockSnapshot &stateToRestore)=0
Re-locks all locks whose state was stored in &#39;stateToRestore&#39;.
ClientState
State for reporting the number of active and queued reader and writer clients.
Definition: locker.h:79
virtual void unsetThreadId()=0
Clears any cached thread id values.
std::array< DefaultLockerImpl, kMaxPerfThreads > locker
Definition: d_concurrency_bm.cpp:66
Locker *const _locker
Definition: locker.h:495
virtual bool isWriteLocked() const =0
~UninterruptibleLockGuard()
Definition: locker.h:489
virtual void downgrade(ResourceId resId, LockMode newMode)=0
Downgrades the specified resource&#39;s lock mode without changing the reference count.
Definition: locker.h:79
bool _shouldAcquireTicket
Definition: locker.h:462
virtual void endWriteUnitOfWork()=0
bool shouldAcquireTicket() const
Definition: locker.h:433
virtual ~Locker()
Definition: locker.h:53
int _uninterruptibleLocksRequested
The number of callers that are guarding from lock interruptions.
Definition: locker.h:452
virtual bool isGlobalLockedRecursively()=0
virtual bool hasMaxLockTimeout()=0
Returns whether this Locker has a maximum lock timeout set.
virtual bool isLockHeldForMode(ResourceId resId, LockMode mode) const =0
LockSnapshot captures the state of all resources that are locked, what modes they&#39;re locked in...
Definition: locker.h:342
virtual void unsetMaxLockTimeout()=0
Clears the max lock timeout override set by setMaxLockTimeout() above.
virtual LockerId getId() const =0
virtual bool inAWriteUnitOfWork() const =0
virtual bool unlock(ResourceId resId)=0
Releases a lock previously acquired through a lock call.
Describes a single lock acquisition for reporting/serialization purposes.
Definition: locker.h:300
std::vector< OneLock > locks
Definition: locker.h:321
Collection *const OperationContext *const opCtx
Definition: collection_impl.cpp:80
Definition: locker.h:79
virtual bool isNoop() const
Returns true if this is an instance of LockerNoop.
Definition: locker.h:63
LockMode mode
Definition: locker.h:305
virtual bool isReadLocked() const =0
const bool _originalShouldConflict
Definition: locker.h:517
virtual void updateThreadIdToCurrentThread()=0
Updates any cached thread id values to represent the current thread.
virtual bool isW() const =0
virtual bool saveLockStateAndUnlock(LockSnapshot *stateOut)=0
Retrieves all locks held by this transaction, other than RESOURCE_MUTEX locks, and what mode they&#39;re ...
virtual bool hasLockPending() const =0
Pending means we are currently trying to get a lock (could be the parallel batch writer lock)...
virtual stdx::thread::id getThreadId() const =0
Get a platform-specific thread identifier of the thread which owns the this locker for tracing purpos...
virtual ResourceId getWaitingResource() const =0
Returns the resource that this locker is waiting/blocked on (if any).