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

checkpoitn a little sync work

This commit is contained in:
dwight 2009-11-28 11:50:46 -05:00
parent fbda5ee9bf
commit 8a26ff4f8d
5 changed files with 74 additions and 45 deletions

View File

@ -13,8 +13,38 @@
#pragma once
#include <boost/thread/shared_mutex.hpp>
namespace mongo {
#if 0
typedef boost::shared_mutex MongoMutex;
#else
/* this will be for old versions of boost */
class MongoMutex {
boost::recursive_mutex m;
public:
void lock() {
#if BOOST_VERSION >= 103500
m.lock();
#else
boost::detail::thread::lock_ops<boost::recursive_mutex>::lock(m);
#endif
}
void unlock() {
#if BOOST_VERSION >= 103500
m.unlock();
#else
boost::detail::thread::lock_ops<boost::recursive_mutex>::unlock(m);
#endif
}
void lock_shared() { lock(); }
void unlock_shared() { unlock(); }
};
#endif
/* mutex time stats */
class MutexInfo {
unsigned long long start, enter, timeLocked; // all in microseconds
@ -45,9 +75,10 @@ namespace mongo {
}
};
extern boost::recursive_mutex &dbMutex;
extern MongoMutex &dbMutex;
extern MutexInfo dbMutexInfo;
/*
struct lock {
recursive_boostlock bl_;
MutexInfo& info_;
@ -60,46 +91,43 @@ namespace mongo {
info_.leaving();
}
};
*/
void dbunlocking_write();
void dbunlocking_read();
/* use writelock and readlock instead */
struct dblock : public lock {
dblock() :
lock( dbMutex, dbMutexInfo ) {
}
~dblock() {
dbunlocking_write();
}
};
struct writelock : public lock {
writelock(const string& ns) :
lock( dbMutex, dbMutexInfo ) {
}
writelock(const char * ns) :
lock( dbMutex, dbMutexInfo ) {
struct writelock {
writelock(const string& ns) {
dbMutex.lock();
dbMutexInfo.entered();
}
~writelock() {
dbunlocking_write();
dbMutexInfo.leaving();
dbMutex.unlock();
}
};
struct readlock : public lock {
readlock(const string& ns) :
lock( dbMutex, dbMutexInfo ) {
}
readlock(const char* ns) :
lock( dbMutex, dbMutexInfo ) {
struct readlock {
readlock(const string& ns) {
dbMutex.lock_shared();
}
~readlock() {
dbunlocking_read();
dbMutex.unlock_shared();
}
};
/* use writelock and readlock instead */
struct dblock : public writelock {
dblock() : writelock("") { }
~dblock() {
}
};
/* a scoped release of a mutex temporarily -- like a scopedlock but reversed.
*/
/*
struct temprelease {
boost::mutex& m;
temprelease(boost::mutex& _m) : m(_m) {
@ -117,6 +145,7 @@ namespace mongo {
#endif
}
};
*/
inline void assertInWriteLock() {
assert( dbMutexInfo.isLocked() );

View File

@ -388,7 +388,7 @@ namespace mongo {
sleepsecs(5);
continue;
}
sleepmillis( _sleepsecs * 1000 );
sleepmillis( (int)(_sleepsecs * 1000) );
MemoryMappedFile::flushAll( false );
log(1) << "flushing mmmap" << endl;
}
@ -1043,7 +1043,16 @@ BOOL CtrlHandler( DWORD fdwCtrlType )
}
#endif
void temptestfoo() {
MongoMutex m;
m.lock();
// m.lock_upgrade();
m.lock_shared();
}
} // namespace mongo
#include "recstore.h"
#include "reccache.h"

View File

@ -120,18 +120,10 @@ namespace mongo {
}
client.top.clientStop();
dbMutexInfo.leaving();
#if BOOST_VERSION >= 103500
dbMutex.unlock();
#else
boost::detail::thread::lock_ops<boost::recursive_mutex>::unlock(dbMutex);
#endif
}
~dbtemprelease() {
#if BOOST_VERSION >= 103500
dbMutex.lock();
#else
boost::detail::thread::lock_ops<boost::recursive_mutex>::lock(dbMutex);
#endif
dbMutexInfo.entered();
if ( clientname.empty() )
cc().setns("", 0);

View File

@ -49,7 +49,7 @@ namespace mongo {
bool autoresync = false;
/* we use new here so we don't have to worry about destructor orders at program shutdown */
boost::recursive_mutex &dbMutex( *(new boost::recursive_mutex) );
MongoMutex &dbMutex( *(new MongoMutex) );
MutexInfo dbMutexInfo;
string dbExecCommand;

View File

@ -48,7 +48,6 @@
namespace mongo {
extern boost::recursive_mutex &dbMutex;
void ensureHaveIdIndex(const char *ns);
/* if 1 sync() is running */
@ -1213,17 +1212,17 @@ namespace mongo {
time_t saveLast = time(0);
while ( 1 ) {
/* from a.s.:
I think the idea here is that we can establish a sync point between the local op log and the remote log with the following steps:
1) identify most recent op in local log -- call it O
2) ask "does nextOpTime reflect the tail of the remote op log?" (in other words, is more() false?) - If yes, all subsequent ops after nextOpTime in the remote log must have occurred after O. If no, we can't establish a sync point.
Note that we can't do step (2) followed by step (1) because if we do so ops may be added to both machines between steps (2) and (1) and we can't establish a sync point. (In particular, between (2) and (1) an op may be added to the remote log before a different op is added to the local log. In this case, the newest remote op will have occurred after nextOpTime but before O.)
Now, for performance reasons we don't want to have to identify the most recent op in the local log every time we call c->more() because in performance sensitive situations more() will be true most of the time. So we do:
0) more()?
1) find most recent op in local log
I think the idea here is that we can establish a sync point between the local op log and the remote log with the following steps:
1) identify most recent op in local log -- call it O
2) ask "does nextOpTime reflect the tail of the remote op log?" (in other words, is more() false?) - If yes, all subsequent ops after nextOpTime in the remote log must have occurred after O. If no, we can't establish a sync point.
Note that we can't do step (2) followed by step (1) because if we do so ops may be added to both machines between steps (2) and (1) and we can't establish a sync point. (In particular, between (2) and (1) an op may be added to the remote log before a different op is added to the local log. In this case, the newest remote op will have occurred after nextOpTime but before O.)
Now, for performance reasons we don't want to have to identify the most recent op in the local log every time we call c->more() because in performance sensitive situations more() will be true most of the time. So we do:
0) more()?
1) find most recent op in local log
2) more()?
*/
if ( !c->more() ) {