Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2993)

Unified Diff: base/queue_timer.cc

Issue 624713003: Keep only base/extractor.[cc|h]. (Closed) Base URL: https://chromium.googlesource.com/external/omaha.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/queue_timer.h ('k') | base/queue_timer_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/queue_timer.cc
diff --git a/base/queue_timer.cc b/base/queue_timer.cc
deleted file mode 100644
index 255fd2b00d8b9b09da80319a6788caa3588cb3e2..0000000000000000000000000000000000000000
--- a/base/queue_timer.cc
+++ /dev/null
@@ -1,185 +0,0 @@
-// Copyright 2007-2009 Google 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.
-// ========================================================================
-//
-// The implementation is straightforward except the destruction of the
-// QueueTimer which needs some clarification.
-// If there is no callback running, then the destructor gets the critical
-// section and then it blocks on the DeleteTimerQueueTimer call, waiting for
-// the kernel to clean up the timer handle. The callback never fires in this
-// case.
-// If a callback is running, then there are two possibilities:
-// 1. The callback gets the critical section. The callback runs as usual and
-// then the destructor gets the critical section. This is also easy.
-// 2. The destructor gets the critical section. In this case, the callback
-// tries the critical section then it returns right away.
-//
-// Alarm timers are started and restarted every time they fire. The usage
-// patterns for alarms is usually Start, Callback, Start, Callback, etc...
-// The cleanup of an alarm timer handle usually happens in the callback, unless
-// the destructor of the QueueTimer is called, in which case the logic
-// above applies.
-//
-// Periodic timers are only started once: Start, Callback, Callback, etc...
-// In this case, the destructor does all the necessary cleanup.
-// Periodic timers must fire at intervals that are reasonable long so that
-// the callbacks do not queue up.
-
-#include "omaha/base/queue_timer.h"
-
-#include "omaha/base/debug.h"
-#include "omaha/base/error.h"
-#include "omaha/base/logging.h"
-
-namespace omaha {
-
-QueueTimer::QueueTimer(HANDLE timer_queue, Callback callback, void* ctx)
- : callback_tid_(0),
- ctx_(ctx),
- due_time_(0),
- period_(0),
- flags_(0),
- timer_handle_(NULL),
- timer_queue_(timer_queue),
- callback_(callback) {
- UTIL_LOG(L3, (_T("[QueueTimer::QueueTimer][0x%p]"), this));
- ASSERT1(timer_queue);
- ASSERT1(callback);
- ::InitializeCriticalSection(&dtor_cs_);
- ::InitializeCriticalSection(&cs_);
-}
-
-// The destructor blocks on waiting for the timer kernel object to be deleted.
-// We can't call the destructor of QueueTimer while we are handling a callback.
-// This will result is a deadlock.
-QueueTimer::~QueueTimer() {
- UTIL_LOG(L3, (_T("[QueueTimer::~QueueTimer][0x%p]"), this));
-
- ::EnterCriticalSection(&dtor_cs_);
- if (timer_handle_) {
- ASSERT1(callback_tid_ != ::GetCurrentThreadId());
-
- // This is a blocking call waiting for all callbacks to clear up.
- bool res = !!::DeleteTimerQueueTimer(timer_queue_,
- timer_handle_,
- INVALID_HANDLE_VALUE);
- ASSERT1(res);
- timer_handle_ = NULL;
- }
- callback_ = NULL;
- timer_queue_ = NULL;
- flags_ = 0;
- period_ = 0;
- due_time_ = 0;
- ctx_ = 0;
- callback_tid_ = 0;
- ::LeaveCriticalSection(&dtor_cs_);
-
- ::DeleteCriticalSection(&cs_);
- ::DeleteCriticalSection(&dtor_cs_);
-}
-
-// Thread safe.
-HRESULT QueueTimer::Start(int due_time, int period, uint32 flags) {
- // Since Start creates the timer there could be a race condition where
- // the timer could fire while we are still executing Start. We protect
- // the start with a critical section so the Start completes before the
- // timer can be entered by the callback.
-
- ::EnterCriticalSection(&cs_);
- HRESULT hr = DoStart(due_time, period, flags);
- ::LeaveCriticalSection(&cs_);
- return hr;
-}
-
-// Thread-safe.
-void QueueTimer::TimerCallback(void* param, BOOLEAN timer_or_wait) {
- ASSERT1(param);
- VERIFY1(timer_or_wait);
-
- QueueTimer* timer = static_cast<QueueTimer*>(param);
-
- if (!::TryEnterCriticalSection(&timer->dtor_cs_)) {
- return;
- }
-
- ::EnterCriticalSection(&timer->cs_);
- timer->DoCallback();
- ::LeaveCriticalSection(&timer->cs_);
-
- ::LeaveCriticalSection(&timer->dtor_cs_);
-}
-
-
-HRESULT QueueTimer::DoStart(int due_time, int period, uint32 flags) {
- UTIL_LOG(L2, (_T("[QueueTimer::DoStart][0x%p][%d][%d][0x%08u]"),
- this, due_time, period, flags));
- due_time_ = due_time;
- period_ = period;
- flags_ = flags;
-
- // Application Verifier says period must be 0 for WT_EXECUTEONLYONCE timers.
- if ((flags & WT_EXECUTEONLYONCE) && period != 0) {
- return E_INVALIDARG;
- }
-
- // Periodic timers can't be started more than one time.
- if (timer_handle_) {
- return E_UNEXPECTED;
- }
-
- bool res = !!::CreateTimerQueueTimer(&timer_handle_,
- timer_queue_,
- &QueueTimer::TimerCallback,
- this,
- due_time,
- period,
- flags_);
- if (!res) {
- HRESULT hr = HRESULTFromLastError();
- UTIL_LOG(LE, (_T("[QueueTimer::Start failed][0x%p][0x%08x]"), this, hr));
- return hr;
- }
-
- ASSERT1(timer_handle_);
- UTIL_LOG(L3, (_T("[QueueTimer::Start timer created][0x%p]"), this));
- return S_OK;
-}
-
-void QueueTimer::DoCallback() {
- UTIL_LOG(L2, (_T("[QueueTimer::OnCallback][0x%p]"), this));
-
- ASSERT1(timer_queue_);
- ASSERT1(timer_handle_);
- ASSERT1(callback_);
-
- if (!period_) {
- // Non-periodic aka alarm timers fire only once. We delete the timer
- // handle so that the timer object can be restarted later on.
- // The call below is non-blocking. The deletion of the kernel object can
- // succeed right away, for example if the timer runs in the timer thread
- // itself. Otherwise, if the last error is ERROR_IO_PENDING the kernel
- // cleans up the object once the callback returns.
- bool res = !!::DeleteTimerQueueTimer(timer_queue_, timer_handle_, NULL);
- ASSERT1(res || (!res && ::GetLastError() == ERROR_IO_PENDING));
- timer_handle_ = NULL;
- }
-
- callback_tid_ = ::GetCurrentThreadId();
- callback_(this);
- callback_tid_ = 0;
-}
-
-} // namespace omaha
-
« no previous file with comments | « base/queue_timer.h ('k') | base/queue_timer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698