| Index: base/reactor.cc
|
| diff --git a/base/reactor.cc b/base/reactor.cc
|
| deleted file mode 100644
|
| index 1a02aa3a5340be445c872108bded437746179e97..0000000000000000000000000000000000000000
|
| --- a/base/reactor.cc
|
| +++ /dev/null
|
| @@ -1,205 +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.
|
| -// ========================================================================
|
| -
|
| -
|
| -#include "omaha/base/reactor.h"
|
| -
|
| -#include <vector>
|
| -#include "base/scoped_ptr.h"
|
| -#include "omaha/base/debug.h"
|
| -#include "omaha/base/error.h"
|
| -#include "omaha/base/logging.h"
|
| -#include "omaha/base/event_handler.h"
|
| -
|
| -namespace omaha {
|
| -
|
| -Reactor::Reactor() {
|
| - CORE_LOG(L4, (_T("[Reactor::Reactor]")));
|
| - ::InitializeCriticalSection(&cs_);
|
| -}
|
| -
|
| -Reactor::~Reactor() {
|
| - CORE_LOG(L4, (_T("[Reactor::~Reactor]")));
|
| -
|
| - // Each handle must be unregistered before destroying the reactor.
|
| - ASSERT1(handlers_.empty());
|
| - ::DeleteCriticalSection(&cs_);
|
| -}
|
| -
|
| -// The reactor loop is just an efficient wait, as the demultiplexing of the
|
| -// events is actually done by the OS thread pool.
|
| -// TODO(omaha): replace the alertable wait with waiting on an event and provide
|
| -// a method for the reactor to stop handling events.
|
| -HRESULT Reactor::HandleEvents() {
|
| - CORE_LOG(L1, (_T("[Reactor::HandleEvents]")));
|
| - VERIFY1(::SleepEx(INFINITE, true) == WAIT_IO_COMPLETION);
|
| - CORE_LOG(L1, (_T("[Reactor::HandleEvents exit]")));
|
| - return S_OK;
|
| -}
|
| -
|
| -void __stdcall Reactor::Callback(void* param, BOOLEAN timer_or_wait) {
|
| - ASSERT1(param);
|
| -
|
| - // Since we wait an INFINITE the wait handle is always signaled.
|
| - VERIFY1(!timer_or_wait);
|
| - RegistrationState* state = static_cast<RegistrationState*>(param);
|
| - ASSERT1(state->reactor);
|
| - state->reactor->DoCallback(state);
|
| -}
|
| -
|
| -// Method does not check to see if the same handle is registered twice.
|
| -HRESULT Reactor::RegisterHandle(HANDLE handle,
|
| - EventHandler* event_handler,
|
| - uint32 flags) {
|
| - ASSERT1(handle);
|
| - ASSERT1(event_handler);
|
| -
|
| - if (!handle || !event_handler) {
|
| - return E_INVALIDARG;
|
| - }
|
| -
|
| - scoped_ptr<RegistrationState> state(new RegistrationState);
|
| - state->event_handler = event_handler;
|
| - state->handle = handle;
|
| - state->reactor = this;
|
| - state->flags = flags | WT_EXECUTEONLYONCE;
|
| -
|
| - // The reactor only calls the handler once.
|
| - ASSERT1(WT_EXECUTEDEFAULT == 0);
|
| -
|
| - // As soon as the handle is registered, the thread pool can queue up a
|
| - // callback and reenter the reactor on a different thread.
|
| - // Acquire the critical section before registering the handle.
|
| - ::EnterCriticalSection(&cs_);
|
| -#if DEBUG
|
| - // The same handle should not be registered multiple times.
|
| - std::vector<RegistrationState*>::iterator it = handlers_.begin();
|
| - for (; it != handlers_.end(); ++it) {
|
| - ASSERT((*it)->handle != handle, (_T("[already registered %d]"), handle));
|
| - }
|
| -#endif
|
| - bool res = !!::RegisterWaitForSingleObject(&state->wait_handle,
|
| - state->handle,
|
| - &Reactor::Callback,
|
| - state.get(),
|
| - INFINITE,
|
| - state->flags);
|
| - HRESULT hr = res ? S_OK : HRESULTFromLastError();
|
| - if (SUCCEEDED(hr)) {
|
| - handlers_.push_back(state.release());
|
| - }
|
| - ::LeaveCriticalSection(&cs_);
|
| -
|
| - return hr;
|
| -}
|
| -
|
| -HRESULT Reactor::RegisterHandle(HANDLE handle) {
|
| - ::EnterCriticalSection(&cs_);
|
| - HRESULT hr = DoRegisterHandle(handle);
|
| - ::LeaveCriticalSection(&cs_);
|
| - return hr;
|
| -}
|
| -
|
| -HRESULT Reactor::DoRegisterHandle(HANDLE handle) {
|
| - ASSERT1(handle);
|
| - std::vector<RegistrationState*>::iterator it = handlers_.begin();
|
| - for (; it != handlers_.end(); ++it) {
|
| - if ((*it)->handle == handle) {
|
| - break;
|
| - }
|
| - }
|
| - if (it == handlers_.end()) {
|
| - // The handle is not registered with the reactor anymore. Registering the
|
| - // the handle again is not possible.
|
| - return E_FAIL;
|
| - }
|
| -
|
| - // Unregister and register the handle again. Unregistering is an non blocking
|
| - // call.
|
| - RegistrationState* state = *it;
|
| - bool res = !!::UnregisterWaitEx(state->wait_handle, NULL);
|
| - if (!res && ::GetLastError() != ERROR_IO_PENDING) {
|
| - return HRESULTFromLastError();
|
| - }
|
| - if (!::RegisterWaitForSingleObject(&state->wait_handle,
|
| - state->handle,
|
| - &Reactor::Callback,
|
| - state,
|
| - INFINITE,
|
| - state->flags)) {
|
| - return HRESULTFromLastError();
|
| - }
|
| - return S_OK;
|
| -}
|
| -
|
| -HRESULT Reactor::UnregisterHandle(HANDLE handle) {
|
| - ASSERT1(handle);
|
| - if (!handle) {
|
| - return E_INVALIDARG;
|
| - }
|
| -
|
| - // Attempts to take the ownership of the registration state for the handle.
|
| - // If taking the ownership does not succeed, it means the handle has already
|
| - // been unregistered.
|
| - scoped_ptr<RegistrationState> state(ReleaseHandlerState(handle));
|
| - if (!state.get()) {
|
| - return E_UNEXPECTED;
|
| - }
|
| -
|
| - // Unregisters the wait handle from the thread pool. The call blocks waiting
|
| - // for any pending callbacks to finish. No lock is being held while waiting
|
| - // here. If there is no callback pending, the call will succeed right away.
|
| - // Otherwise, if a callback has already started, the call waits for the
|
| - // callback to complete.
|
| - bool res = !!::UnregisterWaitEx(state->wait_handle, INVALID_HANDLE_VALUE);
|
| -
|
| - // Clear the registration state, as a defensive programming measure and
|
| - // for debugging purposes.
|
| - state->reactor = NULL;
|
| - state->handle = NULL;
|
| - state->wait_handle = NULL;
|
| - state->event_handler = NULL;
|
| -
|
| - return res ? S_OK : HRESULTFromLastError();
|
| -}
|
| -
|
| -void Reactor::DoCallback(RegistrationState* state) {
|
| - ASSERT1(state);
|
| - ASSERT1(state->event_handler);
|
| - ASSERT1(state->handle);
|
| - state->event_handler->HandleEvent(state->handle);
|
| -}
|
| -
|
| -// Looks up the registration state for a handle and releases the ownership
|
| -// of it to the caller. As the clean up of the state can happen from multiple
|
| -// places, the transfer of ownership ensures the clean up happens once and
|
| -// only once.
|
| -Reactor::RegistrationState* Reactor::ReleaseHandlerState(HANDLE handle) {
|
| - RegistrationState* registration_state = NULL;
|
| - ::EnterCriticalSection(&cs_);
|
| - std::vector<RegistrationState*>::iterator it = handlers_.begin();
|
| - for (; it != handlers_.end(); ++it) {
|
| - if ((*it)->handle == handle) {
|
| - registration_state = *it;
|
| - handlers_.erase(it);
|
| - break;
|
| - }
|
| - }
|
| - ::LeaveCriticalSection(&cs_);
|
| - return registration_state;
|
| -}
|
| -
|
| -} // namespace omaha
|
| -
|
|
|