Bläddra i källkod

Kernel: Add support for recv() with MSG_DONTWAIT.

Passing this flag to recv() temporarily puts the file descriptor into
non-blocking mode.

Also implement LocalSocket::recv() as a simple forwarding to read().
Andreas Kling 6 år sedan
förälder
incheckning
b3a1671f1a
5 ändrade filer med 23 tillägg och 7 borttagningar
  1. 2 2
      Kernel/Net/LocalSocket.cpp
  2. 10 2
      Kernel/Process.cpp
  3. 7 3
      Kernel/Scheduler.cpp
  4. 2 0
      Kernel/UnixTypes.h
  5. 2 0
      LibC/sys/socket.h

+ 2 - 2
Kernel/Net/LocalSocket.cpp

@@ -204,7 +204,7 @@ ssize_t LocalSocket::sendto(FileDescriptor&, const void*, size_t, int, const soc
     ASSERT_NOT_REACHED();
 }
 
-ssize_t LocalSocket::recvfrom(FileDescriptor&, void*, size_t, int flags, sockaddr*, socklen_t*)
+ssize_t LocalSocket::recvfrom(FileDescriptor& descriptor, void* buffer, size_t buffer_size, int, sockaddr*, socklen_t*)
 {
-    ASSERT_NOT_REACHED();
+    return read(descriptor, (byte*)buffer, buffer_size);
 }

+ 10 - 2
Kernel/Process.cpp

@@ -2213,8 +2213,16 @@ ssize_t Process::sys$recvfrom(const Syscall::SC_recvfrom_params* params)
     if (!descriptor->is_socket())
         return -ENOTSOCK;
     auto& socket = *descriptor->socket();
-    kprintf("recvfrom %p (%u), flags=%u, addr: %p (%p)\n", buffer, buffer_length, flags, addr, addr_length);
-    return socket.recvfrom(*descriptor, buffer, buffer_length, flags, addr, addr_length);
+
+    bool original_blocking = descriptor->is_blocking();
+    if (flags & MSG_DONTWAIT)
+        descriptor->set_blocking(false);
+
+    auto nrecv = socket.recvfrom(*descriptor, buffer, buffer_length, flags, addr, addr_length);
+    if (flags & MSG_DONTWAIT)
+        descriptor->set_blocking(original_blocking);
+
+    return nrecv;
 }
 
 int Process::sys$getsockname(int sockfd, sockaddr* addr, socklen_t* addrlen)

+ 7 - 3
Kernel/Scheduler.cpp

@@ -223,10 +223,14 @@ bool Scheduler::pick_next()
     });
 
 #ifdef SCHEDULER_DEBUG
-    dbgprintf("Scheduler choices: (runnable threads: %p)\n", g_runnable_threads);
+    dbgprintf("Non-runnables:\n");
+    for (auto* thread = g_nonrunnable_threads->head(); thread; thread = thread->next()) {
+        auto* process = &thread->process();
+        dbgprintf("[K%x] % 12s %s(%u:%u) @ %w:%x\n", process, to_string(thread->state()), process->name().characters(), process->pid(), thread->tid(), thread->tss().cs, thread->tss().eip);
+    }
+
+    dbgprintf("Runnables:\n");
     for (auto* thread = g_runnable_threads->head(); thread; thread = thread->next()) {
-        //if (process->state() == Thread::BlockedWait || process->state() == Thread::BlockedSleep)
-//            continue;
         auto* process = &thread->process();
         dbgprintf("[K%x] % 12s %s(%u:%u) @ %w:%x\n", process, to_string(thread->state()), process->name().characters(), process->pid(), thread->tid(), thread->tss().cs, thread->tss().eip);
     }

+ 2 - 0
Kernel/UnixTypes.h

@@ -329,6 +329,8 @@ struct pollfd {
 #define SOCK_NONBLOCK 04000
 #define SOCK_CLOEXEC 02000000
 
+#define MSG_DONTWAIT 0x40
+
 #define SOL_SOCKET 1
 
 #define SO_RCVTIMEO 1

+ 2 - 0
LibC/sys/socket.h

@@ -26,6 +26,8 @@ __BEGIN_DECLS
 #define IPPROTO_TCP 6
 #define IPPROTO_UDP 17
 
+#define MSG_DONTWAIT 0x40
+
 struct sockaddr {
     uint16_t sa_family;
     char sa_data[14];