14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file.
44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "mojo/system/waiter_list.h"
64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/logging.h"
8f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "mojo/system/handle_signals_state.h"
94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "mojo/system/waiter.h"
104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace mojo {
124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace system {
134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)WaiterList::WaiterList() {
154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)WaiterList::~WaiterList() {
184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(waiters_.empty());
194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
21f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void WaiterList::AwakeWaitersForStateChange(const HandleSignalsState& state) {
224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (WaiterInfoList::iterator it = waiters_.begin(); it != waiters_.end();
234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)       ++it) {
24f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (state.satisfies(it->signals))
25f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      it->waiter->Awake(MOJO_RESULT_OK, it->context);
26f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    else if (!state.can_satisfy(it->signals))
27f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      it->waiter->Awake(MOJO_RESULT_FAILED_PRECONDITION, it->context);
284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WaiterList::CancelAllWaiters() {
324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (WaiterInfoList::iterator it = waiters_.begin(); it != waiters_.end();
334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)       ++it) {
34f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    it->waiter->Awake(MOJO_RESULT_CANCELLED, it->context);
354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  waiters_.clear();
374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WaiterList::AddWaiter(Waiter* waiter,
40f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                           MojoHandleSignals signals,
41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                           uint32_t context) {
42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  waiters_.push_back(WaiterInfo(waiter, signals, context));
434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WaiterList::RemoveWaiter(Waiter* waiter) {
464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // We allow a thread to wait on the same handle multiple times simultaneously,
474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // so we need to scan the entire list and remove all occurrences of |waiter|.
484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (WaiterInfoList::iterator it = waiters_.begin(); it != waiters_.end();) {
494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    WaiterInfoList::iterator maybe_delete = it;
504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ++it;
514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (maybe_delete->waiter == waiter)
524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      waiters_.erase(maybe_delete);
534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace system
574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace mojo
58