summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/db/client.h2
-rw-r--r--src/mongo/db/curop.cpp1
-rw-r--r--src/mongo/db/d_concurrency.cpp58
-rw-r--r--src/mongo/db/d_concurrency.h10
-rw-r--r--src/mongo/util/concurrency/rwlockimpl.cpp4
-rw-r--r--src/mongo/util/concurrency/simplerwlock.h3
6 files changed, 58 insertions, 20 deletions
diff --git a/src/mongo/db/client.h b/src/mongo/db/client.h
index 7dc4376868d..d40d79436db 100644
--- a/src/mongo/db/client.h
+++ b/src/mongo/db/client.h
@@ -56,6 +56,8 @@ namespace mongo {
class Client : public ClientBasic {
static Client *syncThread;
public:
+ LockState _ls;
+
// always be in clientsMutex when manipulating this. killop stuff uses these.
static set<Client*>& clients;
static mongo::mutex& clientsMutex;
diff --git a/src/mongo/db/curop.cpp b/src/mongo/db/curop.cpp
index 475b5c46ea8..22de0f47e84 100644
--- a/src/mongo/db/curop.cpp
+++ b/src/mongo/db/curop.cpp
@@ -150,6 +150,7 @@ namespace mongo {
b.append( "threadId" , _client->_threadId );
if ( _client->_connectionId )
b.appendNumber( "connectionId" , _client->_connectionId );
+ _client->_ls.reportState(b);
}
if ( ! _message.empty() ) {
diff --git a/src/mongo/db/d_concurrency.cpp b/src/mongo/db/d_concurrency.cpp
index db39c12f69f..b6a7385dbdf 100644
--- a/src/mongo/db/d_concurrency.cpp
+++ b/src/mongo/db/d_concurrency.cpp
@@ -87,8 +87,8 @@ namespace mongo {
static void unlocking_w();
static void unlocking_W();
static QLock& q = *new QLock();
- TSP_DECLARE(LockState,ls);
- TSP_DEFINE(LockState,ls);
+ //TSP_DECLARE(LockState,ls);
+ //TSP_DEFINE(LockState,ls);
void runExclusively(void (*f)(void)) {
q.runExclusively(f);
@@ -122,20 +122,44 @@ namespace mongo {
}
inline LockState& lockState() {
- LockState *p = ls.get();
- if( unlikely( p == 0 ) ) {
- ls.reset(p = new LockState());
- }
- return *p;
- }
- LockState::LockState() : recursive(0),
- threadState(0),
- nestableCount(0),
- otherCount(0),
- otherLock(NULL),
- scopedLk(NULL)
- {
- whichNestable = Lock::notnestable;
+ return cc()._ls;
+ }
+
+ static string kind(int n) {
+ if( n > 0 )
+ return "W";
+ if( n < 0 )
+ return "R";
+ return "?";
+ }
+ /** Note: this is is called by the currentOp command, which is a different
+ thread. So be careful about thread safety here. For example reading
+ this->otherName would not be safe as-is!
+ */
+ void LockState::reportState(BSONObjBuilder& res) {
+ BSONObjBuilder b;
+ if( threadState ) {
+ char buf[2];
+ buf[0] = threadState; buf[1] = 0;
+ b.append("^", buf);
+ }
+ if( nestableCount ) {
+ string s = "?";
+ if( whichNestable == Lock::local )
+ s = "local";
+ else if( whichNestable == Lock::admin )
+ s = "admin";
+ b.append(s, kind(nestableCount));
+ }
+ if( otherCount ) {
+ SimpleRWLock *k = otherLock;
+ if( k ) {
+ b.append(k->name, kind(otherCount));
+ }
+ }
+ BSONObj o = b.obj();
+ if( !o.isEmpty() )
+ res.append("locks", o);
}
void LockState::Dump() {
@@ -604,7 +628,7 @@ namespace mongo {
mapsf<string,SimpleRWLock*>::ref r(dblocks);
SimpleRWLock*& lock = r[db];
if( lock == 0 )
- lock = new SimpleRWLock();
+ lock = new SimpleRWLock(db.c_str());
ls.otherLock = lock;
}
fassert(16134,weLocked==0);
diff --git a/src/mongo/db/d_concurrency.h b/src/mongo/db/d_concurrency.h
index cb3002bd29b..520253e7502 100644
--- a/src/mongo/db/d_concurrency.h
+++ b/src/mongo/db/d_concurrency.h
@@ -199,6 +199,7 @@ namespace mongo {
LockState();
void dump();
static void Dump();
+ void reportState(BSONObjBuilder& b);
unsigned recursive; // we allow recursively asking for a lock; we track that here
@@ -216,4 +217,13 @@ namespace mongo {
Lock::ScopedLock *scopedLk; // for the nonrecursive case. otherwise there would be many
};
+ inline LockState::LockState() : recursive(0),
+ threadState(0),
+ nestableCount(0),
+ otherCount(0),
+ otherLock(NULL),
+ scopedLk(NULL)
+ {
+ whichNestable = Lock::notnestable;
+ }
}
diff --git a/src/mongo/util/concurrency/rwlockimpl.cpp b/src/mongo/util/concurrency/rwlockimpl.cpp
index f397c2a95e5..27f20b66e8c 100644
--- a/src/mongo/util/concurrency/rwlockimpl.cpp
+++ b/src/mongo/util/concurrency/rwlockimpl.cpp
@@ -23,7 +23,7 @@ using namespace std;
namespace mongo {
#if defined(_WIN32)
- SimpleRWLock::SimpleRWLock(const char *p) {
+ SimpleRWLock::SimpleRWLock(const char *p) : name(p?p:"") {
InitializeSRWLock(&_lock);
}
# if defined(_DEBUG)
@@ -74,7 +74,7 @@ namespace mongo {
}
# endif
#else
- SimpleRWLock::SimpleRWLock(const char *p) { }
+ SimpleRWLock::SimpleRWLock(const char *p) : name(p?p:"") { }
void SimpleRWLock::lock() { m.lock(); }
void SimpleRWLock::unlock() { m.unlock(); }
void SimpleRWLock::lock_shared() { m.lock_shared(); }
diff --git a/src/mongo/util/concurrency/simplerwlock.h b/src/mongo/util/concurrency/simplerwlock.h
index c2778539fce..03e7fab3795 100644
--- a/src/mongo/util/concurrency/simplerwlock.h
+++ b/src/mongo/util/concurrency/simplerwlock.h
@@ -18,7 +18,8 @@ namespace mongo {
unsigned tid;
#endif
public:
- SimpleRWLock(const char *p = 0);
+ const string name;
+ SimpleRWLock(const char *name = 0);
void lock();
void unlock();
void lock_shared();