浏览代码

Kernel: Add bitwise operators for Thread::FileBlocker::BlockFlags enum

Switch to using type-safe bitwise operators for the BlockFlags class,
this cleans up a lot of boilerplate casts which are necessary when the
enum is declared as `enum class`.
Brian Gianforcaro 4 年之前
父节点
当前提交
5f6ab77352

+ 12 - 11
Kernel/FileSystem/FileDescription.cpp

@@ -98,22 +98,23 @@ KResult FileDescription::attach()
 
 
 Thread::FileBlocker::BlockFlags FileDescription::should_unblock(Thread::FileBlocker::BlockFlags block_flags) const
 Thread::FileBlocker::BlockFlags FileDescription::should_unblock(Thread::FileBlocker::BlockFlags block_flags) const
 {
 {
-    u32 unblock_flags = (u32)Thread::FileBlocker::BlockFlags::None;
-    if (((u32)block_flags & (u32)Thread::FileBlocker::BlockFlags::Read) && can_read())
-        unblock_flags |= (u32)Thread::FileBlocker::BlockFlags::Read;
-    if (((u32)block_flags & (u32)Thread::FileBlocker::BlockFlags::Write) && can_write())
-        unblock_flags |= (u32)Thread::FileBlocker::BlockFlags::Write;
+    using BlockFlags = Thread::FileBlocker::BlockFlags;
+    BlockFlags unblock_flags = BlockFlags::None;
+    if (has_flag(block_flags, BlockFlags::Read) && can_read())
+        unblock_flags |= BlockFlags::Read;
+    if (has_flag(block_flags, BlockFlags::Write) && can_write())
+        unblock_flags |= BlockFlags::Write;
     // TODO: Implement Thread::FileBlocker::BlockFlags::Exception
     // TODO: Implement Thread::FileBlocker::BlockFlags::Exception
 
 
-    if ((u32)block_flags & (u32)Thread::FileBlocker::BlockFlags::SocketFlags) {
+    if (has_flag(block_flags, BlockFlags::SocketFlags)) {
         auto* sock = socket();
         auto* sock = socket();
         VERIFY(sock);
         VERIFY(sock);
-        if (((u32)block_flags & (u32)Thread::FileBlocker::BlockFlags::Accept) && sock->can_accept())
-            unblock_flags |= (u32)Thread::FileBlocker::BlockFlags::Accept;
-        if (((u32)block_flags & (u32)Thread::FileBlocker::BlockFlags::Connect) && sock->setup_state() == Socket::SetupState::Completed)
-            unblock_flags |= (u32)Thread::FileBlocker::BlockFlags::Connect;
+        if (has_flag(block_flags, BlockFlags::Accept) && sock->can_accept())
+            unblock_flags |= BlockFlags::Accept;
+        if (has_flag(block_flags, BlockFlags::Connect) && sock->setup_state() == Socket::SetupState::Completed)
+            unblock_flags |= BlockFlags::Connect;
     }
     }
-    return (Thread::FileBlocker::BlockFlags)unblock_flags;
+    return unblock_flags;
 }
 }
 
 
 KResult FileDescription::stat(::stat& buffer)
 KResult FileDescription::stat(::stat& buffer)

+ 6 - 4
Kernel/Net/IPv4Socket.cpp

