diff options
-rw-r--r-- | db/db.vcxproj | 2 | ||||
-rwxr-xr-x | db/db.vcxproj.filters | 9 | ||||
-rw-r--r-- | db/lasterror.h | 4 | ||||
-rw-r--r-- | db/repl/manager.cpp | 2 | ||||
-rw-r--r-- | db/repl/replset.cpp | 2 | ||||
-rw-r--r-- | db/repl/replset.h | 32 | ||||
-rw-r--r-- | db/security.h | 4 | ||||
-rw-r--r-- | pch.h | 90 | ||||
-rw-r--r-- | util/concurrency/msg.h | 8 | ||||
-rw-r--r-- | util/concurrency/mutex.h | 96 | ||||
-rw-r--r-- | util/concurrency/task.cpp | 13 | ||||
-rw-r--r-- | util/goodies.h | 54 |
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" @@ -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 |