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#pragma once 8 9#include <zircon/types.h> 10 11#include <fbl/canary.h> 12#include <fbl/intrusive_double_list.h> 13 14class Handle; 15 16// Observer base class for state maintained by StateTracker. 17class StateObserver { 18public: 19 // Optional initial counts. Each object might have a different idea of them 20 // and currently we assume at most two. The state observers will iterate on 21 // the entries and might fire if |signal| matches one of their trigger signals 22 // so each entry should be associated with a unique signal or with 0 if not 23 // applicable. 24 struct CountInfo { 25 struct { 26 uint64_t count; 27 zx_signals_t signal; 28 } entry[2]; 29 }; 30 31 StateObserver() { } 32 33 typedef unsigned Flags; 34 35 // Bitmask of return values for On...() methods 36 static constexpr Flags kNeedRemoval = 1; 37 static constexpr Flags kHandled = 2; 38 39 // Called when this object is added to a StateTracker, to give it the initial state. 40 // Note that |cinfo| might be null. 41 // May return flags: kNeedRemoval 42 // WARNING: This is called under StateTracker's mutex. 43 virtual Flags OnInitialize(zx_signals_t initial_state, const CountInfo* cinfo) = 0; 44 45 // Called whenever the state changes, to give it the new state. 46 // May return flags: kNeedRemoval 47 // WARNING: This is called under StateTracker's mutex 48 virtual Flags OnStateChange(zx_signals_t new_state) = 0; 49 50 // Called when |handle| (which refers to a handle to the object that owns the StateTracker) is 51 // being destroyed/"closed"/transferred. (The object itself, and thus the StateTracker too, may 52 // also be destroyed shortly afterwards.) 53 // Returns flag kHandled if |this| observer handled the call which normally 54 // means it was bound to |handle|. 55 // May also return flags: kNeedRemoval 56 // WARNING: This is called under StateTracker's mutex. 57 virtual Flags OnCancel(const Handle* handle) = 0; 58 59 // Called when the client wants to cancel an outstanding object_wait_aysnc(..key..). In this 60 // case the object might not be destroyed. 61 // Returns flag kHandled if |this| observer handled the call which normally 62 // means it was bound to |handle| and |key|. 63 // May also return flags: kNeedRemoval 64 // WARNING: This is called under StateTracker's mutex. 65 virtual Flags OnCancelByKey(const Handle* handle, const void* port, uint64_t key) { return 0; } 66 67 // Called after this observer has been removed from the state tracker list. In this callback 68 // is safe to delete the observer. 69 virtual void OnRemoved() {} 70 71protected: 72 ~StateObserver() {} 73 74private: 75 fbl::Canary<fbl::magic("SOBS")> canary_; 76 77 friend struct StateObserverListTraits; 78 fbl::DoublyLinkedListNodeState<StateObserver*> state_observer_list_node_state_; 79}; 80 81// For use by StateTracker to maintain a list of StateObservers. (We don't use the default traits so 82// that implementations of StateObserver can themselves use the default traits if they need to be on 83// a different list.) 84struct StateObserverListTraits { 85 inline static fbl::DoublyLinkedListNodeState<StateObserver*>& node_state( 86 StateObserver& obj) { 87 return obj.state_observer_list_node_state_; 88 } 89}; 90