1// Copyright 2016 The Fuchsia Authors 2// 3// Use of this source code is governed by a MIT-style 4// license that can be found in the LICENSE file or at 5// https://opensource.org/licenses/MIT 6 7#include <object/wait_state_observer.h> 8 9#include <assert.h> 10 11#include <kernel/event.h> 12 13#include <object/handle.h> 14#include <object/dispatcher.h> 15 16#include <fbl/type_support.h> 17 18WaitStateObserver::~WaitStateObserver() { 19 DEBUG_ASSERT(!dispatcher_); 20} 21 22zx_status_t WaitStateObserver::Begin(Event* event, 23 Handle* handle, 24 zx_signals_t watched_signals) { 25 canary_.Assert(); 26 DEBUG_ASSERT(!dispatcher_); 27 28 event_ = event; 29 handle_ = handle; 30 watched_signals_ = watched_signals; 31 dispatcher_ = handle->dispatcher(); 32 wakeup_reasons_ = 0u; 33 34 auto status = dispatcher_->add_observer(this); 35 if (status != ZX_OK) { 36 dispatcher_.reset(); 37 return status; 38 } 39 return ZX_OK; 40} 41 42zx_signals_t WaitStateObserver::End() { 43 canary_.Assert(); 44 DEBUG_ASSERT(dispatcher_); 45 DEBUG_ASSERT(dispatcher_->has_state_tracker()); 46 47 dispatcher_->RemoveObserver(this); 48 dispatcher_.reset(); 49 50 // Return the set of reasons that we may have been woken. Basically, this 51 // is set of satisfied bits which were ever set while we were waiting on the list. 52 return wakeup_reasons_; 53} 54 55StateObserver::Flags WaitStateObserver::OnInitialize(zx_signals_t initial_state, 56 const StateObserver::CountInfo* cinfo) { 57 canary_.Assert(); 58 59 // Record the initial state of the state tracker as our wakeup reason. If 60 // we are going to become immediately signaled, the reason is contained 61 // somewhere in this initial state. 62 wakeup_reasons_ = initial_state; 63 64 if (initial_state & watched_signals_) { 65 event_->Signal(); 66 } 67 68 return 0; 69} 70 71StateObserver::Flags WaitStateObserver::OnStateChange(zx_signals_t new_state) { 72 canary_.Assert(); 73 74 // If we are still on our StateTracker's list of observers, and the 75 // StateTracker's state has changed, accumulate the reasons that we may have 76 // woken up. In particular any satisfied bits which have become set 77 // while we were on the list may have been reasons to wake up. 78 wakeup_reasons_ |= new_state; 79 80 if (new_state & watched_signals_) { 81 event_->Signal(); 82 } 83 84 return 0; 85} 86 87StateObserver::Flags WaitStateObserver::OnCancel(const Handle* handle) { 88 canary_.Assert(); 89 90 if (handle == handle_) { 91 wakeup_reasons_ |= ZX_SIGNAL_HANDLE_CLOSED; 92 event_->Signal(ZX_ERR_CANCELED); 93 return kHandled; 94 } else { 95 return 0; 96 } 97} 98