summaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
Diffstat (limited to 'util')
-rw-r--r--util/assert_util.cpp1
-rw-r--r--util/concurrency/spin_lock.h10
-rw-r--r--util/concurrency/value.h35
-rw-r--r--util/concurrency/vars.cpp2
-rw-r--r--util/message.cpp45
-rw-r--r--util/ramlog.h3
-rw-r--r--util/sock.h4
-rw-r--r--util/version.cpp42
8 files changed, 97 insertions, 45 deletions
diff --git a/util/assert_util.cpp b/util/assert_util.cpp
index 47be5e9..8280d8b 100644
--- a/util/assert_util.cpp
+++ b/util/assert_util.cpp
@@ -91,6 +91,7 @@ namespace mongo {
void uasserted(int msgid, const char *msg) {
assertionCount.condrollover( ++assertionCount.user );
+ LOG(1) << "User Assertion: " << msgid << ":" << msg << endl;
raiseError(msgid,msg);
throw UserException(msgid, msg);
}
diff --git a/util/concurrency/spin_lock.h b/util/concurrency/spin_lock.h
index d5360f7..02a8797 100644
--- a/util/concurrency/spin_lock.h
+++ b/util/concurrency/spin_lock.h
@@ -49,6 +49,16 @@ namespace mongo {
SpinLock(SpinLock&);
SpinLock& operator=(SpinLock&);
};
+
+ struct scoped_spinlock {
+ scoped_spinlock( SpinLock& l ) : _l(l){
+ _l.lock();
+ }
+ ~scoped_spinlock() {
+ _l.unlock();
+ }
+ SpinLock& _l;
+ };
} // namespace mongo
diff --git a/util/concurrency/value.h b/util/concurrency/value.h
index 08d5306..0a0ef85 100644
--- a/util/concurrency/value.h
+++ b/util/concurrency/value.h
@@ -60,28 +60,31 @@ namespace mongo {
};
};
- /** this string COULD be mangled but with the double buffering, assuming writes
- are infrequent, it's unlikely. thus, this is reasonable for lockless setting of
- diagnostic strings, where their content isn't critical.
- */
class DiagStr {
- char buf1[256];
- char buf2[256];
- char *p;
+ string _s;
+ static mutex m;
public:
- DiagStr() {
- memset(buf1, 0, 256);
- memset(buf2, 0, 256);
- p = buf1;
+ DiagStr(const DiagStr& r) : _s(r.get()) { }
+ DiagStr() { }
+ bool empty() const {
+ mutex::scoped_lock lk(m);
+ return _s.empty();
+ }
+ string get() const {
+ mutex::scoped_lock lk(m);
+ return _s;
}
-
- const char * get() const { return p; }
void set(const char *s) {
- char *q = (p==buf1) ? buf2 : buf1;
- strncpy(q, s, 255);
- p = q;
+ mutex::scoped_lock lk(m);
+ _s = s;
+ }
+ void set(const string& s) {
+ mutex::scoped_lock lk(m);
+ _s = s;
}
+ operator string() const { return get(); }
+ void operator=(const string& s) { set(s); }
};
}
diff --git a/util/concurrency/vars.cpp b/util/concurrency/vars.cpp
index 3d057a4..19b58eb 100644
--- a/util/concurrency/vars.cpp
+++ b/util/concurrency/vars.cpp
@@ -22,6 +22,8 @@
namespace mongo {
+ mutex DiagStr::m("diags");
+
mongo::mutex _atomicMutex("_atomicMutex");
// intentional leak. otherwise destructor orders can be problematic at termination.
diff --git a/util/message.cpp b/util/message.cpp
index 916aa34..bcb1772 100644
--- a/util/message.cpp
+++ b/util/message.cpp
@@ -359,7 +359,7 @@ namespace mongo {
ConnectBG(int sock, SockAddr farEnd) : _sock(sock), _farEnd(farEnd) { }
void run() { _res = ::connect(_sock, _farEnd.raw(), _farEnd.addressSize); }
- string name() const { return ""; /* too short lived to need to name */ }
+ string name() const { return "ConnectBG"; }
int inError() const { return _res; }
private:
@@ -628,12 +628,20 @@ again:
unsigned retries = 0;
while( len > 0 ) {
int ret = ::recv( sock , buf , len , portRecvFlags );
- if ( ret == 0 ) {
+ if ( ret > 0 ) {
+ if ( len <= 4 && ret != len )
+ log(_logLevel) << "MessagingPort recv() got " << ret << " bytes wanted len=" << len << endl;
+ assert( ret <= len );
+ len -= ret;
+ buf += ret;
+ }
+ else if ( ret == 0 ) {
log(3) << "MessagingPort recv() conn closed? " << farEnd.toString() << endl;
throw SocketException( SocketException::CLOSED );
}
- if ( ret < 0 ) {
+ else { /* ret < 0 */
int e = errno;
+
#if defined(EINTR) && !defined(_WIN32)
if( e == EINTR ) {
if( ++retries == 1 ) {
@@ -642,29 +650,18 @@ again:
}
}
#endif
- if ( e != EAGAIN || _timeout == 0 ) {
- SocketException::Type t = SocketException::RECV_ERROR;
-#if defined(_WINDOWS)
- if( e == WSAETIMEDOUT ) t = SocketException::RECV_TIMEOUT;
-#else
- /* todo: what is the error code on an SO_RCVTIMEO on linux? EGAIN? EWOULDBLOCK? */
+ if ( ( e == EAGAIN
+#ifdef _WINDOWS
+ || e == WSAETIMEDOUT
#endif
- log(_logLevel) << "MessagingPort recv() " << errnoWithDescription(e) << " " << farEnd.toString() <<endl;
- throw SocketException(t);
- }
- else {
- if ( !serverAlive( farEnd.toString() ) ) {
- log(_logLevel) << "MessagingPort recv() remote dead " << farEnd.toString() << endl;
- throw SocketException( SocketException::RECV_ERROR );
- }
+ ) && _timeout > 0 ) {
+ // this is a timeout
+ log(_logLevel) << "MessagingPort recv() timeout " << farEnd.toString() <<endl;
+ throw SocketException(SocketException::RECV_TIMEOUT);
}
- }
- else {
- if ( len <= 4 && ret != len )
- log(_logLevel) << "MessagingPort recv() got " << ret << " bytes wanted len=" << len << endl;
- assert( ret <= len );
- len -= ret;
- buf += ret;
+
+ log(_logLevel) << "MessagingPort recv() " << errnoWithDescription(e) << " " << farEnd.toString() <<endl;
+ throw SocketException(SocketException::RECV_ERROR);
}
}
}
diff --git a/util/ramlog.h b/util/ramlog.h
index fc588e6..b2f3aa0 100644
--- a/util/ramlog.h
+++ b/util/ramlog.h
@@ -108,7 +108,6 @@ namespace mongo {
vector<const char*> v;
get( v );
- bool first = true;
s << "<pre>\n";
for( int i = 0; i < (int)v.size(); i++ ) {
assert( strlen(v[i]) > 20 );
@@ -126,7 +125,7 @@ namespace mongo {
stringstream r;
if( nr == 1 ) r << "repeat last line";
else r << "repeats last " << nr << " lines; ends " << string(v[last]+4,0,15);
- first = false; s << html::a("", r.str(), clean(v,i,x.str()));
+ s << html::a("", r.str(), clean(v,i,x.str()));
}
else s << x.str();
s << '\n';
diff --git a/util/sock.h b/util/sock.h
index 84690fe..54dfb49 100644
--- a/util/sock.h
+++ b/util/sock.h
@@ -199,7 +199,7 @@ namespace mongo {
case AF_INET6: return memcmp(as<sockaddr_in6>().sin6_addr.s6_addr, r.as<sockaddr_in6>().sin6_addr.s6_addr, sizeof(in6_addr)) == 0;
case AF_UNIX: return strcmp(as<sockaddr_un>().sun_path, r.as<sockaddr_un>().sun_path) == 0;
case AF_UNSPEC: return true; // assume all unspecified addresses are the same
- default: massert(SOCK_FAMILY_UNKNOWN_ERROR, "unsupported address family", false);
+ default: massert(SOCK_FAMILY_UNKNOWN_ERROR, "unsupported address family", false); return false;
}
}
bool operator!=(const SockAddr& r) const {
@@ -221,7 +221,7 @@ namespace mongo {
case AF_INET6: return memcmp(as<sockaddr_in6>().sin6_addr.s6_addr, r.as<sockaddr_in6>().sin6_addr.s6_addr, sizeof(in6_addr)) < 0;
case AF_UNIX: return strcmp(as<sockaddr_un>().sun_path, r.as<sockaddr_un>().sun_path) < 0;
case AF_UNSPEC: return false;
- default: massert(SOCK_FAMILY_UNKNOWN_ERROR, "unsupported address family", false);
+ default: massert(SOCK_FAMILY_UNKNOWN_ERROR, "unsupported address family", false); return false;
}
}
diff --git a/util/version.cpp b/util/version.cpp
index f57e256..78a31be 100644
--- a/util/version.cpp
+++ b/util/version.cpp
@@ -23,10 +23,11 @@
#include <string>
#include "unittest.h"
#include "version.h"
+#include "file.h"
namespace mongo {
- const char versionString[] = "1.8.1";
+ const char versionString[] = "1.8.2";
string mongodVersion() {
stringstream ss;
@@ -94,6 +95,45 @@ namespace mongo {
cout << "** WARNING: You are running in OpenVZ. This is known to be broken!!!" << endl;
warned = true;
}
+
+ if (boost::filesystem::exists("/sys/devices/system/node/node1")){
+ // We are on a box with a NUMA enabled kernel and more than 1 numa node (they start at node0)
+ // Now we look at the first line of /proc/self/numa_maps
+ //
+ // Bad example:
+ // $ cat /proc/self/numa_maps
+ // 00400000 default file=/bin/cat mapped=6 N4=6
+ //
+ // Good example:
+ // $ numactl --interleave=all cat /proc/self/numa_maps
+ // 00400000 interleave:0-7 file=/bin/cat mapped=6 N4=6
+
+ File f;
+ f.open("/proc/self/numa_maps", /*read_only*/true);
+ if ( f.is_open() && ! f.bad() ) {
+ char line[100]; //we only need the first line
+ f.read(0, line, sizeof(line));
+
+ // just in case...
+ line[98] = ' ';
+ line[99] = '\0';
+
+ // skip over pointer
+ const char* space = strchr(line, ' ');
+
+ if ( ! space ) {
+ cout << "** WARNING: cannot parse numa_maps" << endl;
+ warned = true;
+ }
+ else if ( ! startsWith(space+1, "interleave") ) {
+ cout << endl;
+ cout << "** WARNING: You are running on a NUMA machine." << endl;
+ cout << "** We suggest launching mongod like this to avoid performance problems:" << endl;
+ cout << "** numactl --interleave=all mongod [other options]" << endl;
+ warned = true;
+ }
+ }
+ }
#endif
if (warned)