summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--db/db.vcxproj2
-rwxr-xr-xdb/db.vcxproj.filters9
-rw-r--r--db/lasterror.h4
-rw-r--r--db/repl/manager.cpp2
-rw-r--r--db/repl/replset.cpp2
-rw-r--r--db/repl/replset.h32
-rw-r--r--db/security.h4
-rw-r--r--pch.h90
-rw-r--r--util/concurrency/msg.h8
-rw-r--r--util/concurrency/mutex.h96
-rw-r--r--util/concurrency/task.cpp13
-rw-r--r--util/goodies.h54
12 files changed, 197 insertions, 119 deletions
diff --git a/db/db.vcxproj b/db/db.vcxproj
index 01810cbd420..183c561b5b9 100644
--- a/db/db.vcxproj
+++ b/db/db.vcxproj
@@ -561,7 +561,6 @@
<None Include="repl\testing.js" />
</ItemGroup>
<ItemGroup>
- <ClInclude Include="..\boost_pieces\any.hpp" />
<ClInclude Include="..\client\dbclientcursor.h" />
<ClInclude Include="..\client\gridfs.h" />
<ClInclude Include="..\client\parallel.h" />
@@ -569,6 +568,7 @@
<ClInclude Include="..\pcre-7.4\config.h" />
<ClInclude Include="..\pcre-7.4\pcre.h" />
<ClInclude Include="..\util\concurrency\msg.h" />
+ <ClInclude Include="..\util\concurrency\mutex.h" />
<ClInclude Include="..\util\concurrency\task.h" />
<ClInclude Include="..\util\mongoutils\html.h" />
<ClInclude Include="..\util\mongoutils\str.h" />
diff --git a/db/db.vcxproj.filters b/db/db.vcxproj.filters
index ab997764ce0..cd4e889649f 100755
--- a/db/db.vcxproj.filters
+++ b/db/db.vcxproj.filters
@@ -680,15 +680,15 @@
<ClInclude Include="..\util\concurrency\task.h">
<Filter>util\concurrency</Filter>
</ClInclude>
- <ClInclude Include="..\boost_pieces\any.hpp">
- <Filter>util\boost_pieces</Filter>
- </ClInclude>
<ClInclude Include="repl\multicmd.h">
<Filter>replset</Filter>
</ClInclude>
<ClInclude Include="..\util\concurrency\msg.h">
<Filter>util\concurrency</Filter>
</ClInclude>
+ <ClInclude Include="..\util\concurrency\mutex.h">
+ <Filter>util\concurrency</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="libs">
@@ -727,9 +727,6 @@
<Filter Include="client">
<UniqueIdentifier>{932baf83-ba80-49e5-8280-f1b9c8dbbde6}</UniqueIdentifier>
</Filter>
- <Filter Include="util\boost_pieces">
- <UniqueIdentifier>{3e9cf058-6d12-41ae-b65a-dc93aaafbf93}</UniqueIdentifier>
- </Filter>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="db.rc">
diff --git a/db/lasterror.h b/db/lasterror.h
index f70cf32af4f..e0b92746ac4 100644
--- a/db/lasterror.h
+++ b/db/lasterror.h
@@ -17,10 +17,6 @@
#pragma once
-#include <boost/thread/tss.hpp>
-#undef assert
-#define assert MONGO_assert
-
namespace mongo {
class BSONObjBuilder;
class Message;
diff --git a/db/repl/manager.cpp b/db/repl/manager.cpp
index 8ad8b32083a..28dd3a7d041 100644
--- a/db/repl/manager.cpp
+++ b/db/repl/manager.cpp
@@ -43,7 +43,7 @@ namespace mongo {
return p;
}
- ReplSet::Manager::Manager(ReplSet *_rs) : task::Port("ReplSet::Manager"), rs(_rs), _primary(NOPRIMARY)
+ ReplSet::Manager::Manager(ReplSet *_rs) : task::Server("ReplSet::Manager"), rs(_rs), _primary(NOPRIMARY)
{
}
diff --git a/db/repl/replset.cpp b/db/repl/replset.cpp
index 7e4f6d1775b..4358c23ec3e 100644
--- a/db/repl/replset.cpp
+++ b/db/repl/replset.cpp
@@ -259,7 +259,7 @@ namespace mongo {
catch(std::exception& e) {
log() << "replSet caught exception in startReplSets thread: " << e.what() << rsLog;
if( theReplSet )
- theReplSet->fatal(); // concurrency: this maybe should be a message.
+ theReplSet->fatal();
}
cc().shutdown();
}
diff --git a/db/repl/replset.h b/db/repl/replset.h
index 0ea76204f4a..6d8a32852f8 100644
--- a/db/repl/replset.h
+++ b/db/repl/replset.h
@@ -34,16 +34,34 @@ namespace mongo {
extern class ReplSet *theReplSet; // null until initialized
extern Tee *rsLog;
+ /** most operations on a ReplSet object should be done while locked. */
+ class RSBase : boost::noncopyable {
+ private:
+ mutex m;
+ int _locked;
+ protected:
+ RSBase() : _locked(0) { }
+ class lock : scoped_lock {
+ RSBase& _b;
+ public:
+ lock(RSBase* b) : scoped_lock(b->m), _b(*b) { b->_locked++; }
+ ~lock() { _b._locked--; }
+ };
+ bool locked() const { return _locked; }
+ };
+
/* information about the entire repl set, such as the various servers in the set, and their state */
/* note: We currently do not free mem when the set goes away - it is assumed the replset is a
singleton and long lived.
*/
- class ReplSet {
+ class ReplSet : RSBase {
public:
- static enum StartupStatus {
+ /** info on our state if the replset isn't yet "up". for example, if we are pre-initiation. */
+ enum StartupStatus {
PRESTART=0, LOADINGCONFIG=1, BADCONFIG=2, EMPTYCONFIG=3,
EMPTYUNREACHABLE=4, STARTED=5, SOON=6
- } startupStatus;
+ };
+ static StartupStatus startupStatus;
static string startupStatusMsg;
void fatal();
@@ -134,7 +152,7 @@ namespace mongo {
List1<Member> _members; /* all members of the set EXCEPT self. */
public:
- class Manager : public task::Port {
+ class Manager : public task::Server {
bool got(const any&);
ReplSet *rs;
int _primary;
@@ -158,7 +176,11 @@ namespace mongo {
};
inline void ReplSet::fatal()
- { _myState = FATAL; log() << "replSet error fatal error, stopping replication" << rsLog; }
+ {
+ lock l(this);
+ _myState = FATAL;
+ log() << "replSet error fatal error, stopping replication" << rsLog;
+ }
inline ReplSet::Member::Member(HostAndPort h, unsigned ord, const ReplSetConfig::MemberCfg *c) :
_config(c), _h(h), _hbinfo(ord) { }
diff --git a/db/security.h b/db/security.h
index d0e0c9e1df9..dd67bf503b0 100644
--- a/db/security.h
+++ b/db/security.h
@@ -18,10 +18,6 @@
#pragma once
-#include <boost/thread/tss.hpp>
-#undef assert
-#define assert MONGO_assert
-
#include "nonce.h"
#include "concurrency.h"
diff --git a/pch.h b/pch.h
index 94303e76b91..55804e21ff0 100644
--- a/pch.h
+++ b/pch.h
@@ -27,7 +27,57 @@
# include <windows.h>
#endif
+#include <sstream>
+#include <string>
+#include <memory>
#include <string>
+#include <iostream>
+#include <fstream>
+#include <map>
+#include <vector>
+#include <set>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sstream>
+#include <signal.h>
+#include "targetver.h"
+#include "time.h"
+#include "string.h"
+#include "limits.h"
+
+#include <boost/any.hpp>
+#include <boost/archive/iterators/base64_from_binary.hpp>
+#include <boost/archive/iterators/binary_from_base64.hpp>
+#include <boost/archive/iterators/transform_width.hpp>
+#include <boost/filesystem/convenience.hpp>
+#include <boost/filesystem/operations.hpp>
+#include <boost/program_options.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/smart_ptr.hpp>
+#include "boost/bind.hpp"
+#include "boost/function.hpp"
+#include <boost/thread/tss.hpp>
+#define BOOST_SPIRIT_THREADSAFE
+#include <boost/version.hpp>
+
+#if BOOST_VERSION >= 103800
+#define BOOST_SPIRIT_USE_OLD_NAMESPACE
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_loops.hpp>
+#include <boost/spirit/include/classic_lists.hpp>
+#else
+#include <boost/spirit/core.hpp>
+#include <boost/spirit/utility/loops.hpp>
+#include <boost/spirit/utility/lists.hpp>
+#endif
+
+#include <boost/tuple/tuple.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/xtime.hpp>
+#undef assert
+#define assert MONGO_assert
namespace mongo {
@@ -77,46 +127,6 @@ namespace mongo {
} // namespace mongo
-#include <memory>
-#include <string>
-#include <iostream>
-#include <fstream>
-#include <map>
-#include <vector>
-#include <set>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sstream>
-#include <signal.h>
-
-#include "targetver.h"
-#include "time.h"
-#include "string.h"
-#include "limits.h"
-
-#include <boost/any.hpp>
-#include <boost/archive/iterators/base64_from_binary.hpp>
-#include <boost/archive/iterators/binary_from_base64.hpp>
-#include <boost/archive/iterators/transform_width.hpp>
-#include <boost/filesystem/convenience.hpp>
-#include <boost/filesystem/operations.hpp>
-#include <boost/program_options.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/smart_ptr.hpp>
-#include "boost/bind.hpp"
-#include "boost/function.hpp"
-
-#include <boost/version.hpp>
-
-#include <boost/tuple/tuple.hpp>
-#include <boost/thread/thread.hpp>
-#include <boost/thread/tss.hpp>
-#include <boost/thread/condition.hpp>
-#include <boost/thread/recursive_mutex.hpp>
-#include <boost/thread/xtime.hpp>
-#undef assert
-#define assert MONGO_assert
-
namespace mongo {
using namespace boost::filesystem;
}
diff --git a/util/concurrency/msg.h b/util/concurrency/msg.h
index b149342ebfc..3a678e9eff6 100644
--- a/util/concurrency/msg.h
+++ b/util/concurrency/msg.h
@@ -27,7 +27,7 @@ namespace mongo {
typedef boost::function<void()> lam;
- class Port : private Task {
+ class Server : private Task {
public:
/** send a message to the port */
void send(lam);
@@ -35,11 +35,11 @@ namespace mongo {
/** typical usage is: task::fork( foo.task() ); */
shared_ptr<Task> taskPtr() { return shared_ptr<Task>(static_cast<Task*>(this)); }
- Port(string name) : _name(name) { }
- virtual ~Port() { }
+ Server(string name) : _name(name) { }
+ virtual ~Server() { }
/** send message but block until function completes */
- void call(lam&);
+ void call(const lam&);
private:
virtual string name() { return _name; }
diff --git a/util/concurrency/mutex.h b/util/concurrency/mutex.h
new file mode 100644
index 00000000000..7d8337e6de6
--- /dev/null
+++ b/util/concurrency/mutex.h
@@ -0,0 +1,96 @@
+// @file mutex.h
+
+/* Copyright 2009 10gen Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <map>
+#include <set>
+
+namespace mongo {
+
+ extern bool __destroyingStatics;
+
+ // If you create a local static instance of this class, that instance will be destroyed
+ // before all global static objects are destroyed, so __destroyingStatics will be set
+ // to true before the global static variables are destroyed.
+ class StaticObserver : boost::noncopyable {
+ public:
+ ~StaticObserver() { __destroyingStatics = true; }
+ };
+
+ // On pthread systems, it is an error to destroy a mutex while held. Static global
+ // mutexes may be held upon shutdown in our implementation, and this way we avoid
+ // destroying them.
+ class mutex : boost::noncopyable {
+ public:
+ /* old boost doesn't support lock()...
+ void __lock() { _m->lock(); }
+ void __unlock() { _m->unlock(); }*/
+
+ mutex() { _m = new boost::mutex(); }
+ ~mutex() {
+ if( !__destroyingStatics ) {
+ delete _m;
+ }
+ }
+ class scoped_lock : boost::noncopyable {
+ public:
+ scoped_lock( mongo::mutex &m ) : _l( m.boost() ) {}
+ boost::mutex::scoped_lock &boost() { return _l; }
+ private:
+ boost::mutex::scoped_lock _l;
+ };
+ private:
+ boost::mutex &boost() { return *_m; }
+ boost::mutex *_m;
+ };
+
+ typedef mutex::scoped_lock scoped_lock;
+ typedef boost::recursive_mutex::scoped_lock recursive_scoped_lock;
+#if 0
+ class MutexDebugger {
+ typedef mutex * mid;
+
+ boost::thread_specific_ptr<int> foo;
+
+ boost::thread_specific_ptr< set<mid> > us;
+ map< mid, set<mid> > followers;
+ mutex x;
+ public:
+ void entering(mid m) {
+ set<mid> *preceeding = us.get();
+ if( preceeding == 0 )
+ us.reset( preceeding = new set<mid>() );
+
+ {
+ scoped_lock lk(x);
+ for( set<mid>::iterator i = preceeding->begin(); i != preceeding->end(); i++ ) {
+ followers[*i].insert(m);
+ assert( followers[m].count(*i) == 0 );
+ }
+ }
+
+ preceeding->insert(m);
+
+
+ }
+ void leaving(mid m) {
+ us.get()->erase(m);
+ }
+ };
+#endif
+}
diff --git a/util/concurrency/task.cpp b/util/concurrency/task.cpp
index 86987fe5c81..06e73b5bab1 100644
--- a/util/concurrency/task.cpp
+++ b/util/concurrency/task.cpp
@@ -17,7 +17,6 @@
*/
#include "pch.h"
-#include "boost/any.hpp"
#include "task.h"
#include "../goodies.h"
#include "../unittest.h"
@@ -77,7 +76,7 @@ namespace mongo {
#include "msg.h"
-/* class Task::Port */
+/* task::Server */
namespace mongo {
namespace task {
@@ -87,7 +86,7 @@ namespace mongo {
bool done;
boost::mutex m;
boost::condition c;
- lam *msg;
+ const lam *msg;
void f() {
(*msg)();
done = true;
@@ -95,7 +94,7 @@ namespace mongo {
}
};
- void Port::call( lam& msg ) {
+ void Server::call( const lam& msg ) {
Ret r;
r.msg = &msg;
lam f = boost::bind(&Ret::f, &r);
@@ -107,7 +106,7 @@ namespace mongo {
}
}
- void Port::send( lam msg ) {
+ void Server::send( lam msg ) {
{
boost::mutex::scoped_lock lk(m);
d.push_back(msg);
@@ -115,7 +114,7 @@ namespace mongo {
c.notify_one();
}
- void Port::doWork() {
+ void Server::doWork() {
while( 1 ) {
lam f;
{
@@ -128,7 +127,7 @@ namespace mongo {
try {
f();
} catch(std::exception& e) {
- log() << "Port::doWork() exception " << e.what() << endl;
+ log() << "Server::doWork() exception " << e.what() << endl;
}
}
}
diff --git a/util/goodies.h b/util/goodies.h
index 39ef14f8484..e0eeb186703 100644
--- a/util/goodies.h
+++ b/util/goodies.h
@@ -1,4 +1,4 @@
-// goodies.h
+// @file goodies.h
// miscellaneous junk
/* Copyright 2009 10gen Inc.
@@ -18,8 +18,8 @@
#pragma once
-#include <sstream>
#include "../bson/util/misc.h"
+#include "concurrency/mutex.h"
namespace mongo {
@@ -276,48 +276,7 @@ namespace mongo {
unsigned secs = xt.sec % 1024;
return secs*1000000 + t;
}
- using namespace boost;
-
- extern bool __destroyingStatics;
-
- // If you create a local static instance of this class, that instance will be destroyed
- // before all global static objects are destroyed, so __destroyingStatics will be set
- // to true before the global static variables are destroyed.
- class StaticObserver : boost::noncopyable {
- public:
- ~StaticObserver() { __destroyingStatics = true; }
- };
-
- // On pthread systems, it is an error to destroy a mutex while held. Static global
- // mutexes may be held upon shutdown in our implementation, and this way we avoid
- // destroying them.
- class mutex : boost::noncopyable {
- public:
- /* old boost doesn't support lock()...
- void __lock() { _m->lock(); }
- void __unlock() { _m->unlock(); }*/
-
- mutex() { _m = new boost::mutex(); }
- ~mutex() {
- if( !__destroyingStatics ) {
- delete _m;
- }
- }
- class scoped_lock : boost::noncopyable {
- public:
- scoped_lock( mongo::mutex &m ) : _l( m.boost() ) {}
- boost::mutex::scoped_lock &boost() { return _l; }
- private:
- boost::mutex::scoped_lock _l;
- };
- private:
- boost::mutex &boost() { return *_m; }
- boost::mutex *_m;
- };
- typedef mongo::mutex::scoped_lock scoped_lock;
- typedef boost::recursive_mutex::scoped_lock recursive_scoped_lock;
-
// simple scoped timer
class Timer {
public:
@@ -776,7 +735,7 @@ namespace mongo {
template<typename U> ptr(U* p) : _p(p) {}
template<typename U> ptr(const ptr<U>& p) : _p(p) {}
template<typename U> ptr(const boost::shared_ptr<U>& p) : _p(p.get()) {}
- template<typename U> ptr(const scoped_ptr<U>& p) : _p(p.get()) {}
+ template<typename U> ptr(const boost::scoped_ptr<U>& p) : _p(p.get()) {}
//template<typename U> ptr(const auto_ptr<U>& p) : _p(p.get()) {}
// assign to ptr<T>
@@ -784,7 +743,7 @@ namespace mongo {
template<typename U> ptr& operator= (U* p) { _p = p; return *this; }
template<typename U> ptr& operator= (const ptr<U>& p) { _p = p; return *this; }
template<typename U> ptr& operator= (const boost::shared_ptr<U>& p) { _p = p.get(); return *this; }
- template<typename U> ptr& operator= (const scoped_ptr<U>& p) { _p = p.get(); return *this; }
+ template<typename U> ptr& operator= (const boost::scoped_ptr<U>& p) { _p = p.get(); return *this; }
//template<typename U> ptr& operator= (const auto_ptr<U>& p) { _p = p.get(); return *this; }
// use
@@ -797,5 +756,8 @@ namespace mongo {
private:
T* _p;
};
-
+
+ /** Hmmmm */
+ using namespace boost;
+
} // namespace mongo