0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00
mongodb/db/db.h

151 lines
3.9 KiB
C
Raw Normal View History

/**
* 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/>.
*/
2008-12-05 22:03:35 +01:00
#pragma once
2008-06-06 15:43:15 +02:00
#include "../stdafx.h"
#include "../grid/message.h"
void jniCallback(Message& m, Message& out);
2008-12-05 22:45:10 +01:00
class MutexInfo {
2008-12-10 22:52:25 +01:00
unsigned long long start, enter, timeLocked; // all in microseconds
2008-12-05 22:45:10 +01:00
int locked;
public:
MutexInfo() : locked(0) {
2008-12-10 22:52:25 +01:00
start = curTimeMicros64();
2008-12-05 22:45:10 +01:00
}
void entered() {
enter = curTimeMicros64();
locked++;
assert( locked == 1 );
}
void leaving() {
locked--;
assert( locked == 0 );
2008-12-10 22:52:25 +01:00
timeLocked += curTimeMicros64() - enter;
2008-12-05 22:45:10 +01:00
}
int isLocked() const { return locked; }
2008-12-10 22:52:25 +01:00
void timingInfo(unsigned long long &s, unsigned long long &tl) {
s = start; tl = timeLocked;
2008-12-05 22:45:10 +01:00
}
};
extern boost::mutex dbMutex;
2008-12-05 22:45:10 +01:00
extern MutexInfo dbMutexInfo;
//extern int dbLocked;
2008-12-10 19:07:18 +01:00
struct lock {
boostlock bl_;
MutexInfo& info_;
lock( boost::mutex &mutex, MutexInfo &info ) :
bl_( mutex ),
info_( info ) {
info_.entered();
}
~lock() {
info_.leaving();
}
};
struct dblock : public lock {
dblock() :
lock( dbMutex, dbMutexInfo ) {
}
};
2008-09-15 04:49:30 +02:00
/* a scoped release of a mutex temporarily -- like a scopedlock but reversed.
*/
struct temprelease {
boost::mutex& m;
temprelease(boost::mutex& _m) : m(_m) {
boost::detail::thread::lock_ops<boost::mutex>::unlock(m);
}
~temprelease() {
boost::detail::thread::lock_ops<boost::mutex>::lock(m);
}
};
#include "pdfile.h"
2008-12-05 22:45:10 +01:00
// tempish...move to TLS or pass all the way down as a parm
extern map<string,Database*> databases;
extern Database *database;
extern const char *curNs;
extern bool master;
/* returns true if the database ("database") did not exist, and it was created on this call */
inline bool setClient(const char *ns) {
/* we must be in critical section at this point as these are global
variables.
*/
assert( dbMutexInfo.isLocked() );
char cl[256];
curNs = ns;
nsToClient(ns, cl);
map<string,Database*>::iterator it = databases.find(cl);
if( it != databases.end() ) {
database = it->second;
return false;
}
// when master for replication, we advertise all the db's, and that
// looks like a 'first operation'. so that breaks this log message's
// meaningfulness. instead of fixing (which would be better), we just
// stop showing for now.
if( !master )
log() << "first operation for database " << cl << endl;
bool justCreated;
Database *c = new Database(cl, justCreated);
databases[cl] = c;
database = c;
database->finishInit();
return justCreated;
}
/* We normally keep around a curNs ptr -- if this ns is temporary,
use this instead so we don't have a bad ptr. we could have made a copy,
but trying to be fast as we call setClient this for every single operation.
*/
inline bool setClientTempNs(const char *ns) {
bool jc = setClient(ns);
curNs = "";
return jc;
}
2008-09-15 04:49:30 +02:00
struct dbtemprelease {
string clientname;
dbtemprelease() {
if( database )
clientname = database->name;
2008-12-05 22:45:10 +01:00
dbMutexInfo.leaving();
2008-09-15 04:49:30 +02:00
boost::detail::thread::lock_ops<boost::mutex>::unlock(dbMutex);
}
~dbtemprelease() {
boost::detail::thread::lock_ops<boost::mutex>::lock(dbMutex);
2008-12-05 22:45:10 +01:00
dbMutexInfo.entered();
2008-09-15 04:49:30 +02:00
if( clientname.empty() )
database = 0;
2008-09-15 04:49:30 +02:00
else
setClient(clientname.c_str());
}
};
2008-12-05 22:45:10 +01:00
#include "dbinfo.h"