Skip to content

Commit

Permalink
Add SharedFD type
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 696587436
  • Loading branch information
MediaPipe Team authored and copybara-github committed Nov 14, 2024
1 parent f53af03 commit 1718461
Show file tree
Hide file tree
Showing 6 changed files with 177 additions and 9 deletions.
22 changes: 22 additions & 0 deletions mediapipe/framework/formats/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,28 @@ cc_test(
":unique_fd",
"//mediapipe/framework/port:gtest_main",
"//mediapipe/framework/port:status_matchers",
"//mediapipe/util:fd_test_util",
],
)

cc_library(
name = "shared_fd",
hdrs = ["shared_fd.h"],
deps = [
":unique_fd",
"@com_google_absl//absl/status:statusor",
],
)

cc_test(
name = "shared_fd_test",
srcs = ["shared_fd_test.cc"],
deps = [
":shared_fd",
":unique_fd",
"//mediapipe/framework/port:gtest_main",
"//mediapipe/framework/port:status_matchers",
"//mediapipe/util:fd_test_util",
],
)

Expand Down
66 changes: 66 additions & 0 deletions mediapipe/framework/formats/shared_fd.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#ifndef MEDIAPIPE_FRAMEWORK_FORMATS_SHARED_FD_H_
#define MEDIAPIPE_FRAMEWORK_FORMATS_SHARED_FD_H_

#include <cstddef>
#include <memory>
#include <utility>

#include "absl/status/statusor.h"
#include "mediapipe/framework/formats/unique_fd.h"

namespace mediapipe {

// Provides a shared ownership for a file descriptor.
//
// File descriptor is closed as soon as last SharedFd is destroyed.
// (Uses `std::shared_ptr` internally and can be used in the same way: copy,
// move, assign/compare with nullptr, use in conditional statements.)
class SharedFd {
public:
// `fd` a valid file descriptor.
explicit SharedFd(UniqueFd fd)
: fd_(std::make_shared<UniqueFd>(std::move(fd))) {}

// Constructs empty SharedFd (fd == nullptr evaluates to true)
SharedFd() = default;

~SharedFd() = default;

// Copyable
SharedFd(const SharedFd&) = default;
SharedFd& operator=(const SharedFd&) = default;

// Moveable
SharedFd(SharedFd&& other) = default;
SharedFd& operator=(SharedFd&& other) = default;

// Resets this SharedFd object (fd == nullptr will evaluate to true).
SharedFd& operator=(std::nullptr_t other) {
fd_ = other;
return *this;
}

bool operator==(std::nullptr_t other) const { return fd_ == other; }
bool operator!=(std::nullptr_t other) const { return !operator==(other); };

// SharedFd can be used in conditional statements:
// ```
// if (fd) {
// int raw_fd = fd.Get();
// }
// ```
explicit operator bool() const { return operator!=(nullptr); }

// Gets raw file descriptor for read purposes.
int Get() const { return fd_->Get(); }

// Duplicates file descriptor.
absl::StatusOr<UniqueFd> Dup() const { return fd_->Dup(); }

private:
std::shared_ptr<UniqueFd> fd_;
};

} // namespace mediapipe

#endif // MEDIAPIPE_FRAMEWORK_FORMATS_SHARED_FD_H_
64 changes: 64 additions & 0 deletions mediapipe/framework/formats/shared_fd_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include "mediapipe/framework/formats/shared_fd.h"

#include <utility>

#include "mediapipe/framework/formats/unique_fd.h"
#include "mediapipe/framework/port/gtest.h"
#include "mediapipe/framework/port/status_matchers.h"
#include "mediapipe/util/fd_test_util.h"

namespace mediapipe {
namespace {

TEST(SharedFdTest, CanCreateFromUniqueFd) {
int raw_fd = GetValidFd();
{
auto fd = SharedFd(UniqueFd(raw_fd));
EXPECT_TRUE(IsFdValid(fd.Get()));
}
EXPECT_FALSE(IsFdValid(raw_fd));
}

TEST(SharedFdTest, CanCopyAndMoveFd) {
int raw_fd = GetValidFd();
auto fd = SharedFd(UniqueFd(raw_fd));
{
SharedFd copied_fd = fd;
EXPECT_TRUE(IsFdValid(copied_fd.Get()));
}
EXPECT_TRUE(IsFdValid(fd.Get()));

{
SharedFd moved_fd = std::move(fd);
EXPECT_TRUE(IsFdValid(moved_fd.Get()));
}
EXPECT_FALSE(IsFdValid(raw_fd));
}

TEST(SharedFdTest, CanBeAssignedAndComparedWithNullptr) {
SharedFd fd;
EXPECT_FALSE(fd);
EXPECT_EQ(fd, nullptr);

int raw_fd = GetValidFd();
fd = SharedFd(UniqueFd(raw_fd));

EXPECT_NE(fd, nullptr);
EXPECT_TRUE(fd);

fd = nullptr;
EXPECT_FALSE(IsFdValid(raw_fd));
EXPECT_EQ(fd, nullptr);
EXPECT_FALSE(fd);
}

TEST(SharedFdTest, CanDup) {
int raw_fd = GetValidFd();
auto fd = SharedFd(UniqueFd(GetValidFd()));
MP_ASSERT_OK_AND_ASSIGN(UniqueFd dup_fd, fd.Dup());
EXPECT_NE(dup_fd.Get(), raw_fd);
EXPECT_TRUE(IsFdValid(dup_fd.Get()));
}

} // namespace
} // namespace mediapipe
10 changes: 1 addition & 9 deletions mediapipe/framework/formats/unique_fd_test.cc
Original file line number Diff line number Diff line change
@@ -1,23 +1,15 @@
#include "mediapipe/framework/formats/unique_fd.h"

#include <fcntl.h>
#include <unistd.h>

#include <utility>

#include "mediapipe/framework/port/gtest.h"
#include "mediapipe/framework/port/status_matchers.h"
#include "mediapipe/util/fd_test_util.h"

namespace mediapipe {

namespace {

// Returns a valid system file descriptor.
int GetValidFd() { return dup(STDOUT_FILENO); }

// Helper function to check if the file descriptor is valid (still open).
int IsFdValid(int fd) { return fcntl(fd, F_GETFD) != -1; }

TEST(UniqueFdTest, ShouldInitializeInvalidFd) {
UniqueFd unique_fd;
EXPECT_FALSE(unique_fd.IsValid());
Expand Down
7 changes: 7 additions & 0 deletions mediapipe/util/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,13 @@ cc_library(
}),
)

cc_library(
name = "fd_test_util",
testonly = True,
hdrs = ["fd_test_util.h"],
visibility = ["//mediapipe:__subpackages__"],
)

cc_library(
name = "header_util",
srcs = ["header_util.cc"],
Expand Down
17 changes: 17 additions & 0 deletions mediapipe/util/fd_test_util.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef MEDIAPIPE_UTIL_FD_TEST_UTIL_H_
#define MEDIAPIPE_UTIL_FD_TEST_UTIL_H_

#include <fcntl.h>
#include <unistd.h>

namespace mediapipe {

// Returns a valid system file descriptor.
inline int GetValidFd() { return dup(STDOUT_FILENO); }

// Helper function to check if the file descriptor is valid (still open).
inline int IsFdValid(int fd) { return fcntl(fd, F_GETFD) != -1; }

} // namespace mediapipe

#endif // MEDIAPIPE_UTIL_FD_TEST_UTIL_H_

0 comments on commit 1718461

Please sign in to comment.