// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/win/object_watcher.h"

#include "base/bind.h"
#include "base/logging.h"
#include "base/threading/sequenced_task_runner_handle.h"

#include <windows.h>

namespace base {
namespace win {

//-----------------------------------------------------------------------------

ObjectWatcher::ObjectWatcher() : weak_factory_(this) {}

ObjectWatcher::~ObjectWatcher() {
  StopWatching();
}

bool ObjectWatcher::StartWatchingOnce(HANDLE object, Delegate* delegate) {
  return StartWatchingInternal(object, delegate, true);
}

bool ObjectWatcher::StartWatchingMultipleTimes(HANDLE object,
                                               Delegate* delegate) {
  return StartWatchingInternal(object, delegate, false);
}

bool ObjectWatcher::StopWatching() {
  if (!wait_object_)
    return false;

  // Make sure ObjectWatcher is used in a sequenced fashion.
  DCHECK(task_runner_->RunsTasksInCurrentSequence());

  // Blocking call to cancel the wait. Any callbacks already in progress will
  // finish before we return from this call.
  if (!UnregisterWaitEx(wait_object_, INVALID_HANDLE_VALUE)) {
    DPLOG(FATAL) << "UnregisterWaitEx failed";
    return false;
  }

  Reset();
  return true;
}

bool ObjectWatcher::IsWatching() const {
  return object_ != nullptr;
}

HANDLE ObjectWatcher::GetWatchedObject() const {
  return object_;
}

// static
void CALLBACK ObjectWatcher::DoneWaiting(void* param, BOOLEAN timed_out) {
  DCHECK(!timed_out);

  // The destructor blocks on any callbacks that are in flight, so we know that
  // that is always a pointer to a valid ObjectWater.
  ObjectWatcher* that = static_cast<ObjectWatcher*>(param);
  that->task_runner_->PostTask(FROM_HERE, that->callback_);
  if (that->run_once_)
    that->callback_.Reset();
}

bool ObjectWatcher::StartWatchingInternal(HANDLE object, Delegate* delegate,
                                          bool execute_only_once) {
  DCHECK(delegate);
  DCHECK(!wait_object_) << "Already watching an object";
  DCHECK(SequencedTaskRunnerHandle::IsSet());

  task_runner_ = SequencedTaskRunnerHandle::Get();

  run_once_ = execute_only_once;

  // Since our job is to just notice when an object is signaled and report the
  // result back to this sequence, we can just run on a Windows wait thread.
  DWORD wait_flags = WT_EXECUTEINWAITTHREAD;
  if (run_once_)
    wait_flags |= WT_EXECUTEONLYONCE;

  // DoneWaiting can be synchronously called from RegisterWaitForSingleObject,
  // so set up all state now.
  callback_ =
      Bind(&ObjectWatcher::Signal, weak_factory_.GetWeakPtr(), delegate);
  object_ = object;

  if (!RegisterWaitForSingleObject(&wait_object_, object, DoneWaiting,
                                   this, INFINITE, wait_flags)) {
    DPLOG(FATAL) << "RegisterWaitForSingleObject failed";
    Reset();
    return false;
  }

  return true;
}

void ObjectWatcher::Signal(Delegate* delegate) {
  // Signaling the delegate may result in our destruction or a nested call to
  // StartWatching(). As a result, we save any state we need and clear previous
  // watcher state before signaling the delegate.
  HANDLE object = object_;
  if (run_once_)
    StopWatching();
  delegate->OnObjectSignaled(object);
}

void ObjectWatcher::Reset() {
  callback_.Reset();
  object_ = nullptr;
  wait_object_ = nullptr;
  task_runner_ = nullptr;
  run_once_ = true;
  weak_factory_.InvalidateWeakPtrs();
}

}  // namespace win
}  // namespace base
