Kaynağa Gözat

Kernel: Rename Thread::clone() => try_clone() and propagate errors

Andreas Kling 3 yıl önce
ebeveyn
işleme
5d5a3708c4
3 değiştirilmiş dosya ile 20 ekleme ve 18 silme
  1. 16 10
      Kernel/Process.cpp
  2. 3 7
      Kernel/Thread.cpp
  3. 1 1
      Kernel/Thread.h

+ 16 - 10
Kernel/Process.cpp

@@ -275,17 +275,23 @@ Process::Process(const String& name, UserID uid, GroupID gid, ProcessID ppid, bo
 KResult Process::attach_resources(NonnullOwnPtr<Memory::AddressSpace>&& preallocated_space, RefPtr<Thread>& first_thread, Process* fork_parent)
 {
     m_space = move(preallocated_space);
-    if (fork_parent) {
-        // NOTE: fork() doesn't clone all threads; the thread that called fork() becomes the only thread in the new process.
-        first_thread = Thread::current()->clone(*this);
-        if (!first_thread)
-            return ENOMEM;
-    } else {
+
+    auto thread_or_error = [&] {
+        if (fork_parent) {
+            // NOTE: fork() doesn't clone all threads; the thread that called fork() becomes the only thread in the new process.
+            return Thread::current()->try_clone(*this);
+        }
         // NOTE: This non-forked code path is only taken when the kernel creates a process "manually" (at boot.)
-        auto thread_or_error = Thread::try_create(*this);
-        if (thread_or_error.is_error())
-            return thread_or_error.error();
-        first_thread = thread_or_error.release_value();
+        return Thread::try_create(*this);
+    }();
+
+    if (thread_or_error.is_error())
+        return thread_or_error.error();
+
+    first_thread = thread_or_error.release_value();
+
+    if (!fork_parent) {
+        // FIXME: Figure out if this is really necessary.
         first_thread->detach();
     }
     return KSuccess;

+ 3 - 7
Kernel/Thread.cpp

@@ -50,11 +50,7 @@ KResultOr<NonnullRefPtr<Thread>> Thread::try_create(NonnullRefPtr<Process> proce
 
     auto name = KString::try_create(process->name());
 
-    auto thread = adopt_ref_if_nonnull(new (nothrow) Thread(move(process), kernel_stack_region.release_nonnull(), block_timer.release_nonnull(), move(name)));
-    if (!thread)
-        return ENOMEM;
-
-    return thread.release_nonnull();
+    return adopt_nonnull_ref_or_enomem(new (nothrow) Thread(move(process), kernel_stack_region.release_nonnull(), block_timer.release_nonnull(), move(name)));
 }
 
 Thread::Thread(NonnullRefPtr<Process> process, NonnullOwnPtr<Memory::Region> kernel_stack_region, NonnullRefPtr<Timer> block_timer, OwnPtr<KString> name)
@@ -1030,11 +1026,11 @@ RegisterState& Thread::get_register_dump_from_stack()
     return *trap->regs;
 }
 
-RefPtr<Thread> Thread::clone(Process& process)
+KResultOr<NonnullRefPtr<Thread>> Thread::try_clone(Process& process)
 {
     auto thread_or_error = Thread::try_create(process);
     if (thread_or_error.is_error())
-        return {};
+        return thread_or_error.error();
     auto& clone = thread_or_error.value();
     auto signal_action_data_span = m_signal_action_data.span();
     signal_action_data_span.copy_to(clone->m_signal_action_data.span());

+ 1 - 1
Kernel/Thread.h

@@ -1101,7 +1101,7 @@ public:
         return !m_is_joinable;
     }
 
-    RefPtr<Thread> clone(Process&);
+    KResultOr<NonnullRefPtr<Thread>> try_clone(Process&);
 
     template<IteratorFunction<Thread&> Callback>
     static IterationDecision for_each_in_state(State, Callback);