drm_hwcomposer: Introduce SharedFd, use standard c++ RAII for UniqueFd
We use too much dup() system calls for present fence propagating. Also when propagating acquire fence we use additional logic for skipping such propagation for the validate/test cycle. Both issues can be solved by introducing SharedFd, which will track reference count of fd object. After that the UniqueFd is used very rarely and can be simplified by wrapping it into std::unique_ptr without caring too much of adding an extra malloc/free operation. Signed-off-by: Roman Stratiienko <r.stratiienko@gmail.com>
This commit is contained in:
parent
2bf68c3749
commit
76892784ac
23 changed files with 157 additions and 182 deletions
|
|
@ -24,7 +24,7 @@
|
|||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "UniqueFd.h"
|
||||
#include "fd.h"
|
||||
#include "log.h"
|
||||
|
||||
namespace android {
|
||||
|
|
@ -32,7 +32,7 @@ namespace android {
|
|||
class UEvent {
|
||||
public:
|
||||
static auto CreateInstance() -> std::unique_ptr<UEvent> {
|
||||
auto fd = UniqueFd(
|
||||
auto fd = MakeUniqueFd(
|
||||
socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_KOBJECT_UEVENT));
|
||||
|
||||
if (!fd) {
|
||||
|
|
@ -46,7 +46,7 @@ class UEvent {
|
|||
addr.nl_groups = UINT32_MAX;
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
|
||||
const int ret = bind(fd.Get(), (struct sockaddr *)&addr, sizeof(addr));
|
||||
const int ret = bind(*fd, (struct sockaddr *)&addr, sizeof(addr));
|
||||
if (ret != 0) {
|
||||
ALOGE("Failed to bind uevent socket: errno=%i", errno);
|
||||
return {};
|
||||
|
|
@ -59,7 +59,7 @@ class UEvent {
|
|||
constexpr int kUEventBufferSize = 1024;
|
||||
char buffer[kUEventBufferSize];
|
||||
ssize_t ret = 0;
|
||||
ret = read(fd_.Get(), &buffer, sizeof(buffer));
|
||||
ret = read(*fd_, &buffer, sizeof(buffer));
|
||||
if (ret == 0)
|
||||
return {};
|
||||
|
||||
|
|
|
|||
115
utils/UniqueFd.h
115
utils/UniqueFd.h
|
|
@ -1,115 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2015, 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
namespace android {
|
||||
|
||||
/*
|
||||
* Using UniqueFd:
|
||||
* 1. Create UniqueFd object:
|
||||
* auto fd_obj = UniqueFd(open("SomeFile", xxx));
|
||||
*
|
||||
* 2. Check whether the fd_obj is empty:
|
||||
* if (!fd_obj) { return -errno; }
|
||||
*
|
||||
* 3. Accessing the file descriptor:
|
||||
* int ret = read(fd_obj.Get(), buf, buf_size);
|
||||
*
|
||||
* 4. Closing the file:
|
||||
* FD will be closed once execution leaves fd_obj scope (on any return,
|
||||
* exception, destruction of class/struct where object is member, etc.).
|
||||
* User can also force closing the fd_obj by calling:
|
||||
* fd_obj = UniqueFd();
|
||||
* // fd is closed and fd_obj is empty now.
|
||||
*
|
||||
* 5. File descriptor may be transferred to the code, which will close it after
|
||||
* using. This can be done in 2 ways:
|
||||
* a. Duplicate the fd, in this case both fds should be closed separately:
|
||||
* int out_fd = dup(fd_obj.Get();
|
||||
* ...
|
||||
* close(out_fd);
|
||||
* b. Transfer ownership, use this method if you do not need the fd anymore.
|
||||
* int out_fd = fd_obj.Release();
|
||||
* // fd_obj is empty now.
|
||||
* ...
|
||||
* close(out_fd);
|
||||
*
|
||||
* 6. Transferring fd into another UniqueFD object:
|
||||
* UniqueFd fd_obj_2 = std::move(fd_obj);
|
||||
* // fd_obj empty now
|
||||
*/
|
||||
|
||||
constexpr int kEmptyFd = -1;
|
||||
|
||||
class UniqueFd {
|
||||
public:
|
||||
UniqueFd() = default;
|
||||
explicit UniqueFd(int fd) : fd_(fd){};
|
||||
|
||||
auto Release [[nodiscard]] () -> int {
|
||||
return std::exchange(fd_, kEmptyFd);
|
||||
}
|
||||
|
||||
auto Get [[nodiscard]] () const -> int {
|
||||
return fd_;
|
||||
}
|
||||
|
||||
static auto Dup(int fd) {
|
||||
// NOLINTNEXTLINE(android-cloexec-dup): fcntl has issue (see issue #63)
|
||||
return UniqueFd(dup(fd));
|
||||
}
|
||||
|
||||
explicit operator bool() const {
|
||||
return fd_ != kEmptyFd;
|
||||
}
|
||||
|
||||
~UniqueFd() {
|
||||
Set(kEmptyFd);
|
||||
}
|
||||
|
||||
/* Allow move semantics */
|
||||
UniqueFd(UniqueFd &&rhs) noexcept {
|
||||
Set(rhs.Release());
|
||||
}
|
||||
|
||||
auto operator=(UniqueFd &&rhs) noexcept -> UniqueFd & {
|
||||
Set(rhs.Release());
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* Disable copy semantics */
|
||||
UniqueFd(const UniqueFd &) = delete;
|
||||
auto operator=(const UniqueFd &) = delete;
|
||||
|
||||
private:
|
||||
void Set(int new_fd) {
|
||||
if (fd_ != kEmptyFd) {
|
||||
close(fd_);
|
||||
}
|
||||
fd_ = new_fd;
|
||||
}
|
||||
|
||||
int fd_ = kEmptyFd;
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
52
utils/fd.cpp
Normal file
52
utils/fd.cpp
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "fd.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
static void CloseFd(const int *fd) {
|
||||
if (fd != nullptr) {
|
||||
if (*fd >= 0)
|
||||
close(*fd);
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
|
||||
delete fd;
|
||||
}
|
||||
}
|
||||
|
||||
auto MakeUniqueFd(int fd) -> UniqueFd {
|
||||
if (fd < 0)
|
||||
return {nullptr, CloseFd};
|
||||
|
||||
return {new int(fd), CloseFd};
|
||||
}
|
||||
|
||||
auto MakeSharedFd(int fd) -> SharedFd {
|
||||
if (fd < 0)
|
||||
return {};
|
||||
|
||||
return {new int(fd), CloseFd};
|
||||
}
|
||||
|
||||
auto DupFd(SharedFd const &fd) -> int {
|
||||
if (!fd)
|
||||
return -1;
|
||||
|
||||
return fcntl(*fd, F_DUPFD_CLOEXEC, 0);
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
36
utils/fd.h
Normal file
36
utils/fd.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (C) 2015 - 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
namespace android {
|
||||
|
||||
using UniqueFd = std::unique_ptr<int, void (*)(const int *)>;
|
||||
using SharedFd = std::shared_ptr<int>;
|
||||
|
||||
auto MakeUniqueFd(int fd) -> UniqueFd;
|
||||
|
||||
auto MakeSharedFd(int fd) -> SharedFd;
|
||||
|
||||
auto DupFd(SharedFd const &fd) -> int;
|
||||
|
||||
} // namespace android
|
||||
Loading…
Add table
Add a link
Reference in a new issue