From 577a25a99e499079d9a4d5f8457a13369f51b87e Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 22 Mar 2016 22:28:13 +0000 Subject: [PATCH] Move hotplug checking into its own thread Currently checking for new linux input devices is called from the rendering thread. We've been getting reports of skipped frames on raspberry pi. Specifically if eventlirc is active and you have an LIRC capable device connected the hotplug check is slow and you get a frame skip every ten seconds. So move this code into its own thread --- xbmc/input/linux/LinuxInputDevices.cpp | 54 +++++++++++++++++++++------------- xbmc/input/linux/LinuxInputDevices.h | 14 ++++++++- xbmc/windowing/WinEventsLinux.cpp | 1 + xbmc/windowing/WinEventsLinux.h | 2 ++ 4 files changed, 49 insertions(+), 22 deletions(-) diff --git a/xbmc/input/linux/LinuxInputDevices.cpp b/xbmc/input/linux/LinuxInputDevices.cpp index 9f3e866..8be2ed4 100644 --- a/xbmc/input/linux/LinuxInputDevices.cpp +++ b/xbmc/input/linux/LinuxInputDevices.cpp @@ -1080,6 +1080,30 @@ bool CLinuxInputDevice::IsUnplugged() return m_bUnplugged; } +CLinuxInputDevicesCheckHotplugged::CLinuxInputDevicesCheckHotplugged(CLinuxInputDevices &parent) : + CThread("CLinuxInputDevicesCheckHotplugged"), m_parent(parent) +{ + Create(); + SetPriority(THREAD_PRIORITY_BELOW_NORMAL); +} + +CLinuxInputDevicesCheckHotplugged::~CLinuxInputDevicesCheckHotplugged() +{ + m_bStop = true; + m_quitEvent.Set(); + StopThread(true); +} + +void CLinuxInputDevicesCheckHotplugged::Process() +{ + while (!m_bStop) + { + m_parent.CheckHotplugged(); + // every ten seconds + m_quitEvent.WaitMSec(10000); + } +} + bool CLinuxInputDevices::CheckDevice(const char *device) { int fd; @@ -1146,10 +1170,6 @@ void CLinuxInputDevices::InitAvailable() */ void CLinuxInputDevices::CheckHotplugged() { - CSingleLock lock(m_devicesListLock); - - int deviceId = m_devices.size(); - /* No devices specified. Try to guess some. */ for (int i = 0; i < MAX_LINUX_INPUT_DEVICES; i++) { @@ -1157,18 +1177,22 @@ void CLinuxInputDevices::CheckHotplugged() bool ispresent = false; snprintf(buf, 32, "/dev/input/event%d", i); - - for (size_t j = 0; j < m_devices.size(); j++) { - if (m_devices[j]->GetFileName().compare(buf) == 0) + CSingleLock lock(m_devicesListLock); + for (size_t j = 0; j < m_devices.size(); j++) { - ispresent = true; - break; + if (m_devices[j]->GetFileName().compare(buf) == 0) + { + ispresent = true; + break; + } } } if (!ispresent && CheckDevice(buf)) { + CSingleLock lock(m_devicesListLock); + int deviceId = m_devices.size(); CLog::Log(LOGINFO, "Found input device %s", buf); m_devices.push_back(new CLinuxInputDevice(buf, deviceId)); ++deviceId; @@ -1359,18 +1383,6 @@ XBMC_Event CLinuxInputDevices::ReadEvent() InitAvailable(); m_bReInitialize = false; } - else - { - time_t now; - time(&now); - - if ((now - m_lastHotplugCheck) >= 10) - { - CheckHotplugged(); - m_lastHotplugCheck = now; - } - } - CSingleLock lock(m_devicesListLock); XBMC_Event event; diff --git a/xbmc/input/linux/LinuxInputDevices.h b/xbmc/input/linux/LinuxInputDevices.h index 8c88a1d..4fde1aa 100644 --- a/xbmc/input/linux/LinuxInputDevices.h +++ b/xbmc/input/linux/LinuxInputDevices.h @@ -28,6 +28,7 @@ #include "threads/SingleLock.h" #include "input/touch/ITouchInputHandler.h" #include "input/touch/generic/IGenericTouchGestureDetector.h" +#include "threads/Thread.h" struct KeymapEntry { @@ -105,7 +106,18 @@ private: bool CheckDevice(const char *device); std::vector m_devices; bool m_bReInitialize; - time_t m_lastHotplugCheck; +}; + +class CLinuxInputDevicesCheckHotplugged : protected CThread +{ +public: + CLinuxInputDevicesCheckHotplugged(CLinuxInputDevices &parent); + ~CLinuxInputDevicesCheckHotplugged(); +private: + CLinuxInputDevices &m_parent; + CEvent m_quitEvent; +protected: + virtual void Process(); }; #endif /* LINUXINPUTDEVICES_H_ */ diff --git a/xbmc/windowing/WinEventsLinux.cpp b/xbmc/windowing/WinEventsLinux.cpp index aaba119..a958a23 100644 --- a/xbmc/windowing/WinEventsLinux.cpp +++ b/xbmc/windowing/WinEventsLinux.cpp @@ -53,6 +53,7 @@ bool CWinEventsLinux::MessagePump() if (!m_initialized) { m_devices.InitAvailable(); + m_checkHotplug = std::unique_ptr(new CLinuxInputDevicesCheckHotplugged(m_devices)); m_initialized = true; } diff --git a/xbmc/windowing/WinEventsLinux.h b/xbmc/windowing/WinEventsLinux.h index a17e987..72d1de4 100644 --- a/xbmc/windowing/WinEventsLinux.h +++ b/xbmc/windowing/WinEventsLinux.h @@ -22,6 +22,7 @@ #define WINDOW_EVENTS_LINUX_H #pragma once +#include #include "windowing/WinEvents.h" #include "input/linux/LinuxInputDevices.h" @@ -42,6 +43,7 @@ public: private: static bool m_initialized; + std::unique_ptr m_checkHotplug; static CLinuxInputDevices m_devices; }; -- 2.7.4