1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 06:37:35 +00:00

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. :^)
This commit is contained in:
Andreas Kling 2019-07-29 07:26:01 +02:00
parent 7356fd389f
commit 5ded77df39
14 changed files with 97 additions and 2 deletions

View file

@ -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());

View file

@ -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;
}

View file

@ -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 {

View file

@ -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;
}
}

View file

@ -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 };

View file

@ -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;

View file

@ -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 {