Skip to content

medialib: acquire priority access for Control

Romain Vimont requested to merge rom1v/vlc:ml_priority_access.5 into master

Contrary to Get and List requests, which acquire the priority access since 7ef4e1ef, not all Control requests may acquire the priority access safely currently.

Indeed, some of them indirectly acquire the internal medialibrary mutex (for example, MediaLibrary::reload() calls startDiscoverer()), which may be locked by a non-priority caller.

Acquire priority access for Control requests which do not suffer for this problem.


Here is a relevant stack trace illustrating a possible deadlock for other Control requests:

Thread 29 (Thread 0x7fffbfeef700 (LWP 297683) "Thread (pooled)"):
#0  futex_wait_cancelable (private=0, expected=0, futex_word=0x6130000cffc8) at ../sysdeps/nptl/futex-internal.h:186
#1  __pthread_cond_wait_common (abstime=0x0, clockid=0, mutex=0x6130000cffd0, cond=0x6130000cffa0) at pthread_cond_wait.c:508
#2  __pthread_cond_wait (cond=0x6130000cffa0, mutex=0x6130000cffd0) at pthread_cond_wait.c:638
#3  0x00007ffff55c090c in std::condition_variable::wait(std::unique_lock<std::mutex>&) () at /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4  0x00007ffff07c3020 in std::condition_variable::wait<medialibrary::utils::SWMRLock::lock_read()::<lambda()> >(std::unique_lock<std::mutex> &, struct {...}) (this=0x6130000cffa0, __lock=..., __p=...) at /usr/include/c++/10/condition_variable:111
#5  0x00007ffff07c2af6 in medialibrary::utils::SWMRLock::lock_read() (this=0x6130000cffa0) at ../src/utils/SWMRLock.cpp:42
#6  0x00007ffff06ebd0d in medialibrary::utils::ReadLocker::lock() (this=0x6130000d0020) at ../src/utils/SWMRLock.h:102
#7  0x00007ffff06ed913 in std::unique_lock<medialibrary::utils::ReadLocker>::lock() (this=0x7fffbfeee6d0) at /usr/include/c++/10/bits/unique_lock.h:138
#8  0x00007ffff06ec8ab in std::unique_lock<medialibrary::utils::ReadLocker>::unique_lock(medialibrary::utils::ReadLocker&) (this=0x7fffbfeee6d0, __m=...) at /usr/include/c++/10/bits/unique_lock.h:68
#9  0x00007ffff06e9fd8 in medialibrary::sqlite::Connection::acquireReadContext() (this=0x6130000cff10) at ../src/database/SqliteConnection.cpp:153
#10 0x00007ffff05dcc78 in medialibrary::sqlite::Tools::fetchOne<medialibrary::Device, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>(medialibrary::MediaLibrary const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (ml=0x614000007840, req="SELECT * FROM Device WHERE uuid = ? AND scheme = ?") at ../src/database/SqliteTools.h:298
#11 0x00007ffff05db3a5 in medialibrary::DatabaseHelpers<medialibrary::Device>::fetch<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>(medialibrary::MediaLibrary const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (ml=0x614000007840, req="SELECT * FROM Device WHERE uuid = ? AND scheme = ?") at ../src/database/DatabaseHelpers.h:45
#12 0x00007ffff05d9df7 in medialibrary::Device::fromUuid(medialibrary::MediaLibrary const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (ml=0x614000007840, uuid="5668-A738", scheme="file://") at ../src/Device.cpp:248
#13 0x00007ffff0675d42 in medialibrary::MediaLibrary::FsFactoryCb::onDeviceMounted(medialibrary::fs::IDevice const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (this=0x6140000078a0, deviceFs=..., newMountpoint="file:///boot/efi") at ../src/MediaLibrary.cpp:2811
#14 0x00007ffff0c1f029 in vlc::medialibrary::SDFileSystemFactory::onDeviceMounted(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool) (this=0x60e00014dff0, uuid="5668-A738", mountpoint="file:///boot/efi", removable=false) at ../../modules/misc/medialibrary/fs/fs.cpp:152
#15 0x00007ffff07202a2 in medialibrary::fs::CommonDeviceLister::refresh() (this=0x6060000487b0) at ../src/filesystem/common/CommonDeviceLister.cpp:106
#16 0x00007ffff0c1cf34 in vlc::medialibrary::SDFileSystemFactory::refreshDevices() (this=0x60e00014dff0) at ../../modules/misc/medialibrary/fs/fs.cpp:90
#17 0x00007ffff0675686 in medialibrary::MediaLibrary::startFsFactoriesAndRefresh() (this=0x614000007840) at ../src/MediaLibrary.cpp:2699
#18 0x00007ffff06faf75 in medialibrary::DiscovererWorker::runReloadAllDevices() (this=0x60e000151700) at ../src/discoverer/DiscovererWorker.cpp:536
#19 0x00007ffff06fa255 in medialibrary::DiscovererWorker::run() (this=0x60e000151700) at ../src/discoverer/DiscovererWorker.cpp:367
#20 0x00007ffff0704669 in std::__invoke_impl<void, void (medialibrary::DiscovererWorker::*)(), medialibrary::DiscovererWorker*>(std::__invoke_memfun_deref, void (medialibrary::DiscovererWorker::*&&)(), medialibrary::DiscovererWorker*&&) (__f=@0x60300087ec30: (void (medialibrary::DiscovererWorker::*)(class medialibrary::DiscovererWorker * const)) 0x7ffff06fa1ca <medialibrary::DiscovererWorker::run()>, __t=@0x60300087ec28: 0x60e000151700) at /usr/include/c++/10/bits/invoke.h:73
#21 0x00007ffff07045ab in std::__invoke<void (medialibrary::DiscovererWorker::*)(), medialibrary::DiscovererWorker*>(void (medialibrary::DiscovererWorker::*&&)(), medialibrary::DiscovererWorker*&&) (__fn=@0x60300087ec30: (void (medialibrary::DiscovererWorker::*)(class medialibrary::DiscovererWorker * const)) 0x7ffff06fa1ca <medialibrary::DiscovererWorker::run()>) at /usr/include/c++/10/bits/invoke.h:95
#22 0x00007ffff070451b in std::thread::_Invoker<std::tuple<void (medialibrary::DiscovererWorker::*)(), medialibrary::DiscovererWorker*> >::_M_invoke<0ul, 1ul>(std::_Index_tuple<0ul, 1ul>) (this=0x60300087ec28) at /usr/include/c++/10/thread:264
#23 0x00007ffff07044d4 in std::thread::_Invoker<std::tuple<void (medialibrary::DiscovererWorker::*)(), medialibrary::DiscovererWorker*> >::operator()() (this=0x60300087ec28) at /usr/include/c++/10/thread:271
#24 0x00007ffff07044b8 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (medialibrary::DiscovererWorker::*)(), medialibrary::DiscovererWorker*> > >::_M_run() (this=0x60300087ec20) at /usr/include/c++/10/thread:215
#25 0x00007ffff55c5ed0 in  () at /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#26 0x00007ffff6b18ea7 in start_thread (arg=<optimized out>) at pthread_create.c:477
#27 0x00007ffff6a48def in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 27 (Thread 0x7fffc0963700 (LWP 297681) "Thread (pooled)"):
#0  __lll_lock_wait (futex=futex@entry=0x614000007848, private=0) at lowlevellock.c:52
#1  0x00007ffff6b1b843 in __GI___pthread_mutex_lock (mutex=0x614000007848) at ../nptl/pthread_mutex_lock.c:80
#2  0x00007ffff05907e0 in __gthread_mutex_lock(__gthread_mutex_t*) (__mutex=0x614000007848) at /usr/include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:749
#3  0x00007ffff0590c38 in std::mutex::lock() (this=0x614000007848) at /usr/include/c++/10/bits/std_mutex.h:100
#4  0x00007ffff0593908 in std::lock_guard<std::mutex>::lock_guard(std::mutex&) (this=0x7fffc09625c8, __m=...) at /usr/include/c++/10/bits/std_mutex.h:159
#5  0x00007ffff0661238 in medialibrary::MediaLibrary::startDiscoverer() (this=0x614000007840) at ../src/MediaLibrary.cpp:1151
#6  0x00007ffff06735d7 in medialibrary::MediaLibrary::reload() (this=0x614000007840) at ../src/MediaLibrary.cpp:2248
#7  0x00007ffff0b36648 in MediaLibrary::Control(int, __va_list_tag*) (this=0x606000048860, query=5, args=0x7fffc0962b90) at ../../modules/misc/medialibrary/medialibrary.cpp:569
#8  0x00007ffff0b5d36c in Control(vlc_medialibrary_module_t *, int, typedef __va_list_tag __va_list_tag *) (module=0x60b0002f9cf0, query=5, args=0x7fffc0962b90) at ../../modules/misc/medialibrary/medialibrary.cpp:1965
#9  0x00007ffff5fcfe44 in vlc_ml_control (p_ml=0x60b0002f9cf0, i_query=5) at ../../src/misc/medialibrary.c:425
#10 0x00007fffdbacd6ba in vlc_ml_reload_folder(vlc_medialibrary_t*, char const*) (p_ml=0x60b0002f9cf0, psz_mrl=0x0) at ../../include/vlc_media_library.h:947
#11 0x00007fffdbad5e4f in MediaLib::Task::run() (this=0x603000929aa0) at ../../modules/gui/qt/medialibrary/medialib.cpp:235
#12 0x00007fffd791fed2 in  () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#13 0x00007fffd791cbe1 in  () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#14 0x00007ffff6b18ea7 in start_thread (arg=<optimized out>) at pthread_create.c:477
#15 0x00007ffff6a48def in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Merge request reports