From 05292354d3034919b1196b61ccdd41966950b5cd Mon Sep 17 00:00:00 2001 From: MediaPipe Team Date: Tue, 5 Nov 2024 15:57:32 -0800 Subject: [PATCH] No public description PiperOrigin-RevId: 693505976 --- mediapipe/framework/formats/BUILD | 1 + mediapipe/framework/formats/unique_fd.cc | 118 +++++++++++++++++++++++ mediapipe/framework/formats/unique_fd.h | 97 +------------------ 3 files changed, 123 insertions(+), 93 deletions(-) create mode 100644 mediapipe/framework/formats/unique_fd.cc diff --git a/mediapipe/framework/formats/BUILD b/mediapipe/framework/formats/BUILD index 3e74db39cc..9eaba8c0e2 100644 --- a/mediapipe/framework/formats/BUILD +++ b/mediapipe/framework/formats/BUILD @@ -300,6 +300,7 @@ cc_test( cc_library( name = "unique_fd", + srcs = ["unique_fd.cc"], hdrs = ["unique_fd.h"], deps = [ "//mediapipe/framework/port:ret_check", diff --git a/mediapipe/framework/formats/unique_fd.cc b/mediapipe/framework/formats/unique_fd.cc new file mode 100644 index 0000000000..38f2aed338 --- /dev/null +++ b/mediapipe/framework/formats/unique_fd.cc @@ -0,0 +1,118 @@ +#include "mediapipe/framework/formats/unique_fd.h" + +#include + +#include "absl/base/attributes.h" +#include "absl/log/absl_log.h" +#include "absl/status/statusor.h" +#include "mediapipe/framework/port/ret_check.h" + +#if (__ANDROID_API__ >= 29) && defined(__BIONIC__) && !defined(NDEBUG) +#define MEDIAPIPE_UNIQUE_FD_USE_FDSAN 1 + +#include + +#include + +#endif // (__ANDROID_API__ >= 29) && defined(__BIONIC__) && !defined(NDEBUG) + +namespace mediapipe { + +namespace { + +#if defined(MEDIAPIPE_UNIQUE_FD_USE_FDSAN) +// Address of the object is used as tag. +uint64_t Tag(UniqueFd* fd) { return reinterpret_cast(fd); } + +// These functions are marked with __attribute__((weak)), so that their +// availability can be determined at runtime. These wrappers will use them +// if available, and fall back to no-ops or regular close on devices older +// than API level 29 or non-bionic or non-production builds. +void FdsanExchangeTag(int fd, uint64_t old_tag, uint64_t new_tag) { + if (android_fdsan_exchange_owner_tag) { + android_fdsan_exchange_owner_tag(fd, old_tag, new_tag); + } +} + +void FdsanClose(int fd, uint64_t tag) { + if (android_fdsan_close_with_tag) { + if (android_fdsan_close_with_tag(fd, tag) != 0) { + ABSL_LOG(ERROR) << "Failed to close fd: " << fd; + } + return; + } + if (::close(fd) != 0) { + ABSL_LOG(ERROR) << "Failed to close fd: " << fd; + } +} +#endif // MEDIAPIPE_UNIQUE_FD_USE_FDSAN + +} // namespace + +UniqueFd& UniqueFd::operator=(UniqueFd&& move) { + if (this == &move) { + return *this; + } + + Reset(); + + if (move.fd_ != -1) { + fd_ = move.fd_; + move.fd_ = -1; +#if defined(MEDIAPIPE_UNIQUE_FD_USE_FDSAN) + // Acquire ownership from the moved-from object. + FdsanExchangeTag(fd_, Tag(&move), Tag(this)); +#endif // MEDIAPIPE_UNIQUE_FD_USE_FDSAN + } + + return *this; +} + +absl::StatusOr UniqueFd::Dup() const { + RET_CHECK(IsValid()); + int dup_fd = dup(Get()); + return UniqueFd(dup_fd); +} + +// Releases ownership of the file descriptor and returns it. +ABSL_MUST_USE_RESULT int UniqueFd::Release() { + if (!IsValid()) { + return -1; + } + + int fd = fd_; + fd_ = -1; +#if defined(MEDIAPIPE_UNIQUE_FD_USE_FDSAN) + // Release ownership. + FdsanExchangeTag(fd, Tag(this), 0); +#endif // MEDIAPIPE_UNIQUE_FD_USE_FDSAN + return fd; +} + +// Closes a wrapped file descriptor and resets the wrapper. +void UniqueFd::Reset(int new_fd) { + if (IsValid()) { +#if defined(MEDIAPIPE_UNIQUE_FD_USE_FDSAN) + FdsanClose(fd_, Tag(this)); +#else + if (::close(fd_) != 0) { + ABSL_LOG(ERROR) << "Failed to close fd: " << fd_; + } +#endif // MEDIAPIPE_UNIQUE_FD_USE_FDSAN + fd_ = -1; + } + + if (new_fd != -1) { + fd_ = new_fd; +#if defined(MEDIAPIPE_UNIQUE_FD_USE_FDSAN) + // Acquire ownership of the presumably unowned fd. + FdsanExchangeTag(fd_, 0, Tag(this)); +#endif // MEDIAPIPE_UNIQUE_FD_USE_FDSAN + } +} + +} // namespace mediapipe + +#ifdef MEDIAPIPE_UNIQUE_FD_USE_FDSAN +#undef MEDIAPIPE_UNIQUE_FD_USE_FDSAN +#endif diff --git a/mediapipe/framework/formats/unique_fd.h b/mediapipe/framework/formats/unique_fd.h index 015628d9c4..3f1c63d7c1 100644 --- a/mediapipe/framework/formats/unique_fd.h +++ b/mediapipe/framework/formats/unique_fd.h @@ -1,19 +1,10 @@ #ifndef MEDIAPIPE_FRAMEWORK_FORMATS_ANDROID_UNIQUE_FD_H_ #define MEDIAPIPE_FRAMEWORK_FORMATS_ANDROID_UNIQUE_FD_H_ -#include - #include #include "absl/base/attributes.h" -#include "absl/log/absl_log.h" #include "absl/status/statusor.h" -#include "mediapipe/framework/port/ret_check.h" - -#if (__ANDROID_API__ >= 29) && defined(__BIONIC__) && !defined(NDEBUG) -#define MEDIAPIPE_USE_FDSAN 1 -#include -#endif // (__ANDROID_API__ >= 29) && defined(__BIONIC__) && !defined(NDEBUG) namespace mediapipe { @@ -38,103 +29,23 @@ class UniqueFd { ~UniqueFd() { Reset(); } UniqueFd& operator=(const UniqueFd& copy) = delete; - UniqueFd& operator=(UniqueFd&& move) { - if (this == &move) { - return *this; - } - - Reset(); - - if (move.fd_ != -1) { - fd_ = move.fd_; - move.fd_ = -1; -#if defined(MEDIAPIPE_USE_FDSAN) - // Acquire ownership from the moved-from object. - FdsanExchangeTag(fd_, move.Tag(), Tag()); -#endif // MEDIAPIPE_USE_FDSAN - } - - return *this; - } - + UniqueFd& operator=(UniqueFd&& move); // Returns a non-owned file descriptor. int Get() const { return fd_; } // Checks if a valid file descriptor is wrapped. bool IsValid() const { return fd_ >= 0; } - absl::StatusOr Dup() const { - RET_CHECK(IsValid()); - int dup_fd = dup(Get()); - return UniqueFd(dup_fd); - } + absl::StatusOr Dup() const; // Releases ownership of the file descriptor and returns it. - ABSL_MUST_USE_RESULT int Release() { - if (!IsValid()) { - return -1; - } - - int fd = fd_; - fd_ = -1; -#if defined(MEDIAPIPE_USE_FDSAN) - // Release ownership. - FdsanExchangeTag(fd, Tag(), 0); -#endif // MEDIAPIPE_USE_FDSAN - return fd; - } + ABSL_MUST_USE_RESULT int Release(); // Closes a wrapped file descriptor and resets the wrapper. - void Reset(int new_fd = -1) { - if (IsValid()) { -#if defined(MEDIAPIPE_USE_FDSAN) - FdsanClose(fd_, Tag()); -#else - if (::close(fd_) != 0) { - ABSL_LOG(ERROR) << "Failed to close fd: " << fd_; - } -#endif // MEDIAPIPE_USE_FDSAN - fd_ = -1; - } - - if (new_fd != -1) { - fd_ = new_fd; -#if defined(MEDIAPIPE_USE_FDSAN) - // Acquire ownership of the presumably unowned fd. - FdsanExchangeTag(fd_, 0, Tag()); -#endif // MEDIAPIPE_USE_FDSAN - } - } + void Reset(int new_fd = -1); private: int fd_ = -1; - -#if defined(MEDIAPIPE_USE_FDSAN) - // Address of the object is used as tag. - uint64_t Tag() { return reinterpret_cast(this); } - - // These functions are marked with __attribute__((weak)), so that their - // availability can be determined at runtime. These wrappers will use them - // if available, and fall back to no-ops or regular close on devices older - // than API level 29 or non-bionic or non-production builds. - static void FdsanExchangeTag(int fd, uint64_t old_tag, uint64_t new_tag) { - if (android_fdsan_exchange_owner_tag) { - android_fdsan_exchange_owner_tag(fd, old_tag, new_tag); - } - } - - static void FdsanClose(int fd, uint64_t tag) { - if (android_fdsan_close_with_tag) { - if (android_fdsan_close_with_tag(fd, tag) != 0) { - ABSL_LOG(ERROR) << "Failed to close fd: " << fd; - } - return; - } - if (::close(fd) != 0) { - ABSL_LOG(ERROR) << "Failed to close fd: " << fd; - } - } -#endif // MEDIAPIPE_USE_FDSAN }; } // namespace mediapipe