1 // Copyright 2018 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #pragma once 6 7 #include <atomic> 8 #include <threads.h> 9 #include <zircon/thread_annotations.h> 10 11 namespace devmgr { 12 13 // locking and lock debugging 14 15 namespace internal { 16 extern mtx_t devhost_api_lock; 17 extern std::atomic<thrd_t> devhost_api_lock_owner; 18 } // namespace internal 19 20 #define REQ_DM_LOCK TA_REQ(&::devmgr::internal::devhost_api_lock) 21 #define USE_DM_LOCK TA_GUARDED(&::devmgr::internal::devhost_api_lock) 22 DM_LOCK()23static inline void DM_LOCK() TA_ACQ(&::devmgr::internal::devhost_api_lock) { 24 mtx_lock(&internal::devhost_api_lock); 25 internal::devhost_api_lock_owner.store(thrd_current()); 26 } 27 DM_UNLOCK()28static inline void DM_UNLOCK() TA_REL(&::devmgr::internal::devhost_api_lock) { 29 internal::devhost_api_lock_owner.store(0); 30 mtx_unlock(&internal::devhost_api_lock); 31 } 32 DM_LOCK_HELD()33static inline bool DM_LOCK_HELD() { 34 return thrd_equal(internal::devhost_api_lock_owner.load(), thrd_current()); 35 } 36 37 class ApiAutoLock { 38 public: ApiAutoLock()39 ApiAutoLock() TA_ACQ(&::devmgr::internal::devhost_api_lock) { 40 DM_LOCK(); 41 } 42 ~ApiAutoLock() TA_REL(&::devmgr::internal::devhost_api_lock) { 43 DM_UNLOCK(); 44 } 45 }; 46 47 class ApiAutoRelock { 48 public: ApiAutoRelock()49 ApiAutoRelock() TA_REL(&::devmgr::internal::devhost_api_lock) { 50 DM_UNLOCK(); 51 } 52 ~ApiAutoRelock() TA_ACQ(&::devmgr::internal::devhost_api_lock) { 53 DM_LOCK(); 54 } 55 }; 56 57 } // namespace devmgr 58