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