|
@@ -1,8 +1,6 @@
|
|
#pragma once
|
|
#pragma once
|
|
|
|
|
|
#include "types.h"
|
|
#include "types.h"
|
|
-#include "TSS.h"
|
|
|
|
-#include "i386.h"
|
|
|
|
#include "TTY.h"
|
|
#include "TTY.h"
|
|
#include "Syscall.h"
|
|
#include "Syscall.h"
|
|
#include <Kernel/VirtualFileSystem.h>
|
|
#include <Kernel/VirtualFileSystem.h>
|
|
@@ -12,9 +10,9 @@
|
|
#include <AK/Vector.h>
|
|
#include <AK/Vector.h>
|
|
#include <AK/WeakPtr.h>
|
|
#include <AK/WeakPtr.h>
|
|
#include <AK/Weakable.h>
|
|
#include <AK/Weakable.h>
|
|
|
|
+#include <Kernel/Thread.h>
|
|
#include <Kernel/Lock.h>
|
|
#include <Kernel/Lock.h>
|
|
|
|
|
|
-class Alarm;
|
|
|
|
class FileDescriptor;
|
|
class FileDescriptor;
|
|
class PageDirectory;
|
|
class PageDirectory;
|
|
class Region;
|
|
class Region;
|
|
@@ -31,26 +29,11 @@ struct CoolGlobals {
|
|
extern CoolGlobals* g_cool_globals;
|
|
extern CoolGlobals* g_cool_globals;
|
|
#endif
|
|
#endif
|
|
|
|
|
|
-enum class ShouldUnblockProcess { No = 0, Yes };
|
|
|
|
-
|
|
|
|
-struct SignalActionData {
|
|
|
|
- LinearAddress handler_or_sigaction;
|
|
|
|
- dword mask { 0 };
|
|
|
|
- int flags { 0 };
|
|
|
|
- LinearAddress restorer;
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-struct DisplayInfo {
|
|
|
|
- unsigned width;
|
|
|
|
- unsigned height;
|
|
|
|
- unsigned bpp;
|
|
|
|
- unsigned pitch;
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
void kgettimeofday(timeval&);
|
|
void kgettimeofday(timeval&);
|
|
|
|
|
|
class Process : public InlineLinkedListNode<Process>, public Weakable<Process> {
|
|
class Process : public InlineLinkedListNode<Process>, public Weakable<Process> {
|
|
friend class InlineLinkedListNode<Process>;
|
|
friend class InlineLinkedListNode<Process>;
|
|
|
|
+ friend class Thread;
|
|
public:
|
|
public:
|
|
static Process* create_kernel_process(String&& name, void (*entry)());
|
|
static Process* create_kernel_process(String&& name, void (*entry)());
|
|
static Process* create_user_process(const String& path, uid_t, gid_t, pid_t ppid, int& error, Vector<String>&& arguments = Vector<String>(), Vector<String>&& environment = Vector<String>(), TTY* = nullptr);
|
|
static Process* create_user_process(const String& path, uid_t, gid_t, pid_t ppid, int& error, Vector<String>&& arguments = Vector<String>(), Vector<String>&& environment = Vector<String>(), TTY* = nullptr);
|
|
@@ -58,29 +41,6 @@ public:
|
|
|
|
|
|
static Vector<pid_t> all_pids();
|
|
static Vector<pid_t> all_pids();
|
|
static Vector<Process*> all_processes();
|
|
static Vector<Process*> all_processes();
|
|
- static void finalize_dying_processes();
|
|
|
|
-
|
|
|
|
- enum State {
|
|
|
|
- Invalid = 0,
|
|
|
|
- Runnable,
|
|
|
|
- Running,
|
|
|
|
- Skip1SchedulerPass,
|
|
|
|
- Skip0SchedulerPasses,
|
|
|
|
- Dying,
|
|
|
|
- Dead,
|
|
|
|
- Stopped,
|
|
|
|
- BeingInspected,
|
|
|
|
- BlockedLurking,
|
|
|
|
- BlockedSleep,
|
|
|
|
- BlockedWait,
|
|
|
|
- BlockedRead,
|
|
|
|
- BlockedWrite,
|
|
|
|
- BlockedSignal,
|
|
|
|
- BlockedSelect,
|
|
|
|
- BlockedConnect,
|
|
|
|
- BlockedReceive,
|
|
|
|
- BlockedSnoozing,
|
|
|
|
- };
|
|
|
|
|
|
|
|
enum Priority {
|
|
enum Priority {
|
|
LowPriority,
|
|
LowPriority,
|
|
@@ -93,19 +53,20 @@ public:
|
|
Ring3 = 3,
|
|
Ring3 = 3,
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+ // FIXME(Thread): Is this really how this should work?
|
|
|
|
+ bool is_dead() const { return main_thread().state() == Thread::State::Dead; }
|
|
|
|
+
|
|
|
|
+ Thread::State state() const { return main_thread().state(); }
|
|
|
|
+
|
|
|
|
+ Thread& main_thread() { return *m_main_thread; }
|
|
|
|
+ const Thread& main_thread() const { return *m_main_thread; }
|
|
|
|
+
|
|
bool is_ring0() const { return m_ring == Ring0; }
|
|
bool is_ring0() const { return m_ring == Ring0; }
|
|
bool is_ring3() const { return m_ring == Ring3; }
|
|
bool is_ring3() const { return m_ring == Ring3; }
|
|
- bool is_stopped() const { return m_state == Stopped; }
|
|
|
|
- bool is_blocked() const
|
|
|
|
- {
|
|
|
|
- return m_state == BlockedSleep || m_state == BlockedWait || m_state == BlockedRead || m_state == BlockedWrite || m_state == BlockedSignal || m_state == BlockedSelect;
|
|
|
|
- }
|
|
|
|
|
|
|
|
PageDirectory& page_directory() { return *m_page_directory; }
|
|
PageDirectory& page_directory() { return *m_page_directory; }
|
|
const PageDirectory& page_directory() const { return *m_page_directory; }
|
|
const PageDirectory& page_directory() const { return *m_page_directory; }
|
|
|
|
|
|
- bool in_kernel() const { return (m_tss.cs & 0x03) == 0; }
|
|
|
|
-
|
|
|
|
static Process* from_pid(pid_t);
|
|
static Process* from_pid(pid_t);
|
|
|
|
|
|
void set_priority(Priority p) { m_priority = p; }
|
|
void set_priority(Priority p) { m_priority = p; }
|
|
@@ -115,10 +76,6 @@ public:
|
|
pid_t pid() const { return m_pid; }
|
|
pid_t pid() const { return m_pid; }
|
|
pid_t sid() const { return m_sid; }
|
|
pid_t sid() const { return m_sid; }
|
|
pid_t pgid() const { return m_pgid; }
|
|
pid_t pgid() const { return m_pgid; }
|
|
- dword ticks() const { return m_ticks; }
|
|
|
|
- word selector() const { return m_far_ptr.selector; }
|
|
|
|
- TSS32& tss() { return m_tss; }
|
|
|
|
- State state() const { return m_state; }
|
|
|
|
uid_t uid() const { return m_uid; }
|
|
uid_t uid() const { return m_uid; }
|
|
gid_t gid() const { return m_gid; }
|
|
gid_t gid() const { return m_gid; }
|
|
const HashTable<gid_t>& gids() const { return m_gids; }
|
|
const HashTable<gid_t>& gids() const { return m_gids; }
|
|
@@ -130,34 +87,14 @@ public:
|
|
|
|
|
|
bool in_group(gid_t) const;
|
|
bool in_group(gid_t) const;
|
|
|
|
|
|
- const FarPtr& far_ptr() const { return m_far_ptr; }
|
|
|
|
-
|
|
|
|
FileDescriptor* file_descriptor(int fd);
|
|
FileDescriptor* file_descriptor(int fd);
|
|
const FileDescriptor* file_descriptor(int fd) const;
|
|
const FileDescriptor* file_descriptor(int fd) const;
|
|
|
|
|
|
- void block(Process::State);
|
|
|
|
- void unblock();
|
|
|
|
-
|
|
|
|
- void set_wakeup_time(dword t) { m_wakeup_time = t; }
|
|
|
|
- dword wakeup_time() const { return m_wakeup_time; }
|
|
|
|
-
|
|
|
|
- void snooze_until(Alarm&);
|
|
|
|
-
|
|
|
|
template<typename Callback> static void for_each(Callback);
|
|
template<typename Callback> static void for_each(Callback);
|
|
template<typename Callback> static void for_each_in_pgrp(pid_t, Callback);
|
|
template<typename Callback> static void for_each_in_pgrp(pid_t, Callback);
|
|
- template<typename Callback> static void for_each_in_state(State, Callback);
|
|
|
|
- template<typename Callback> static void for_each_living(Callback);
|
|
|
|
template<typename Callback> void for_each_child(Callback);
|
|
template<typename Callback> void for_each_child(Callback);
|
|
|
|
+ template<typename Callback> void for_each_thread(Callback) const;
|
|
|
|
|
|
- bool tick();
|
|
|
|
- void set_ticks_left(dword t) { m_ticks_left = t; }
|
|
|
|
- dword ticks_left() const { return m_ticks_left; }
|
|
|
|
-
|
|
|
|
- dword kernel_stack_base() const { return (dword)m_kernel_stack; };
|
|
|
|
- dword kernel_stack_for_signal_handler_base() const { return (dword)m_kernel_stack_for_signal_handler; };
|
|
|
|
-
|
|
|
|
- void set_selector(word s) { m_far_ptr.selector = s; }
|
|
|
|
- void set_state(State s) { m_state = s; }
|
|
|
|
void die();
|
|
void die();
|
|
void finalize();
|
|
void finalize();
|
|
|
|
|
|
@@ -182,7 +119,6 @@ public:
|
|
int sys$stat(const char*, stat*);
|
|
int sys$stat(const char*, stat*);
|
|
int sys$lseek(int fd, off_t, int whence);
|
|
int sys$lseek(int fd, off_t, int whence);
|
|
int sys$kill(pid_t pid, int sig);
|
|
int sys$kill(pid_t pid, int sig);
|
|
- int sys$geterror() { return m_error; }
|
|
|
|
[[noreturn]] void sys$exit(int status);
|
|
[[noreturn]] void sys$exit(int status);
|
|
[[noreturn]] void sys$sigreturn();
|
|
[[noreturn]] void sys$sigreturn();
|
|
pid_t sys$waitpid(pid_t, int* wstatus, int options);
|
|
pid_t sys$waitpid(pid_t, int* wstatus, int options);
|
|
@@ -249,8 +185,6 @@ public:
|
|
int sys$seal_shared_buffer(int shared_buffer_id);
|
|
int sys$seal_shared_buffer(int shared_buffer_id);
|
|
int sys$get_shared_buffer_size(int shared_buffer_id);
|
|
int sys$get_shared_buffer_size(int shared_buffer_id);
|
|
|
|
|
|
- KResult wait_for_connect(Socket&);
|
|
|
|
-
|
|
|
|
static void initialize();
|
|
static void initialize();
|
|
|
|
|
|
[[noreturn]] void crash();
|
|
[[noreturn]] void crash();
|
|
@@ -263,21 +197,12 @@ public:
|
|
const Vector<Retained<Region>>& regions() const { return m_regions; }
|
|
const Vector<Retained<Region>>& regions() const { return m_regions; }
|
|
void dump_regions();
|
|
void dump_regions();
|
|
|
|
|
|
- void did_schedule() { ++m_times_scheduled; }
|
|
|
|
- dword times_scheduled() const { return m_times_scheduled; }
|
|
|
|
-
|
|
|
|
dword m_ticks_in_user { 0 };
|
|
dword m_ticks_in_user { 0 };
|
|
dword m_ticks_in_kernel { 0 };
|
|
dword m_ticks_in_kernel { 0 };
|
|
|
|
|
|
dword m_ticks_in_user_for_dead_children { 0 };
|
|
dword m_ticks_in_user_for_dead_children { 0 };
|
|
dword m_ticks_in_kernel_for_dead_children { 0 };
|
|
dword m_ticks_in_kernel_for_dead_children { 0 };
|
|
|
|
|
|
- pid_t waitee_pid() const { return m_waitee_pid; }
|
|
|
|
-
|
|
|
|
- dword frame_ptr() const { return m_tss.ebp; }
|
|
|
|
- dword stack_ptr() const { return m_tss.esp; }
|
|
|
|
- dword stack_top() const { return m_tss.ss == 0x10 ? m_stack_top0 : m_stack_top3; }
|
|
|
|
-
|
|
|
|
bool validate_read_from_kernel(LinearAddress) const;
|
|
bool validate_read_from_kernel(LinearAddress) const;
|
|
|
|
|
|
bool validate_read(const void*, ssize_t) const;
|
|
bool validate_read(const void*, ssize_t) const;
|
|
@@ -292,13 +217,6 @@ public:
|
|
int number_of_open_file_descriptors() const;
|
|
int number_of_open_file_descriptors() const;
|
|
int max_open_file_descriptors() const { return m_max_open_file_descriptors; }
|
|
int max_open_file_descriptors() const { return m_max_open_file_descriptors; }
|
|
|
|
|
|
- void send_signal(byte signal, Process* sender);
|
|
|
|
-
|
|
|
|
- ShouldUnblockProcess dispatch_one_pending_signal();
|
|
|
|
- ShouldUnblockProcess dispatch_signal(byte signal);
|
|
|
|
- bool has_unmasked_pending_signals() const;
|
|
|
|
- void terminate_due_to_signal(byte signal);
|
|
|
|
-
|
|
|
|
size_t amount_virtual() const;
|
|
size_t amount_virtual() const;
|
|
size_t amount_resident() const;
|
|
size_t amount_resident() const;
|
|
size_t amount_shared() const;
|
|
size_t amount_shared() const;
|
|
@@ -308,16 +226,18 @@ public:
|
|
|
|
|
|
bool is_superuser() const { return m_euid == 0; }
|
|
bool is_superuser() const { return m_euid == 0; }
|
|
|
|
|
|
- FPUState& fpu_state() { return m_fpu_state; }
|
|
|
|
- bool has_used_fpu() const { return m_has_used_fpu; }
|
|
|
|
- void set_has_used_fpu(bool b) { m_has_used_fpu = b; }
|
|
|
|
-
|
|
|
|
Region* allocate_region_with_vmo(LinearAddress, size_t, Retained<VMObject>&&, size_t offset_in_vmo, String&& name, bool is_readable, bool is_writable);
|
|
Region* allocate_region_with_vmo(LinearAddress, size_t, Retained<VMObject>&&, size_t offset_in_vmo, String&& name, bool is_readable, bool is_writable);
|
|
Region* allocate_file_backed_region(LinearAddress, size_t, RetainPtr<Inode>&&, String&& name, bool is_readable, bool is_writable);
|
|
Region* allocate_file_backed_region(LinearAddress, size_t, RetainPtr<Inode>&&, String&& name, bool is_readable, bool is_writable);
|
|
Region* allocate_region(LinearAddress, size_t, String&& name, bool is_readable = true, bool is_writable = true, bool commit = true);
|
|
Region* allocate_region(LinearAddress, size_t, String&& name, bool is_readable = true, bool is_writable = true, bool commit = true);
|
|
bool deallocate_region(Region& region);
|
|
bool deallocate_region(Region& region);
|
|
|
|
|
|
- void set_blocked_socket(Socket* socket) { m_blocked_socket = socket; }
|
|
|
|
|
|
+ void set_being_inspected(bool b) { m_being_inspected = b; }
|
|
|
|
+ bool is_being_inspected() const { return m_being_inspected; }
|
|
|
|
+
|
|
|
|
+ void terminate_due_to_signal(byte signal);
|
|
|
|
+ void send_signal(byte, Process* sender);
|
|
|
|
+
|
|
|
|
+ int thread_count() const;
|
|
|
|
|
|
private:
|
|
private:
|
|
friend class MemoryManager;
|
|
friend class MemoryManager;
|
|
@@ -327,22 +247,21 @@ private:
|
|
Process(String&& name, uid_t, gid_t, pid_t ppid, RingLevel, RetainPtr<Inode>&& cwd = nullptr, RetainPtr<Inode>&& executable = nullptr, TTY* = nullptr, Process* fork_parent = nullptr);
|
|
Process(String&& name, uid_t, gid_t, pid_t ppid, RingLevel, RetainPtr<Inode>&& cwd = nullptr, RetainPtr<Inode>&& executable = nullptr, TTY* = nullptr, Process* fork_parent = nullptr);
|
|
|
|
|
|
int do_exec(String path, Vector<String> arguments, Vector<String> environment);
|
|
int do_exec(String path, Vector<String> arguments, Vector<String> environment);
|
|
- void push_value_on_stack(dword);
|
|
|
|
- void make_userspace_stack(Vector<String> arguments, Vector<String> environment);
|
|
|
|
|
|
|
|
int alloc_fd();
|
|
int alloc_fd();
|
|
- void set_default_signal_dispositions();
|
|
|
|
void disown_all_shared_buffers();
|
|
void disown_all_shared_buffers();
|
|
|
|
|
|
void create_signal_trampolines_if_needed();
|
|
void create_signal_trampolines_if_needed();
|
|
|
|
|
|
|
|
+ Thread* m_main_thread { nullptr };
|
|
|
|
+
|
|
RetainPtr<PageDirectory> m_page_directory;
|
|
RetainPtr<PageDirectory> m_page_directory;
|
|
|
|
|
|
Process* m_prev { nullptr };
|
|
Process* m_prev { nullptr };
|
|
Process* m_next { nullptr };
|
|
Process* m_next { nullptr };
|
|
|
|
|
|
String m_name;
|
|
String m_name;
|
|
- void (*m_entry)() { nullptr };
|
|
|
|
|
|
+
|
|
pid_t m_pid { 0 };
|
|
pid_t m_pid { 0 };
|
|
uid_t m_uid { 0 };
|
|
uid_t m_uid { 0 };
|
|
gid_t m_gid { 0 };
|
|
gid_t m_gid { 0 };
|
|
@@ -350,17 +269,9 @@ private:
|
|
gid_t m_egid { 0 };
|
|
gid_t m_egid { 0 };
|
|
pid_t m_sid { 0 };
|
|
pid_t m_sid { 0 };
|
|
pid_t m_pgid { 0 };
|
|
pid_t m_pgid { 0 };
|
|
- dword m_ticks { 0 };
|
|
|
|
- dword m_ticks_left { 0 };
|
|
|
|
- dword m_stack_top0 { 0 };
|
|
|
|
- dword m_stack_top3 { 0 };
|
|
|
|
- FarPtr m_far_ptr;
|
|
|
|
- State m_state { Invalid };
|
|
|
|
|
|
+
|
|
Priority m_priority { NormalPriority };
|
|
Priority m_priority { NormalPriority };
|
|
- dword m_wakeup_time { 0 };
|
|
|
|
- TSS32 m_tss;
|
|
|
|
- TSS32 m_tss_to_resume_kernel;
|
|
|
|
- FPUState m_fpu_state;
|
|
|
|
|
|
+
|
|
struct FileDescriptorAndFlags {
|
|
struct FileDescriptorAndFlags {
|
|
operator bool() const { return !!descriptor; }
|
|
operator bool() const { return !!descriptor; }
|
|
void clear() { descriptor = nullptr; flags = 0; }
|
|
void clear() { descriptor = nullptr; flags = 0; }
|
|
@@ -370,23 +281,8 @@ private:
|
|
};
|
|
};
|
|
Vector<FileDescriptorAndFlags> m_fds;
|
|
Vector<FileDescriptorAndFlags> m_fds;
|
|
RingLevel m_ring { Ring0 };
|
|
RingLevel m_ring { Ring0 };
|
|
- int m_error { 0 };
|
|
|
|
- void* m_kernel_stack { nullptr };
|
|
|
|
- void* m_kernel_stack_for_signal_handler { nullptr };
|
|
|
|
- dword m_times_scheduled { 0 };
|
|
|
|
- pid_t m_waitee_pid { -1 };
|
|
|
|
- int m_blocked_fd { -1 };
|
|
|
|
- Vector<int> m_select_read_fds;
|
|
|
|
- Vector<int> m_select_write_fds;
|
|
|
|
- Vector<int> m_select_exceptional_fds;
|
|
|
|
- timeval m_select_timeout;
|
|
|
|
- bool m_select_has_timeout { false };
|
|
|
|
|
|
+
|
|
int m_max_open_file_descriptors { 16 };
|
|
int m_max_open_file_descriptors { 16 };
|
|
- SignalActionData m_signal_action_data[32];
|
|
|
|
- dword m_pending_signals { 0 };
|
|
|
|
- dword m_signal_mask { 0 };
|
|
|
|
- RetainPtr<Socket> m_blocked_socket;
|
|
|
|
- Alarm* m_snoozing_alarm { nullptr };
|
|
|
|
|
|
|
|
byte m_termination_status { 0 };
|
|
byte m_termination_status { 0 };
|
|
byte m_termination_signal { 0 };
|
|
byte m_termination_signal { 0 };
|
|
@@ -409,34 +305,28 @@ private:
|
|
pid_t m_ppid { 0 };
|
|
pid_t m_ppid { 0 };
|
|
mode_t m_umask { 022 };
|
|
mode_t m_umask { 022 };
|
|
|
|
|
|
- bool m_was_interrupted_while_blocked { false };
|
|
|
|
-
|
|
|
|
static void notify_waiters(pid_t waitee, int exit_status, int signal);
|
|
static void notify_waiters(pid_t waitee, int exit_status, int signal);
|
|
|
|
|
|
HashTable<gid_t> m_gids;
|
|
HashTable<gid_t> m_gids;
|
|
|
|
|
|
- Region* m_signal_stack_user_region { nullptr };
|
|
|
|
|
|
+ bool m_being_inspected { false };
|
|
|
|
|
|
- RetainPtr<Region> m_display_framebuffer_region;
|
|
|
|
-
|
|
|
|
- bool m_has_used_fpu { false };
|
|
|
|
|
|
+ int m_next_tid { 0 };
|
|
};
|
|
};
|
|
|
|
|
|
-extern Process* current;
|
|
|
|
-
|
|
|
|
class ProcessInspectionHandle {
|
|
class ProcessInspectionHandle {
|
|
public:
|
|
public:
|
|
ProcessInspectionHandle(Process& process)
|
|
ProcessInspectionHandle(Process& process)
|
|
: m_process(process)
|
|
: m_process(process)
|
|
- , m_original_state(process.state())
|
|
|
|
{
|
|
{
|
|
- if (&process != current)
|
|
|
|
- m_process.set_state(Process::BeingInspected);
|
|
|
|
|
|
+ if (&process != ¤t->process()) {
|
|
|
|
+ ASSERT(!m_process.is_being_inspected());
|
|
|
|
+ m_process.set_being_inspected(true);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
-
|
|
|
|
~ProcessInspectionHandle()
|
|
~ProcessInspectionHandle()
|
|
{
|
|
{
|
|
- m_process.set_state(m_original_state);
|
|
|
|
|
|
+ m_process.set_being_inspected(false);
|
|
}
|
|
}
|
|
|
|
|
|
Process& process() { return m_process; }
|
|
Process& process() { return m_process; }
|
|
@@ -454,15 +344,10 @@ public:
|
|
Process& operator*() { return m_process; }
|
|
Process& operator*() { return m_process; }
|
|
private:
|
|
private:
|
|
Process& m_process;
|
|
Process& m_process;
|
|
- Process::State m_original_state { Process::Invalid };
|
|
|
|
};
|
|
};
|
|
|
|
|
|
-extern const char* to_string(Process::State);
|
|
|
|
extern const char* to_string(Process::Priority);
|
|
extern const char* to_string(Process::Priority);
|
|
|
|
|
|
-extern void block(Process::State);
|
|
|
|
-extern void sleep(dword ticks);
|
|
|
|
-
|
|
|
|
extern InlineLinkedList<Process>* g_processes;
|
|
extern InlineLinkedList<Process>* g_processes;
|
|
|
|
|
|
template<typename Callback>
|
|
template<typename Callback>
|
|
@@ -493,39 +378,30 @@ inline void Process::for_each_child(Callback callback)
|
|
}
|
|
}
|
|
|
|
|
|
template<typename Callback>
|
|
template<typename Callback>
|
|
-inline void Process::for_each_in_pgrp(pid_t pgid, Callback callback)
|
|
|
|
|
|
+inline void Process::for_each_thread(Callback callback) const
|
|
{
|
|
{
|
|
- ASSERT_INTERRUPTS_DISABLED();
|
|
|
|
- for (auto* process = g_processes->head(); process;) {
|
|
|
|
- auto* next_process = process->next();
|
|
|
|
- if (process->pgid() == pgid) {
|
|
|
|
- if (!callback(*process))
|
|
|
|
|
|
+ InterruptDisabler disabler;
|
|
|
|
+ pid_t my_pid = pid();
|
|
|
|
+ for (auto* thread = g_threads->head(); thread;) {
|
|
|
|
+ auto* next_thread = thread->next();
|
|
|
|
+ if (thread->pid() == my_pid) {
|
|
|
|
+ if (callback(*thread) == IterationDecision::Abort)
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
- process = next_process;
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-template<typename Callback>
|
|
|
|
-inline void Process::for_each_in_state(State state, Callback callback)
|
|
|
|
-{
|
|
|
|
- ASSERT_INTERRUPTS_DISABLED();
|
|
|
|
- for (auto* process = g_processes->head(); process;) {
|
|
|
|
- auto* next_process = process->next();
|
|
|
|
- if (process->state() == state)
|
|
|
|
- callback(*process);
|
|
|
|
- process = next_process;
|
|
|
|
|
|
+ thread = next_thread;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
template<typename Callback>
|
|
template<typename Callback>
|
|
-inline void Process::for_each_living(Callback callback)
|
|
|
|
|
|
+inline void Process::for_each_in_pgrp(pid_t pgid, Callback callback)
|
|
{
|
|
{
|
|
ASSERT_INTERRUPTS_DISABLED();
|
|
ASSERT_INTERRUPTS_DISABLED();
|
|
for (auto* process = g_processes->head(); process;) {
|
|
for (auto* process = g_processes->head(); process;) {
|
|
auto* next_process = process->next();
|
|
auto* next_process = process->next();
|
|
- if (process->state() != Process::Dead && process->state() != Process::Dying)
|
|
|
|
- callback(*process);
|
|
|
|
|
|
+ if (process->pgid() == pgid) {
|
|
|
|
+ if (!callback(*process))
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
process = next_process;
|
|
process = next_process;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -544,3 +420,8 @@ inline bool InodeMetadata::may_execute(Process& process) const
|
|
{
|
|
{
|
|
return may_execute(process.euid(), process.gids());
|
|
return may_execute(process.euid(), process.gids());
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+inline int Thread::pid() const
|
|
|
|
+{
|
|
|
|
+ return m_process.pid();
|
|
|
|
+}
|