summaryrefslogtreecommitdiff
path: root/src/mongo/bson/optime.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/bson/optime.cpp')
-rw-r--r--src/mongo/bson/optime.cpp105
1 files changed, 105 insertions, 0 deletions
diff --git a/src/mongo/bson/optime.cpp b/src/mongo/bson/optime.cpp
new file mode 100644
index 00000000000..6cc01969366
--- /dev/null
+++ b/src/mongo/bson/optime.cpp
@@ -0,0 +1,105 @@
+/* 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.
+ */
+
+#include "mongo/bson/optime.h"
+
+#include <iostream>
+#include <limits>
+#include <ctime>
+
+#include "mongo/bson/inline_decls.h"
+#include "mongo/util/debug_util.h"
+#include "mongo/util/log.h"
+#include "mongo/util/startup_test.h"
+
+namespace mongo {
+
+ OpTime OpTime::last(0, 0);
+ boost::condition OpTime::notifier;
+ mongo::mutex OpTime::m("optime");
+
+ NOINLINE_DECL OpTime OpTime::skewed() {
+ bool toLog = false;
+ ONCE toLog = true;
+ RARELY toLog = true;
+ last.i++;
+ if ( last.i & 0x80000000 )
+ toLog = true;
+ if ( toLog ) {
+ log() << "clock skew detected prev: " << last.secs << " now: " << (unsigned) time(0)
+ << std::endl;
+ }
+ if ( last.i & 0x80000000 ) {
+ log() << "error large clock skew detected, shutting down" << std::endl;
+ throw ClockSkewException();
+ }
+ return last;
+ }
+
+ /*static*/ OpTime OpTime::_now() {
+ OpTime result;
+ unsigned t = (unsigned) time(0);
+ if ( last.secs == t ) {
+ last.i++;
+ result = last;
+ }
+ else if ( t < last.secs ) {
+ result = skewed(); // separate function to keep out of the hot code path
+ }
+ else {
+ last = OpTime(t, 1);
+ result = last;
+ }
+ notifier.notify_all();
+ return last;
+ }
+
+ OpTime OpTime::now(const mongo::mutex::scoped_lock&) {
+ return _now();
+ }
+
+ OpTime OpTime::getLast(const mongo::mutex::scoped_lock&) {
+ return last;
+ }
+
+ OpTime OpTime::max() {
+ unsigned int t = static_cast<unsigned int>(std::numeric_limits<int32_t>::max());
+ unsigned int i = std::numeric_limits<uint32_t>::max();
+ return OpTime(t, i);
+ }
+
+ void OpTime::waitForDifferent(unsigned millis){
+ mutex::scoped_lock lk(m);
+ while (*this == last) {
+ if (!notifier.timed_wait(lk.boost(), boost::posix_time::milliseconds(millis)))
+ return; // timed out
+ }
+ }
+
+ struct TestOpTime : public StartupTest {
+ void run() {
+ OpTime t;
+ for ( int i = 0; i < 10; i++ ) {
+ OpTime s = OpTime::_now();
+ verify( s != t );
+ t = s;
+ }
+ OpTime q = t;
+ verify( q == t );
+ verify( !(q != t) );
+ }
+ } testoptime;
+
+}