@@ -47,6 +47,8 @@ namespace Kernel {
 
 
 static AK::Singleton<Lockable<HashTable<IPv4Socket*>>> s_table;
 static AK::Singleton<Lockable<HashTable<IPv4Socket*>>> s_table;
 
 
+using BlockFlags = Thread::FileDescriptionBlocker::BlockFlags;
+
 Lockable<HashTable<IPv4Socket*>>& IPv4Socket::all_sockets()
 Lockable<HashTable<IPv4Socket*>>& IPv4Socket::all_sockets()
 {
 {
     return *s_table;
     return *s_table;
@@ -247,11 +249,11 @@ KResultOr<size_t> IPv4Socket::receive_byte_buffered(FileDescription& description
             return EAGAIN;
             return EAGAIN;
 
 
         locker.unlock();
         locker.unlock();
-        auto unblocked_flags = Thread::FileDescriptionBlocker::BlockFlags::None;
+        auto unblocked_flags = BlockFlags::None;
         auto res = Thread::current()->block<Thread::ReadBlocker>({}, description, unblocked_flags);
         auto res = Thread::current()->block<Thread::ReadBlocker>({}, description, unblocked_flags);
         locker.lock();
         locker.lock();
 
 
-        if (!((u32)unblocked_flags & (u32)Thread::FileDescriptionBlocker::BlockFlags::Read)) {
+        if (!has_flag(unblocked_flags, BlockFlags::Read)) {
             if (res.was_interrupted())
             if (res.was_interrupted())
                 return EINTR;
                 return EINTR;
 
 
@@ -300,11 +302,11 @@ KResultOr<size_t> IPv4Socket::receive_packet_buffered(FileDescription& descripti
         }
         }
 
 
         locker.unlock();
         locker.unlock();
-        auto unblocked_flags = Thread::FileDescriptionBlocker::BlockFlags::None;
+        auto unblocked_flags = BlockFlags::None;
         auto res = Thread::current()->block<Thread::ReadBlocker>({}, description, unblocked_flags);
         auto res = Thread::current()->block<Thread::ReadBlocker>({}, description, unblocked_flags);
         locker.lock();
         locker.lock();
 
 
-        if (!((u32)unblocked_flags & (u32)Thread::FileDescriptionBlocker::BlockFlags::Read)) {
+        if (!has_flag(unblocked_flags, BlockFlags::Read)) {
             if (res.was_interrupted())
             if (res.was_interrupted())
                 return EINTR;
                 return EINTR;
 
 

+ 1 - 1
Kernel/Net/LocalSocket.cpp

@@ -192,7 +192,7 @@ KResult LocalSocket::connect(FileDescription& description, Userspace<const socka
 
 
     dbgln_if(LOCAL_SOCKET_DEBUG, "LocalSocket({}) connect({}) status is {}", this, safe_address, to_string(setup_state()));
     dbgln_if(LOCAL_SOCKET_DEBUG, "LocalSocket({}) connect({}) status is {}", this, safe_address, to_string(setup_state()));
 
 
-    if (!((u32)unblock_flags & (u32)Thread::FileDescriptionBlocker::BlockFlags::Connect)) {
+    if (!has_flag(unblock_flags, Thread::FileDescriptionBlocker::BlockFlags::Connect)) {
         set_connect_side_role(Role::None);
         set_connect_side_role(Role::None);
         return ECONNREFUSED;
         return ECONNREFUSED;
     }
     }

+ 6 - 4
Kernel/Syscalls/read.cpp

@@ -30,6 +30,8 @@
 
 
 namespace Kernel {
 namespace Kernel {
 
 
+using BlockFlags = Thread::FileBlocker::BlockFlags;
+
 KResultOr<ssize_t> Process::sys$readv(int fd, Userspace<const struct iovec*> iov, int iov_count)
 KResultOr<ssize_t> Process::sys$readv(int fd, Userspace<const struct iovec*> iov, int iov_count)
 {
 {
     REQUIRE_PROMISE(stdio);
     REQUIRE_PROMISE(stdio);
@@ -65,10 +67,10 @@ KResultOr<ssize_t> Process::sys$readv(int fd, Userspace<const struct iovec*> iov
     for (auto& vec : vecs) {
     for (auto& vec : vecs) {
         if (description->is_blocking()) {
         if (description->is_blocking()) {
             if (!description->can_read()) {
             if (!description->can_read()) {
-                auto unblock_flags = Thread::FileBlocker::BlockFlags::None;
+                auto unblock_flags = BlockFlags::None;
                 if (Thread::current()->block<Thread::ReadBlocker>({}, *description, unblock_flags).was_interrupted())
                 if (Thread::current()->block<Thread::ReadBlocker>({}, *description, unblock_flags).was_interrupted())
                     return EINTR;
                     return EINTR;
-                if (!((u32)unblock_flags & (u32)Thread::FileBlocker::BlockFlags::Read))
+                if (!has_flag(unblock_flags, BlockFlags::Read))
                     return EAGAIN;
                     return EAGAIN;
                 // TODO: handle exceptions in unblock_flags
                 // TODO: handle exceptions in unblock_flags
             }
             }
@@ -102,10 +104,10 @@ KResultOr<ssize_t> Process::sys$read(int fd, Userspace<u8*> buffer, ssize_t size
         return EISDIR;
         return EISDIR;
     if (description->is_blocking()) {
     if (description->is_blocking()) {
         if (!description->can_read()) {
         if (!description->can_read()) {
-            auto unblock_flags = Thread::FileBlocker::BlockFlags::None;
+            auto unblock_flags = BlockFlags::None;
             if (Thread::current()->block<Thread::ReadBlocker>({}, *description, unblock_flags).was_interrupted())
             if (Thread::current()->block<Thread::ReadBlocker>({}, *description, unblock_flags).was_interrupted())
                 return EINTR;
                 return EINTR;
-            if (!((u32)unblock_flags & (u32)Thread::FileBlocker::BlockFlags::Read))
+            if (!has_flag(unblock_flags, BlockFlags::Read))
                 return EAGAIN;
                 return EAGAIN;
             // TODO: handle exceptions in unblock_flags
             // TODO: handle exceptions in unblock_flags
         }
         }

+ 25 - 23
Kernel/Syscalls/select.cpp

@@ -32,6 +32,8 @@
 
 
 namespace Kernel {
 namespace Kernel {
 
 
+using BlockFlags = Thread::FileBlocker::BlockFlags;
+
 KResultOr<int> Process::sys$select(Userspace<const Syscall::SC_select_params*> user_params)
 KResultOr<int> Process::sys$select(Userspace<const Syscall::SC_select_params*> user_params)
 {
 {
     REQUIRE_PROMISE(stdio);
     REQUIRE_PROMISE(stdio);
@@ -76,14 +78,14 @@ KResultOr<int> Process::sys$select(Userspace<const Syscall::SC_select_params*> u
     Thread::SelectBlocker::FDVector fds_info;
     Thread::SelectBlocker::FDVector fds_info;
     Vector<int, FD_SETSIZE> fds;
     Vector<int, FD_SETSIZE> fds;
     for (int fd = 0; fd < params.nfds; fd++) {
     for (int fd = 0; fd < params.nfds; fd++) {
-        u32 block_flags = (u32)Thread::FileBlocker::BlockFlags::None;
+        auto block_flags = BlockFlags::None;
         if (params.readfds && FD_ISSET(fd, &fds_read))
         if (params.readfds && FD_ISSET(fd, &fds_read))
-            block_flags |= (u32)Thread::FileBlocker::BlockFlags::Read;
+            block_flags |= BlockFlags::Read;
         if (params.writefds && FD_ISSET(fd, &fds_write))
         if (params.writefds && FD_ISSET(fd, &fds_write))
-            block_flags |= (u32)Thread::FileBlocker::BlockFlags::Write;
+            block_flags |= BlockFlags::Write;
         if (params.exceptfds && FD_ISSET(fd, &fds_except))
         if (params.exceptfds && FD_ISSET(fd, &fds_except))
-            block_flags |= (u32)Thread::FileBlocker::BlockFlags::Exception;
-        if (block_flags == (u32)Thread::FileBlocker::BlockFlags::None)
+            block_flags |= BlockFlags::Exception;
+        if (block_flags == BlockFlags::None)
             continue;
             continue;
 
 
         auto description = file_description(fd);
         auto description = file_description(fd);
@@ -91,7 +93,7 @@ KResultOr<int> Process::sys$select(Userspace<const Syscall::SC_select_params*> u
             dbgln("sys$select: Bad fd number {}", fd);
             dbgln("sys$select: Bad fd number {}", fd);
             return EBADF;
             return EBADF;
         }
         }
-        fds_info.append({ description.release_nonnull(), (Thread::FileBlocker::BlockFlags)block_flags });
+        fds_info.append({ description.release_nonnull(), block_flags });
         fds.append(fd);
         fds.append(fd);
     }
     }
 
 
@@ -113,17 +115,17 @@ KResultOr<int> Process::sys$select(Userspace<const Syscall::SC_select_params*> u
     int marked_fd_count = 0;
     int marked_fd_count = 0;
     for (size_t i = 0; i < fds_info.size(); i++) {
     for (size_t i = 0; i < fds_info.size(); i++) {
         auto& fd_entry = fds_info[i];
         auto& fd_entry = fds_info[i];
-        if (fd_entry.unblocked_flags == Thread::FileBlocker::BlockFlags::None)
+        if (fd_entry.unblocked_flags == BlockFlags::None)
             continue;
             continue;
-        if (params.readfds && ((u32)fd_entry.unblocked_flags & (u32)Thread::FileBlocker::BlockFlags::Read)) {
+        if (params.readfds && has_flag(fd_entry.unblocked_flags, BlockFlags::Read)) {
             FD_SET(fds[i], &fds_read);
             FD_SET(fds[i], &fds_read);
             marked_fd_count++;
             marked_fd_count++;
         }
         }
-        if (params.writefds && ((u32)fd_entry.unblocked_flags & (u32)Thread::FileBlocker::BlockFlags::Write)) {
+        if (params.writefds && has_flag(fd_entry.unblocked_flags, BlockFlags::Write)) {
             FD_SET(fds[i], &fds_write);
             FD_SET(fds[i], &fds_write);
             marked_fd_count++;
             marked_fd_count++;
         }
         }
-        if (params.exceptfds && ((u32)fd_entry.unblocked_flags & (u32)Thread::FileBlocker::BlockFlags::Exception)) {
+        if (params.exceptfds && has_flag(fd_entry.unblocked_flags, BlockFlags::Exception)) {
             FD_SET(fds[i], &fds_except);
             FD_SET(fds[i], &fds_except);
             marked_fd_count++;
             marked_fd_count++;
         }
         }
@@ -180,14 +182,14 @@ KResultOr<int> Process::sys$poll(Userspace<const Syscall::SC_poll_params*> user_
             dbgln("sys$poll: Bad fd number {}", pfd.fd);
             dbgln("sys$poll: Bad fd number {}", pfd.fd);
             return EBADF;
             return EBADF;
         }
         }
-        u32 block_flags = (u32)Thread::FileBlocker::BlockFlags::Exception; // always want POLLERR, POLLHUP, POLLNVAL
+        BlockFlags block_flags = BlockFlags::Exception; // always want POLLERR, POLLHUP, POLLNVAL
         if (pfd.events & POLLIN)
         if (pfd.events & POLLIN)
-            block_flags |= (u32)Thread::FileBlocker::BlockFlags::Read;
+            block_flags |= BlockFlags::Read;
         if (pfd.events & POLLOUT)
         if (pfd.events & POLLOUT)
-            block_flags |= (u32)Thread::FileBlocker::BlockFlags::Write;
+            block_flags |= BlockFlags::Write;
         if (pfd.events & POLLPRI)
         if (pfd.events & POLLPRI)
-            block_flags |= (u32)Thread::FileBlocker::BlockFlags::ReadPriority;
-        fds_info.append({ description.release_nonnull(), (Thread::FileBlocker::BlockFlags)block_flags });
+            block_flags |= BlockFlags::ReadPriority;
+        fds_info.append({ description.release_nonnull(), block_flags });
     }
     }
 
 
     auto current_thread = Thread::current();
     auto current_thread = Thread::current();
@@ -213,26 +215,26 @@ KResultOr<int> Process::sys$poll(Userspace<const Syscall::SC_poll_params*> user_
         auto& fds_entry = fds_info[i];
         auto& fds_entry = fds_info[i];
 
 
         pfd.revents = 0;
         pfd.revents = 0;
-        if (fds_entry.unblocked_flags == Thread::FileBlocker::BlockFlags::None)
+        if (fds_entry.unblocked_flags == BlockFlags::None)
             continue;
             continue;
 
 
-        if ((u32)fds_entry.unblocked_flags & (u32)Thread::FileBlocker::BlockFlags::Exception) {
-            if ((u32)fds_entry.unblocked_flags & (u32)Thread::FileBlocker::BlockFlags::ReadHangUp)
+        if (has_flag(fds_entry.unblocked_flags, BlockFlags::Exception)) {
+            if (has_flag(fds_entry.unblocked_flags, BlockFlags::ReadHangUp))
                 pfd.revents |= POLLRDHUP;
                 pfd.revents |= POLLRDHUP;
-            if ((u32)fds_entry.unblocked_flags & (u32)Thread::FileBlocker::BlockFlags::WriteError)
+            if (has_flag(fds_entry.unblocked_flags, BlockFlags::WriteError))
                 pfd.revents |= POLLERR;
                 pfd.revents |= POLLERR;
-            if ((u32)fds_entry.unblocked_flags & (u32)Thread::FileBlocker::BlockFlags::WriteHangUp)
+            if (has_flag(fds_entry.unblocked_flags, BlockFlags::WriteHangUp))
                 pfd.revents |= POLLNVAL;
                 pfd.revents |= POLLNVAL;
         } else {
         } else {
-            if ((u32)fds_entry.unblocked_flags & (u32)Thread::FileBlocker::BlockFlags::Read) {
+            if (has_flag(fds_entry.unblocked_flags, BlockFlags::Read)) {
                 VERIFY(pfd.events & POLLIN);
                 VERIFY(pfd.events & POLLIN);
                 pfd.revents |= POLLIN;
                 pfd.revents |= POLLIN;
             }
             }
-            if ((u32)fds_entry.unblocked_flags & (u32)Thread::FileBlocker::BlockFlags::ReadPriority) {
+            if (has_flag(fds_entry.unblocked_flags, BlockFlags::ReadPriority)) {
                 VERIFY(pfd.events & POLLPRI);
                 VERIFY(pfd.events & POLLPRI);
                 pfd.revents |= POLLPRI;
                 pfd.revents |= POLLPRI;
             }
             }
-            if ((u32)fds_entry.unblocked_flags & (u32)Thread::FileBlocker::BlockFlags::Write) {
+            if (has_flag(fds_entry.unblocked_flags, BlockFlags::Write)) {
                 VERIFY(pfd.events & POLLOUT);
                 VERIFY(pfd.events & POLLOUT);
                 pfd.revents |= POLLOUT;
                 pfd.revents |= POLLOUT;
             }
             }

+ 3 - 0
Kernel/Thread.h

@@ -26,6 +26,7 @@
 
 
 #pragma once
 #pragma once
 
 
+#include <AK/EnumBits.h>
 #include <AK/Function.h>
 #include <AK/Function.h>
 #include <AK/HashMap.h>
 #include <AK/HashMap.h>
 #include <AK/IntrusiveList.h>
 #include <AK/IntrusiveList.h>
@@ -1267,6 +1268,8 @@ private:
     void drop_thread_count(bool);
     void drop_thread_count(bool);
 };
 };
 
 
+AK_ENUM_BITWISE_OPERATORS(Thread::FileBlocker::BlockFlags);
+
 template<typename Callback>
 template<typename Callback>
 inline IterationDecision Thread::for_each(Callback callback)
 inline IterationDecision Thread::for_each(Callback callback)
 {
 {

+ 4 - 4
Kernel/ThreadBlockers.cpp

@@ -265,17 +265,17 @@ const FileDescription& Thread::FileDescriptionBlocker::blocked_description() con
 }
 }
 
 
 Thread::AcceptBlocker::AcceptBlocker(FileDescription& description, BlockFlags& unblocked_flags)
 Thread::AcceptBlocker::AcceptBlocker(FileDescription& description, BlockFlags& unblocked_flags)
-    : FileDescriptionBlocker(description, (BlockFlags)((u32)BlockFlags::Accept | (u32)BlockFlags::Exception), unblocked_flags)
+    : FileDescriptionBlocker(description, BlockFlags::Accept | BlockFlags::Exception, unblocked_flags)
 {
 {
 }
 }
 
 
 Thread::ConnectBlocker::ConnectBlocker(FileDescription& description, BlockFlags& unblocked_flags)
 Thread::ConnectBlocker::ConnectBlocker(FileDescription& description, BlockFlags& unblocked_flags)
-    : FileDescriptionBlocker(description, (BlockFlags)((u32)BlockFlags::Connect | (u32)BlockFlags::Exception), unblocked_flags)
+    : FileDescriptionBlocker(description, BlockFlags::Connect | BlockFlags::Exception, unblocked_flags)
 {
 {
 }
 }
 
 
 Thread::WriteBlocker::WriteBlocker(FileDescription& description, BlockFlags& unblocked_flags)
 Thread::WriteBlocker::WriteBlocker(FileDescription& description, BlockFlags& unblocked_flags)
-    : FileDescriptionBlocker(description, (BlockFlags)((u32)BlockFlags::Write | (u32)BlockFlags::Exception), unblocked_flags)
+    : FileDescriptionBlocker(description, BlockFlags::Write | BlockFlags::Exception, unblocked_flags)
 {
 {
 }
 }
 
 
@@ -295,7 +295,7 @@ auto Thread::WriteBlocker::override_timeout(const BlockTimeout& timeout) -> cons
 }
 }
 
 
 Thread::ReadBlocker::ReadBlocker(FileDescription& description, BlockFlags& unblocked_flags)
 Thread::ReadBlocker::ReadBlocker(FileDescription& description, BlockFlags& unblocked_flags)
-    : FileDescriptionBlocker(description, (BlockFlags)((u32)BlockFlags::Read | (u32)BlockFlags::Exception), unblocked_flags)
+    : FileDescriptionBlocker(description, BlockFlags::Read | BlockFlags::Exception, unblocked_flags)
 {
 {
 }
 }