diff --git a/db/jsobj.cpp b/db/jsobj.cpp index e1cbb55fbe4..17cdf4db533 100644 --- a/db/jsobj.cpp +++ b/db/jsobj.cpp @@ -1430,7 +1430,7 @@ namespace mongo { } void OID::init() { - static unsigned inc = (unsigned) security.getNonce(); + static WrappingInt inc = (unsigned) security.getNonce(); unsigned t = (unsigned) time(0); char *T = (char *) &t; data[0] = T[3]; @@ -1440,9 +1440,8 @@ namespace mongo { (unsigned&) data[4] = _machine; - // TODO: use compiler intrinsic atomic increment instead of inc++ - int old_inc = inc++; - T = (char *) &old_inc; + int new_inc = inc.atomicIncrement(); + T = (char *) &new_inc; char * raw = (char*)&b; raw[0] = T[3]; raw[1] = T[2]; diff --git a/util/goodies.h b/util/goodies.h index 23a214b2a60..eb0631061a6 100644 --- a/util/goodies.h +++ b/util/goodies.h @@ -19,6 +19,10 @@ #pragma once +#if defined(__MSCV__) +# include +#endif + namespace mongo { #if !defined(_WIN32) && !defined(NOEXECINFO) @@ -112,14 +116,22 @@ namespace mongo { x = 0; } WrappingInt(unsigned z) : x(z) { } - unsigned x; + volatile unsigned x; operator unsigned() const { return x; } - WrappingInt& operator++() { - x++; - return *this; + + WrappingInt atomicIncrement(){ +#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) + return __sync_add_and_fetch(&x, 1); +#elif defined(__MSCV__) + return InterlockedIncrement((long*)&x); //long is 32bits in Win64 +#else +# warning "OID and MSGID generation will not be thread safe" + return ++inc; +#endif } + static int diff(unsigned a, unsigned b) { return a-b; } diff --git a/util/message.cpp b/util/message.cpp index a483df42569..cfb03a53168 100644 --- a/util/message.cpp +++ b/util/message.cpp @@ -429,8 +429,7 @@ again: } msgstart; MSGID nextMessageId(){ - MSGID msgid = NextMsgId; - ++NextMsgId; + MSGID msgid = NextMsgId.atomicIncrement(); if ( usingClientIds ){ msgid = msgid & 0xFFFF;