blob: a9f7a591bd4e858d5ee6e2fc04a84c0d695eee7a [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ipcz/api_object.h"
#include <cstdint>
#include "third_party/abseil-cpp/absl/container/flat_hash_set.h"
#include "third_party/abseil-cpp/absl/synchronization/mutex.h"
namespace ipcz {
namespace {
#if defined(LEAK_SANITIZER)
// When LSan is enabled, we keep all living API objects tracked within a global
// hash set so that they're always reachable and never detected as leaks. This
// is to work around the fact that Chromium has amassed hundreds of tests across
// more than a dozen test suites which leak Mojo handles; and prior to MojoIpcz
// the leaks were masked from LSan by Mojo's use of a global handle table.
//
// TODO(https://crbug.com/1415046): Remove this once all of the leaky tests are
// fixed.
class TrackedObjectSet {
public:
TrackedObjectSet() = default;
~TrackedObjectSet() = default;
void Add(APIObject* object) {
absl::MutexLock lock(&mutex_);
tracked_objects_.insert(reinterpret_cast<uintptr_t>(object));
}
void Remove(APIObject* object) {
absl::MutexLock lock(&mutex_);
tracked_objects_.erase(reinterpret_cast<uintptr_t>(object));
}
private:
absl::Mutex mutex_;
// Use a uintptr_t to track since these aren't meant to be usable as pointers.
absl::flat_hash_set<uintptr_t> tracked_objects_ ABSL_GUARDED_BY(mutex_);
};
TrackedObjectSet& GetTrackedObjectSet() {
static auto* set = new TrackedObjectSet();
return *set;
}
void TrackObject(APIObject* object) {
GetTrackedObjectSet().Add(object);
}
void UntrackObject(APIObject* object) {
GetTrackedObjectSet().Remove(object);
}
#else
void TrackObject(APIObject*) {}
void UntrackObject(APIObject*) {}
#endif
} // namespace
APIObject::APIObject(ObjectType type) : type_(type) {
TrackObject(this);
}
APIObject::~APIObject() {
UntrackObject(this);
}
bool APIObject::CanSendFrom(Portal& sender) {
return false;
}
} // namespace ipcz