blob: b3ecaf211019e79e323d03bda5967fc1d787facb [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_LIB_CALLBACK_DESTRUCTION_SENTINEL_H_
#define SRC_LIB_CALLBACK_DESTRUCTION_SENTINEL_H_
#include <lib/fit/function.h>
#include <lib/syslog/cpp/macros.h>
#include "src/lib/fxl/macros.h"
namespace callback {
// Helper class to determine if a class has been deleted while running some
// code.
//
// To use a DestructionSentinel, one must add a DestructionSentinel member
// to the class susceptible to be deleted while running code. Any code
// susceptible to delete the class must be run inside the |DestructedWhile|
// method, and the method must do an early return if |DestructedWhile| returns
// |true|.
class DestructionSentinel {
public:
DestructionSentinel();
~DestructionSentinel();
// Executes |closure| and returns |true| if the sentinel has been destroyed
// while executing it.
inline bool DestructedWhile(const fit::closure& closure) {
bool is_destructed = false;
bool* old_is_destructed_ptr = is_destructed_ptr_;
is_destructed_ptr_ = &is_destructed;
closure();
if (is_destructed) {
if (old_is_destructed_ptr)
*old_is_destructed_ptr = true;
return true;
}
is_destructed_ptr_ = old_is_destructed_ptr;
return false;
};
private:
bool* is_destructed_ptr_ = nullptr;
FXL_DISALLOW_COPY_AND_ASSIGN(DestructionSentinel);
};
} // namespace callback
#endif // SRC_LIB_CALLBACK_DESTRUCTION_SENTINEL_H_