diff options
author | Andreas Kling <kling@serenityos.org> | 2022-03-07 16:34:14 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-03-07 16:35:23 +0100 |
commit | baa6ff56497e583d706a2999134f6468f2f89b29 (patch) | |
tree | 6007d6fdfd7da60062037b063e44fee47b2179d3 /Kernel/Devices/HID | |
parent | ff60e8ffc6e940bcf71cc1a5a697d1b2c25c6caa (diff) | |
download | serenity-baa6ff56497e583d706a2999134f6468f2f89b29.zip |
Kernel: Wrap HIDManagement keymap data in SpinlockProtected
This serializes access to the current keymap data everywhere in the
kernel, allowing to mark sys$setkeymap() as not needing the big lock.
Diffstat (limited to 'Kernel/Devices/HID')
-rw-r--r-- | Kernel/Devices/HID/HIDManagement.cpp | 40 | ||||
-rw-r--r-- | Kernel/Devices/HID/HIDManagement.h | 14 |
2 files changed, 34 insertions, 20 deletions
diff --git a/Kernel/Devices/HID/HIDManagement.cpp b/Kernel/Devices/HID/HIDManagement.cpp index 1d45324d0e..084f0befc6 100644 --- a/Kernel/Devices/HID/HIDManagement.cpp +++ b/Kernel/Devices/HID/HIDManagement.cpp @@ -86,17 +86,23 @@ size_t HIDManagement::generate_minor_device_number_for_keyboard() return m_keyboard_minor_number++; } +UNMAP_AFTER_INIT HIDManagement::KeymapData::KeymapData() + : character_map_name(KString::must_create("en-us"sv)) + , character_map(DEFAULT_CHARACTER_MAP) +{ +} + UNMAP_AFTER_INIT HIDManagement::HIDManagement() - : m_character_map_name(KString::must_create("en-us"sv)) - , m_character_map(DEFAULT_CHARACTER_MAP) { } void HIDManagement::set_maps(NonnullOwnPtr<KString> character_map_name, Keyboard::CharacterMapData const& character_map_data) { - m_character_map_name = move(character_map_name); - m_character_map = character_map_data; - dbgln("New Character map '{}' passed in by client.", m_character_map_name); + m_keymap_data.with([&](auto& keymap_data) { + keymap_data.character_map_name = move(character_map_name); + keymap_data.character_map = character_map_data; + dbgln("New Character map '{}' passed in by client.", keymap_data.character_map_name); + }); } UNMAP_AFTER_INIT ErrorOr<void> HIDManagement::enumerate() @@ -150,17 +156,19 @@ u32 HIDManagement::get_char_from_character_map(KeyEvent event) const auto index = event.scancode & 0xFF; // Index is last byte of scan code. auto caps_lock_on = event.caps_lock_on; - u32 code_point; - if (modifiers & Mod_Alt) - code_point = m_character_map.alt_map[index]; - else if ((modifiers & Mod_Shift) && (modifiers & Mod_AltGr)) - code_point = m_character_map.shift_altgr_map[index]; - else if (modifiers & Mod_Shift) - code_point = m_character_map.shift_map[index]; - else if (modifiers & Mod_AltGr) - code_point = m_character_map.altgr_map[index]; - else - code_point = m_character_map.map[index]; + u32 code_point = 0; + m_keymap_data.with([&](auto& keymap_data) { + if (modifiers & Mod_Alt) + code_point = keymap_data.character_map.alt_map[index]; + else if ((modifiers & Mod_Shift) && (modifiers & Mod_AltGr)) + code_point = keymap_data.character_map.shift_altgr_map[index]; + else if (modifiers & Mod_Shift) + code_point = keymap_data.character_map.shift_map[index]; + else if (modifiers & Mod_AltGr) + code_point = keymap_data.character_map.altgr_map[index]; + else + code_point = keymap_data.character_map.map[index]; + }); if (caps_lock_on && (modifiers == 0 || modifiers == Mod_Shift)) { if (code_point >= 'a' && code_point <= 'z') diff --git a/Kernel/Devices/HID/HIDManagement.h b/Kernel/Devices/HID/HIDManagement.h index 5201fb9891..691fe3d476 100644 --- a/Kernel/Devices/HID/HIDManagement.h +++ b/Kernel/Devices/HID/HIDManagement.h @@ -16,6 +16,7 @@ #include <Kernel/API/KeyCode.h> #include <Kernel/API/MousePacket.h> #include <Kernel/Locking/Spinlock.h> +#include <Kernel/Locking/SpinlockProtected.h> #include <Kernel/UnixTypes.h> #include <LibKeyboard/CharacterMapData.h> @@ -39,8 +40,14 @@ public: ErrorOr<void> enumerate(); - StringView keymap_name() const { return m_character_map_name->view(); } - Keyboard::CharacterMapData const& character_map() const { return m_character_map; } + struct KeymapData { + KeymapData(); + NonnullOwnPtr<KString> character_map_name; + Keyboard::CharacterMapData character_map; + }; + + SpinlockProtected<KeymapData>& keymap_data() { return m_keymap_data; } + u32 get_char_from_character_map(KeyEvent) const; void set_client(KeyboardClient* client) { m_client = client; } @@ -50,10 +57,9 @@ private: size_t generate_minor_device_number_for_mouse(); size_t generate_minor_device_number_for_keyboard(); + SpinlockProtected<KeymapData> m_keymap_data; size_t m_mouse_minor_number { 0 }; size_t m_keyboard_minor_number { 0 }; - NonnullOwnPtr<KString> m_character_map_name; - Keyboard::CharacterMapData m_character_map; KeyboardClient* m_client { nullptr }; RefPtr<I8042Controller> m_i8042_controller; NonnullRefPtrVector<HIDDevice> m_hid_devices; |