// Copyright 2022 The ChromiumOS Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef VM_TOOLS_SOMMELIER_WEAK_RESOURCE_PTR_H_ #define VM_TOOLS_SOMMELIER_WEAK_RESOURCE_PTR_H_ #include "sommelier.h" // NOLINT(build/include_directory) #include #include #include #include #include // WeakResourcePtr is a weak pointer for a proxy object (sl_host_foo). It can // be useful for objects with events like enter/leave, to keep track of an // object provided in the enter event and ensure that it is not used if the // client destroys it. template class WeakResourcePtr { public: WeakResourcePtr() { wl_list_init(&destroy_listener_.link); destroy_listener_.notify = ResourceDestroyed; } ~WeakResourcePtr() { wl_list_remove(&destroy_listener_.link); } WeakResourcePtr& operator=(SlHostType* host) { if (host == host_) return *this; Reset(); if (host) { host_ = host; wl_resource_add_destroy_listener(host_->resource, &destroy_listener_); } return *this; } operator bool() const { return host_; } SlHostType* operator->() const { return host_; } SlHostType* get() const { return host_; } void Reset() { host_ = nullptr; // Remove the listener wl_list_remove(&destroy_listener_.link); wl_list_init(&destroy_listener_.link); } private: SlHostType* host_ = nullptr; // This is always in an initialized state wl_listener destroy_listener_; static void ResourceDestroyed(wl_listener* listener, void* data) { WeakResourcePtr* ptr; ptr = wl_container_of(listener, ptr, destroy_listener_); ptr->Reset(); } }; #endif // VM_TOOLS_SOMMELIER_WEAK_RESOURCE_PTR_H_