Title: [292225] trunk/Source/WebKit
- Revision
- 292225
- Author
- commit-qu...@webkit.org
- Date
- 2022-04-01 10:43:40 -0700 (Fri, 01 Apr 2022)
Log Message
[Linux] Implement IPC::Semaphore
https://bugs.webkit.org/show_bug.cgi?id=238596
Patch by Zan Dobersek <zdober...@igalia.com> on 2022-04-01
Reviewed by Adrian Perez de Castro.
Provide a Linux implementation for IPC::Semaphore that's based on
eventfd mechanics.
The IPC::Semaphore class now has a UNIX-specific file descriptor member
variable. For Linux, this file descriptor is an eventfd with semaphore
semantics (eventfd being Linux-specific). Signalling and waiting on
such semaphore is done through the read() and write() functions.
Non-Linux platforms are expected to provide something equivalent, if
possible.
For encoding and decoding that's necessary to move these semaphores
across process boundaries, IPC::Attachment is used. For encoding the
eventfd is simply duplicated and pushed into the Attachment, and for
decoding the Attachment's file descriptor is taken and adopted by the
Semaphore object.
* Platform/IPC/IPCSemaphore.h:
(IPC::Semaphore::operator bool const):
* Platform/IPC/unix/IPCSemaphoreUnix.cpp:
(IPC::Semaphore::Semaphore):
(IPC::Semaphore::~Semaphore):
(IPC::Semaphore::operator=):
(IPC::Semaphore::signal):
(IPC::waitImpl):
(IPC::Semaphore::wait):
(IPC::Semaphore::waitFor):
(IPC::Semaphore::encode const):
(IPC::Semaphore::decode):
(IPC::Semaphore::destroy):
Modified Paths
Diff
Modified: trunk/Source/WebKit/ChangeLog (292224 => 292225)
--- trunk/Source/WebKit/ChangeLog 2022-04-01 17:22:25 UTC (rev 292224)
+++ trunk/Source/WebKit/ChangeLog 2022-04-01 17:43:40 UTC (rev 292225)
@@ -1,3 +1,40 @@
+2022-04-01 Zan Dobersek <zdober...@igalia.com>
+
+ [Linux] Implement IPC::Semaphore
+ https://bugs.webkit.org/show_bug.cgi?id=238596
+
+ Reviewed by Adrian Perez de Castro.
+
+ Provide a Linux implementation for IPC::Semaphore that's based on
+ eventfd mechanics.
+
+ The IPC::Semaphore class now has a UNIX-specific file descriptor member
+ variable. For Linux, this file descriptor is an eventfd with semaphore
+ semantics (eventfd being Linux-specific). Signalling and waiting on
+ such semaphore is done through the read() and write() functions.
+ Non-Linux platforms are expected to provide something equivalent, if
+ possible.
+
+ For encoding and decoding that's necessary to move these semaphores
+ across process boundaries, IPC::Attachment is used. For encoding the
+ eventfd is simply duplicated and pushed into the Attachment, and for
+ decoding the Attachment's file descriptor is taken and adopted by the
+ Semaphore object.
+
+ * Platform/IPC/IPCSemaphore.h:
+ (IPC::Semaphore::operator bool const):
+ * Platform/IPC/unix/IPCSemaphoreUnix.cpp:
+ (IPC::Semaphore::Semaphore):
+ (IPC::Semaphore::~Semaphore):
+ (IPC::Semaphore::operator=):
+ (IPC::Semaphore::signal):
+ (IPC::waitImpl):
+ (IPC::Semaphore::wait):
+ (IPC::Semaphore::waitFor):
+ (IPC::Semaphore::encode const):
+ (IPC::Semaphore::decode):
+ (IPC::Semaphore::destroy):
+
2022-04-01 Youenn Fablet <you...@apple.com>
ServiceWorkerRegistration.getNotifications should list all persistent notifications
Modified: trunk/Source/WebKit/Platform/IPC/IPCSemaphore.h (292224 => 292225)
--- trunk/Source/WebKit/Platform/IPC/IPCSemaphore.h 2022-04-01 17:22:25 UTC (rev 292224)
+++ trunk/Source/WebKit/Platform/IPC/IPCSemaphore.h 2022-04-01 17:43:40 UTC (rev 292225)
@@ -64,6 +64,10 @@
explicit operator bool() const { return m_sendRight || m_semaphore != SEMAPHORE_NULL; }
#elif OS(WINDOWS)
explicit Semaphore(HANDLE);
+#elif USE(UNIX_DOMAIN_SOCKETS)
+ explicit Semaphore(int fd);
+
+ explicit operator bool() const { return m_fd != -1; }
#else
explicit operator bool() const { return true; }
#endif
@@ -75,6 +79,8 @@
semaphore_t m_semaphore { SEMAPHORE_NULL };
#elif OS(WINDOWS)
HANDLE m_semaphoreHandle { nullptr };
+#elif USE(UNIX_DOMAIN_SOCKETS)
+ int m_fd { -1 };
#endif
};
Modified: trunk/Source/WebKit/Platform/IPC/unix/IPCSemaphoreUnix.cpp (292224 => 292225)
--- trunk/Source/WebKit/Platform/IPC/unix/IPCSemaphoreUnix.cpp 2022-04-01 17:22:25 UTC (rev 292224)
+++ trunk/Source/WebKit/Platform/IPC/unix/IPCSemaphoreUnix.cpp 2022-04-01 17:43:40 UTC (rev 292225)
@@ -26,47 +26,135 @@
#include "config.h"
#include "IPCSemaphore.h"
+#include <wtf/UniStdExtras.h>
+
+#if OS(LINUX)
+#include <sys/eventfd.h>
+#endif
+
namespace IPC {
Semaphore::Semaphore()
{
- ASSERT_NOT_REACHED();
+#if OS(LINUX)
+ m_fd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK | EFD_SEMAPHORE);
+#endif
}
-Semaphore::Semaphore(Semaphore&&)
+Semaphore::Semaphore(int fd)
+ : m_fd(fd)
+{ }
+
+Semaphore::Semaphore(Semaphore&& o)
{
- ASSERT_NOT_REACHED();
+ m_fd = o.m_fd;
+ o.m_fd = -1;
}
-Semaphore::~Semaphore() = default;
+Semaphore::~Semaphore()
+{
+ destroy();
+}
-Semaphore& Semaphore::operator=(Semaphore&&) = default;
+Semaphore& Semaphore::operator=(Semaphore&& o)
+{
+ if (&o == this)
+ return *this;
+ destroy();
+ m_fd = o.m_fd;
+ o.m_fd = -1;
+ return *this;
+}
+
void Semaphore::signal()
{
+#if OS(LINUX)
+ ASSERT_WITH_MESSAGE(m_fd >= 0, "Signalling on an invalid semaphore object");
+
+ // Matching waitImpl() and EFD_SEMAPHORE semantics, increment the semaphore value by 1.
+ uint64_t value = 1;
+ while (true) {
+ int ret = write(m_fd, &value, sizeof(uint64_t));
+ if (LIKELY(ret != -1 || errno != EINTR))
+ break;
+ }
+#endif
}
+#if OS(LINUX)
+static bool waitImpl(int fd, int timeout)
+{
+ struct pollfd pollfdValue { .fd = fd, .events = POLLIN, .revents = 0 };
+ int ret = 0;
+
+ // Iterate on polling while interrupts are thrown, otherwise bail out of the loop immediately.
+ while (true) {
+ ret = poll(&pollfdValue, 1, timeout);
+ if (LIKELY(ret != -1 || errno != EINTR))
+ break;
+ }
+
+ // Fail if the return value doesn't indicate the single file descriptor with only input events available.
+ if (ret != 1 || !!(pollfdValue.revents ^ POLLIN))
+ return false;
+
+ // There should be data for reading -- due to EFD_SEMAPHORE, it should be 1 packed into an 8-byte value.
+ uint64_t value = 0;
+ ret = read(fd, &value, sizeof(uint64_t));
+ if (ret != sizeof(uint64_t) || value != 1)
+ return false;
+
+ return true;
+}
+#endif
+
bool Semaphore::wait()
{
+#if OS(LINUX)
+ ASSERT_WITH_MESSAGE(m_fd >= 0, "Waiting on an invalid semaphore object");
+
+ return waitImpl(m_fd, -1);
+#else
return false;
+#endif
}
-bool Semaphore::waitFor(Timeout)
+bool Semaphore::waitFor(Timeout timeout)
{
+#if OS(LINUX)
+ ASSERT_WITH_MESSAGE(m_fd >= 0, "Waiting on an invalid semaphore object");
+
+ int timeoutValue = -1;
+ if (!timeout.isInfinity())
+ timeoutValue = int(timeout.secondsUntilDeadline().milliseconds());
+ return waitImpl(m_fd, timeoutValue);
+#else
return false;
+#endif
}
-void Semaphore::encode(Encoder&) const
+void Semaphore::encode(Encoder& encoder) const
{
+ int duplicate = -1;
+ if (m_fd != -1)
+ duplicate = dupCloseOnExec(m_fd);
+
+ encoder.addAttachment(Attachment(duplicate));
}
-std::optional<Semaphore> Semaphore::decode(Decoder&)
+std::optional<Semaphore> Semaphore::decode(Decoder& decoder)
{
- return Semaphore { };
+ auto attachment = decoder.takeLastAttachment();
+ if (!attachment)
+ return std::nullopt;
+ return std::optional<Semaphore> { std::in_place, attachment->releaseFileDescriptor() };
}
void Semaphore::destroy()
{
+ if (m_fd >= 0)
+ closeWithRetry(m_fd);
}
} // namespace IPC
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes