diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-07-29 07:26:01 +0200 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-07-29 07:26:01 +0200 |
commit | 5ded77df39e816f565b26761624893d085ca6eef (patch) | |
tree | b840f17e0038d3e8e09f5e530a6b3af3c1d802ac /Kernel | |
parent | 7356fd389f4e73f98f3c28b91830189fea109b5b (diff) | |
download | serenity-5ded77df39e816f565b26761624893d085ca6eef.zip |
Kernel+ProcessManager: Let processes have an icon and show it in the table.
Processes can now have an icon assigned, which is essentially a 16x16 RGBA32
bitmap exposed as a shared buffer ID.
You set the icon ID by calling set_process_icon(int) and the icon ID will be
exposed through /proc/all.
To make this work, I added a mechanism for making shared buffers globally
accessible. For safety reasons, each app seals the icon buffer before making
it global.
Right now the first call to GWindow::set_icon() is what determines the
process icon. We'll probably change this in the future. :^)
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/FileSystem/ProcFS.cpp | 1 | ||||
-rw-r--r-- | Kernel/Process.cpp | 26 | ||||
-rw-r--r-- | Kernel/Process.h | 7 | ||||
-rw-r--r-- | Kernel/SharedBuffer.cpp | 17 | ||||
-rw-r--r-- | Kernel/SharedBuffer.h | 3 | ||||
-rw-r--r-- | Kernel/Syscall.cpp | 4 | ||||
-rw-r--r-- | Kernel/Syscall.h | 4 |
7 files changed, 60 insertions, 2 deletions
diff --git a/Kernel/FileSystem/ProcFS.cpp b/Kernel/FileSystem/ProcFS.cpp index b1ea7d9491..5041fd10c9 100644 --- a/Kernel/FileSystem/ProcFS.cpp +++ b/Kernel/FileSystem/ProcFS.cpp @@ -548,6 +548,7 @@ ByteBuffer procfs$all(InodeIdentifier) process_object.set("ticks", process.main_thread().ticks()); process_object.set("priority", to_string(process.priority())); process_object.set("syscall_count", process.syscall_count()); + process_object.set("icon_id", process.icon_id()); array.append(process_object); }; build_process(*Scheduler::colonel()); diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index ef8803a85e..a4d1b41644 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -2452,6 +2452,19 @@ int Process::sys$share_buffer_with(int shared_buffer_id, pid_t peer_pid) return 0; } +int Process::sys$share_buffer_globally(int shared_buffer_id) +{ + LOCKER(shared_buffers().lock()); + auto it = shared_buffers().resource().find(shared_buffer_id); + if (it == shared_buffers().resource().end()) + return -EINVAL; + auto& shared_buffer = *(*it).value; + if (!shared_buffer.is_shared_with(m_pid)) + return -EPERM; + shared_buffer.share_globally(); + return 0; +} + int Process::sys$release_shared_buffer(int shared_buffer_id) { LOCKER(shared_buffers().lock()); @@ -2773,3 +2786,16 @@ String Process::backtrace(ProcessInspectionHandle& handle) const }); return builder.to_string(); } + +int Process::sys$set_process_icon(int icon_id) +{ + LOCKER(shared_buffers().lock()); + auto it = shared_buffers().resource().find(icon_id); + if (it == shared_buffers().resource().end()) + return -EINVAL; + auto& shared_buffer = *(*it).value; + if (!shared_buffer.is_shared_with(m_pid)) + return -EPERM; + m_icon_id = icon_id; + return 0; +} diff --git a/Kernel/Process.h b/Kernel/Process.h index 7f38cb5e71..e114bc0cbf 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -22,6 +22,7 @@ class PageDirectory; class Region; class VMObject; class ProcessTracer; +class SharedBuffer; timeval kgettimeofday(); void kgettimeofday(timeval&); @@ -208,12 +209,14 @@ public: int sys$mknod(const char* pathname, mode_t, dev_t); int sys$create_shared_buffer(int, void** buffer); int sys$share_buffer_with(int, pid_t peer_pid); + int sys$share_buffer_globally(int); void* sys$get_shared_buffer(int shared_buffer_id); int sys$release_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$halt(); int sys$reboot(); + int sys$set_process_icon(int icon_id); static void initialize(); @@ -281,6 +284,8 @@ public: const ELFLoader* elf_loader() const { return m_elf_loader.ptr(); } + int icon_id() const { return m_icon_id; } + private: friend class MemoryManager; friend class Scheduler; @@ -359,6 +364,8 @@ private: Lock m_big_lock { "Process" }; u64 m_alarm_deadline { 0 }; + + int m_icon_id { -1 }; }; class ProcessInspectionHandle { diff --git a/Kernel/SharedBuffer.cpp b/Kernel/SharedBuffer.cpp index 29665e3bc9..5753a2a6b3 100644 --- a/Kernel/SharedBuffer.cpp +++ b/Kernel/SharedBuffer.cpp @@ -1,5 +1,5 @@ -#include <Kernel/SharedBuffer.h> #include <Kernel/Process.h> +#include <Kernel/SharedBuffer.h> Lockable<HashMap<int, NonnullOwnPtr<SharedBuffer>>>& shared_buffers() { @@ -29,6 +29,8 @@ void SharedBuffer::sanity_check(const char* what) bool SharedBuffer::is_shared_with(pid_t peer_pid) { LOCKER(shared_buffers().lock()); + if (m_global) + return true; for (auto& ref : m_refs) { if (ref.pid == peer_pid) { return true; @@ -42,6 +44,18 @@ void* SharedBuffer::ref_for_process_and_get_address(Process& process) { LOCKER(shared_buffers().lock()); ASSERT(is_shared_with(process.pid())); + if (m_global) { + bool found = false; + for (auto& ref : m_refs) { + if (ref.pid == process.pid()) { + found = true; + break; + } + } + if (!found) + m_refs.append(Reference(process.pid())); + } + for (auto& ref : m_refs) { if (ref.pid == process.pid()) { ref.count++; @@ -93,6 +107,7 @@ void SharedBuffer::deref_for_process(Process& process) destroy_if_unused(); return; } + return; } } diff --git a/Kernel/SharedBuffer.h b/Kernel/SharedBuffer.h index e779186892..bd2751471d 100644 --- a/Kernel/SharedBuffer.h +++ b/Kernel/SharedBuffer.h @@ -36,14 +36,17 @@ public: bool is_shared_with(pid_t peer_pid); void* ref_for_process_and_get_address(Process& process); void share_with(pid_t peer_pid); + void share_globally() { m_global = true; } void deref_for_process(Process& process); void disown(pid_t pid); size_t size() const { return m_vmo->size(); } void destroy_if_unused(); void seal(); + int id() const { return m_shared_buffer_id; } int m_shared_buffer_id { -1 }; bool m_writable { true }; + bool m_global { false }; NonnullRefPtr<VMObject> m_vmo; Vector<Reference, 2> m_refs; unsigned m_total_refs { 0 }; diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp index 43db79393e..432a593bba 100644 --- a/Kernel/Syscall.cpp +++ b/Kernel/Syscall.cpp @@ -299,6 +299,10 @@ static u32 handle(RegisterDump& regs, u32 function, u32 arg1, u32 arg2, u32 arg3 return current->process().sys$dump_backtrace(); case Syscall::SC_watch_file: return current->process().sys$watch_file((const char*)arg1, (int)arg2); + case Syscall::SC_share_buffer_globally: + return current->process().sys$share_buffer_globally((int)arg1); + case Syscall::SC_set_process_icon: + return current->process().sys$set_process_icon((int)arg1); default: kprintf("<%u> int0x82: Unknown function %u requested {%x, %x, %x}\n", current->process().pid(), function, arg1, arg2, arg3); return -ENOSYS; diff --git a/Kernel/Syscall.h b/Kernel/Syscall.h index b45343964f..44ba85cd88 100644 --- a/Kernel/Syscall.h +++ b/Kernel/Syscall.h @@ -119,7 +119,9 @@ struct timeval; __ENUMERATE_SYSCALL(dump_backtrace) \ __ENUMERATE_SYSCALL(dbgputch) \ __ENUMERATE_SYSCALL(dbgputstr) \ - __ENUMERATE_SYSCALL(watch_file) + __ENUMERATE_SYSCALL(watch_file) \ + __ENUMERATE_SYSCALL(share_buffer_globally) \ + __ENUMERATE_SYSCALL(set_process_icon) namespace Syscall { |