[Groonga-commit] groonga/grnxx [master] Implement grnxx::InternalClock.

Back to archive index

susumu.yata null+****@clear*****
Fri Mar 1 13:50:09 JST 2013


susumu.yata	2013-03-01 13:50:09 +0900 (Fri, 01 Mar 2013)

  New Revision: 61267bc654a721cf37fe6a8e7ba09a923199c96d
  https://github.com/groonga/grnxx/commit/61267bc654a721cf37fe6a8e7ba09a923199c96d

  Log:
    Implement grnxx::InternalClock.

  Added files:
    lib/internal_clock.cpp
  Modified files:
    lib/Makefile.am
    lib/internal_clock.hpp

  Modified: lib/Makefile.am (+1 -0)
===================================================================
--- lib/Makefile.am    2013-03-01 11:50:40 +0900 (106394c)
+++ lib/Makefile.am    2013-03-01 13:50:09 +0900 (9ef39b8)
@@ -16,6 +16,7 @@ libgrnxx_la_SOURCES =		\
 	duration.cpp		\
 	error.cpp		\
 	grnxx.cpp		\
+	internal_clock.cpp	\
 	logger.cpp		\
 	map.cpp			\
 	mutex.cpp		\

  Added: lib/internal_clock.cpp (+91 -0) 100644
===================================================================
--- /dev/null
+++ lib/internal_clock.cpp    2013-03-01 13:50:09 +0900 (37bddae)
@@ -0,0 +1,91 @@
+/*
+  Copyright (C) 2013  Brazil, Inc.
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+#include "internal_clock.hpp"
+
+#include <pthread.h>
+
+#include <thread>
+
+#include "error.hpp"
+#include "lock.hpp"
+#include "logger.hpp"
+#include "thread.hpp"
+#include "system_clock.hpp"
+
+namespace grnxx {
+namespace {
+
+// Accuracy of the internal clock. Note that a short sleep may lead to a
+// busy-wait loop, which exhausts CPU resources.
+constexpr Duration UPDATE_INTERVAL = Duration::milliseconds(100);
+
+Time *internal_time = nullptr;
+
+// Update the internal clock periodically.
+void internal_clock_routine() {
+  // TODO: Fix this endless loop.
+  while (true) {
+    Thread::sleep(UPDATE_INTERVAL);
+    *internal_time = SystemClock::now();
+  }
+}
+
+// Start a thread to update the internal clock.
+void start_internal_clock() {
+  try {
+    std::thread thread(internal_clock_routine);
+    thread.detach();
+  } catch (...) {
+    // Failed to start thread.
+    *internal_time = Time::min();
+    return;
+  }
+
+  // Start a new thread, if fork() is invoked, on the child process.
+  int error = ::pthread_atfork(nullptr, nullptr, start_internal_clock);
+  if (error != 0) {
+    // TODO: Error handling.
+    GRNXX_WARNING() << "failed to set a fork handler: '::pthread_atfork' "
+                    << Error(error);
+    // The current process works well even if this failed.
+  }
+
+  *internal_time = SystemClock::now();
+}
+
+}  // namespace
+
+Time InternalClock::now_ = Time::min();
+
+Time InternalClock::start() {
+  if (!internal_time) {
+    static Mutex mutex(MUTEX_UNLOCKED);
+    Lock lock(&mutex);
+    if (!internal_time) {
+      internal_time = &now_;
+      start_internal_clock();
+      if (now_ != Time::min()) {
+        return now_;
+      }
+    }
+  }
+  // Use the system clock if the internal clock is not available.
+  return SystemClock::now();
+}
+
+}  // namespace grnxx

  Modified: lib/internal_clock.hpp (+11 -2)
===================================================================
--- lib/internal_clock.hpp    2013-03-01 11:50:40 +0900 (bdb3b72)
+++ lib/internal_clock.hpp    2013-03-01 13:50:09 +0900 (9e5d6a9)
@@ -25,8 +25,17 @@ namespace grnxx {
 
 class InternalClock {
  public:
-  // TODO
-  static Time now();
+  static Time now() {
+    if (now_ == Time::min()) {
+      return start();
+    }
+    return now_;
+  }
+
+ private:
+  static Time now_;
+
+  static Time start();
 };
 
 }  // namespace grnxx
-------------- next part --------------
HTML����������������������������...
Download 



More information about the Groonga-commit mailing list
Back to archive index