/usr/include/mongo/db/d_concurrency.h is in mongodb-dev 1:2.4.9-1ubuntu2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 | // @file d_concurrency.h
/**
* Copyright (C) 2008 10gen Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// only used by mongod, thus the name ('d')
// (also used by dbtests test binary, which is running mongod test code)
#pragma once
#include "mongo/base/string_data.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/lockstat.h"
#include "mongo/util/concurrency/mutex.h"
#include "mongo/util/concurrency/rwlock.h"
namespace mongo {
class WrapperForRWLock;
class LockState;
class Lock : boost::noncopyable {
public:
enum Nestable { notnestable=0, local, admin };
static int isLocked(); // true if *anything* is locked (by us)
static int isReadLocked(); // r or R
static int somethingWriteLocked(); // w or W
static bool isW(); // W
static bool isR();
static bool isRW(); // R or W. i.e., we are write-exclusive
static bool nested();
static bool isWriteLocked(const StringData& ns);
static bool atLeastReadLocked(const StringData& ns); // true if this db is locked
static void assertAtLeastReadLocked(const StringData& ns);
static void assertWriteLocked(const StringData& ns);
static bool dbLevelLockingEnabled();
static LockStat* globalLockStat();
static LockStat* nestableLockStat( Nestable db );
class ScopedLock;
// note: avoid TempRelease when possible. not a good thing.
struct TempRelease {
TempRelease();
~TempRelease();
const bool cant; // true if couldn't because of recursive locking
ScopedLock *scopedLk;
};
/** turn on "parallel batch writer mode". blocks all other threads. this mode is off
by default. note only one thread creates a ParallelBatchWriterMode object; the rest just
call iAmABatchParticipant(). Note that this lock is not released on a temprelease, just
the normal lock things below.
*/
class ParallelBatchWriterMode : boost::noncopyable {
RWLockRecursive::Exclusive _lk;
public:
ParallelBatchWriterMode() : _lk(_batchLock) {}
static void iAmABatchParticipant();
static RWLockRecursive &_batchLock;
};
private:
class ParallelBatchWriterSupport : boost::noncopyable {
public:
ParallelBatchWriterSupport();
private:
void tempRelease();
void relock();
scoped_ptr<RWLockRecursive::Shared> _lk;
friend class ScopedLock;
};
public:
class ScopedLock : boost::noncopyable {
public:
virtual ~ScopedLock();
/** @return micros since we started acquiring */
long long acquireFinished( LockStat* stat );
// Accrue elapsed lock time since last we called reset
void recordTime();
// Start recording a new period, starting now()
void resetTime();
protected:
explicit ScopedLock( char type );
private:
friend struct TempRelease;
void tempRelease(); // TempRelease class calls these
void relock();
protected:
virtual void _tempRelease() = 0;
virtual void _relock() = 0;
private:
ParallelBatchWriterSupport _pbws_lk;
void _recordTime( long long micros );
Timer _timer;
char _type; // 'r','w','R','W'
LockStat* _stat; // the stat for the relevant lock to increment when we're done
};
// note that for these classes recursive locking is ok if the recursive locking "makes sense"
// i.e. you could grab globalread after globalwrite.
class GlobalWrite : public ScopedLock {
bool noop;
protected:
void _tempRelease();
void _relock();
public:
// stopGreed is removed and does NOT work
// timeoutms is only for writelocktry -- deprecated -- do not use
GlobalWrite(bool stopGreed = false, int timeoutms = -1 );
virtual ~GlobalWrite();
void downgrade(); // W -> R
void upgrade(); // caution see notes
};
class GlobalRead : public ScopedLock { // recursive is ok
public:
bool noop;
protected:
void _tempRelease();
void _relock();
public:
// timeoutms is only for readlocktry -- deprecated -- do not use
GlobalRead( int timeoutms = -1 );
virtual ~GlobalRead();
};
// lock this database. do not shared_lock globally first, that is handledin herein.
class DBWrite : public ScopedLock {
/**
* flow
* 1) lockDB
* a) lockTop
* b) lockNestable or lockOther
* 2) unlockDB
*/
void lockTop(LockState&);
void lockNestable(Nestable db);
void lockOther(const StringData& db);
void lockDB(const string& ns);
void unlockDB();
protected:
void _tempRelease();
void _relock();
public:
DBWrite(const StringData& dbOrNs);
virtual ~DBWrite();
class UpgradeToExclusive : private boost::noncopyable {
public:
UpgradeToExclusive();
~UpgradeToExclusive();
bool gotUpgrade() const { return _gotUpgrade; }
private:
bool _gotUpgrade;
};
private:
bool _locked_w;
bool _locked_W;
WrapperForRWLock *_weLocked;
const string _what;
bool _nested;
};
// lock this database for reading. do not shared_lock globally first, that is handledin herein.
class DBRead : public ScopedLock {
void lockTop(LockState&);
void lockNestable(Nestable db);
void lockOther(const StringData& db);
void lockDB(const string& ns);
void unlockDB();
protected:
void _tempRelease();
void _relock();
public:
DBRead(const StringData& dbOrNs);
virtual ~DBRead();
private:
bool _locked_r;
WrapperForRWLock *_weLocked;
string _what;
bool _nested;
};
};
class readlocktry : boost::noncopyable {
bool _got;
scoped_ptr<Lock::GlobalRead> _dbrlock;
public:
readlocktry( int tryms );
~readlocktry();
bool got() const { return _got; }
};
class writelocktry : boost::noncopyable {
bool _got;
scoped_ptr<Lock::GlobalWrite> _dbwlock;
public:
writelocktry( int tryms );
~writelocktry();
bool got() const { return _got; }
};
/** a mutex, but reported in curop() - thus a "high level" (HL) one
some overhead so we don't use this for everything. the externalobjsort mutex
uses this, as it can be held for eons. implementation still needed. */
class HLMutex : public SimpleMutex {
LockStat ls;
public:
HLMutex(const char *name);
};
}
|