diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-01-21 05:18:28 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-01-21 05:18:28 +0100 |
commit | 76a28817931e6826a6f406a6b677082aa8c4f949 (patch) | |
tree | 58e294d5a6fc36de2bb89a1bc92645b3998a9b91 | |
parent | d1af5c97ca18d48700ccf7d939f9911a43a9c2eb (diff) | |
download | serenity-76a28817931e6826a6f406a6b677082aa8c4f949.zip |
Mark the two Regions used GraphicsBitmaps as explicitly shared.
This fixes a goofy problem where forking a GUI process would cowify the
GraphicsBitmap for everyone making a hue confusing mess.
-rw-r--r-- | Kernel/MemoryManager.cpp | 7 | ||||
-rw-r--r-- | Kernel/MemoryManager.h | 3 | ||||
-rw-r--r-- | SharedGraphics/GraphicsBitmap.cpp | 2 |
3 files changed, 11 insertions, 1 deletions
diff --git a/Kernel/MemoryManager.cpp b/Kernel/MemoryManager.cpp index e719243e2f..60d1a9c127 100644 --- a/Kernel/MemoryManager.cpp +++ b/Kernel/MemoryManager.cpp @@ -563,11 +563,16 @@ RetainPtr<Region> Region::clone() { InterruptDisabler disabler; - if (is_readable && !is_writable) { + if (m_shared || (is_readable && !is_writable)) { // Create a new region backed by the same VMObject. return adopt(*new Region(linearAddress, size, m_vmo.copyRef(), m_offset_in_vmo, String(name), is_readable, is_writable)); } + dbgprintf("%s<%u> Region::clone(): cowing %s (L%x)\n", + current->name().characters(), + current->pid(), + name.characters(), + linearAddress.get()); // Set up a COW region. The parent (this) region becomes COW as well! for (size_t i = 0; i < page_count(); ++i) cow_map.set(i, true); diff --git a/Kernel/MemoryManager.h b/Kernel/MemoryManager.h index 17b99fcfe1..46cbe89edb 100644 --- a/Kernel/MemoryManager.h +++ b/Kernel/MemoryManager.h @@ -117,6 +117,8 @@ public: const VMObject& vmo() const { return *m_vmo; } VMObject& vmo() { return *m_vmo; } + void set_shared(bool shared) { m_shared = shared; } + RetainPtr<Region> clone(); bool contains(LinearAddress laddr) const { @@ -156,6 +158,7 @@ public: String name; bool is_readable { true }; bool is_writable { true }; + bool m_shared { false }; Bitmap cow_map; }; diff --git a/SharedGraphics/GraphicsBitmap.cpp b/SharedGraphics/GraphicsBitmap.cpp index 00dcd3707a..3da6cce03c 100644 --- a/SharedGraphics/GraphicsBitmap.cpp +++ b/SharedGraphics/GraphicsBitmap.cpp @@ -21,12 +21,14 @@ GraphicsBitmap::GraphicsBitmap(Process& process, const Size& size) size_t size_in_bytes = size.width() * size.height() * sizeof(RGBA32); auto vmo = VMObject::create_anonymous(size_in_bytes); m_client_region = process.allocate_region_with_vmo(LinearAddress(), size_in_bytes, vmo.copyRef(), 0, "GraphicsBitmap (client)", true, true); + m_client_region->set_shared(true); m_client_region->commit(process); { auto& server = WSEventLoop::the().server_process(); InterruptDisabler disabler; m_server_region = server.allocate_region_with_vmo(LinearAddress(), size_in_bytes, move(vmo), 0, "GraphicsBitmap (server)", true, true); + m_server_region->set_shared(true); } m_data = (RGBA32*)m_server_region->linearAddress.asPtr(); } |