Add fd_handle interface
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Wed, 22 Jul 2020 19:29:17 +0000 (15:29 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Mon, 27 Jul 2020 20:31:53 +0000 (16:31 -0400)
An fd_handle allows the reference counting of file descriptors which may
be shared by multiple objects. There is no synchronization imposed (or
provided) for the use of the underlying file descriptors as this utility
meant to be used on file descriptors where this would not make
sense (eventfd, dir fd, etc.)

Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: I1bdeb48caddda125aa8f41afd502df2eb4a0b8b2

src/common/Makefile.am
src/common/fd-handle.c [new file with mode: 0644]
src/common/fd-handle.h [new file with mode: 0644]

index d071bdfdfca6f4bc3dcc6dcbc12dbc445a2586cb..49e9a8fd8a478d0d691798fdeec77da3115620ea 100644 (file)
@@ -49,6 +49,7 @@ libcommon_la_SOURCES = \
        evaluation.c \
        event.c \
        filter.c filter.h \
+       fd-handle.c fd-handle.h \
        fs-handle.c fs-handle.h fs-handle-internal.h \
        futex.c futex.h \
        location.c \
diff --git a/src/common/fd-handle.c b/src/common/fd-handle.c
new file mode 100644 (file)
index 0000000..a9c7be4
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2020 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ */
+
+#include <unistd.h>
+#include <urcu/ref.h>
+
+#include "fd-handle.h"
+#include <common/error.h>
+
+struct fd_handle {
+       struct urcu_ref ref;
+       int fd;
+};
+
+static void fd_handle_release(struct urcu_ref *ref)
+{
+       int ret;
+       struct fd_handle *handle = container_of(ref, struct fd_handle, ref);
+
+       assert(handle->fd >= 0);
+       ret = close(handle->fd);
+       if (ret == -1) {
+               PERROR("Failed to close file descriptor of fd_handle upon release: fd = %d",
+                               handle->fd);
+       }
+
+       free(handle);
+}
+
+LTTNG_HIDDEN
+struct fd_handle *fd_handle_create(int fd)
+{
+       struct fd_handle *handle = NULL;
+
+       if (fd < 0) {
+               ERR("Attempted to create an fd_handle from an invalid file descriptor: fd = %d",
+                               fd);
+               goto end;
+       }
+
+       handle = zmalloc(sizeof(*handle));
+       if (!handle) {
+               PERROR("Failed to allocate fd_handle");
+               goto end;
+       }
+
+       urcu_ref_init(&handle->ref);
+       handle->fd = fd;
+
+end:
+       return handle;
+}
+
+LTTNG_HIDDEN
+void fd_handle_get(struct fd_handle *handle)
+{
+       assert(handle);
+       urcu_ref_get(&handle->ref);
+}
+
+LTTNG_HIDDEN
+void fd_handle_put(struct fd_handle *handle)
+{
+       assert(handle);
+       urcu_ref_put(&handle->ref, fd_handle_release);
+}
+
+LTTNG_HIDDEN
+int fd_handle_get_fd(struct fd_handle *handle)
+{
+       assert(handle);
+       return handle->fd;
+}
+
+LTTNG_HIDDEN
+struct fd_handle *fd_handle_copy(const struct fd_handle *handle)
+{
+       struct fd_handle *new_handle = NULL;
+       const int new_fd = dup(handle->fd);
+
+       if (new_fd < 0) {
+               PERROR("Failed to duplicate file descriptor while copying fd_handle: fd = %d", handle->fd);
+               goto end;
+       }
+
+       new_handle = fd_handle_create(new_fd);
+end:
+       return new_handle;
+}
diff --git a/src/common/fd-handle.h b/src/common/fd-handle.h
new file mode 100644 (file)
index 0000000..4463f30
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2020 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ */
+
+#ifndef FD_HANDLE_H
+#define FD_HANDLE_H
+
+#include <common/macros.h>
+
+/*
+ * Wrapper around a file descriptor providing reference counting semantics.
+ *
+ * An fd_handle will close() the underlying file descriptor when its reference
+ * count reaches zero.
+ */
+struct fd_handle;
+
+/* Create a file descriptor handle. */
+LTTNG_HIDDEN
+struct fd_handle *fd_handle_create(int fd);
+
+/* Acquire reference to a file descriptor handle. */
+LTTNG_HIDDEN
+void fd_handle_get(struct fd_handle *handle);
+
+/* Release reference to a file descriptor handle. */
+LTTNG_HIDDEN
+void fd_handle_put(struct fd_handle *handle);
+
+/*
+ * Return the underlying file descriptor of a file descriptor handle.
+ *
+ * This function can't fail.
+ */
+LTTNG_HIDDEN
+int fd_handle_get_fd(struct fd_handle *handle);
+
+/*
+ * Obtain a copy of a file descriptor handle.
+ *
+ * On success, the caller becomes the sole owner of the returned file descriptor
+ * handle. The underlying file descriptor is duplicated using dup(). Refer to
+ * the system documentation for the semantics of dup() for this particular file
+ * descriptor type.
+ */
+LTTNG_HIDDEN
+struct fd_handle *fd_handle_copy(const struct fd_handle *handle);
+
+#endif /* FS_HANDLE_H */
This page took 0.03668 seconds and 4 git commands to generate.