Copy commit queue in check_new_wayland_res

This will allow us to call wlr_buffer_lock/unlock in import_commit without
causing a deadlock.
This commit is contained in:
Simon Ser 2020-05-19 11:26:52 +02:00 committed by Pierre-Loup A. Griffais
parent d88cfec0c2
commit 31a0713455

View file

@ -2362,22 +2362,27 @@ void handle_done_commits( void )
void check_new_wayland_res( void ) void check_new_wayland_res( void )
{ {
// We need to release buffers without having a commit queue lock, otherwise // When importing buffer, we'll potentially need to perform operations with
// we won't be able to lock wlserver without a deadlock // a wlserver lock (e.g. wlr_buffer_lock). We can't do this with a
std::vector<struct wlr_buffer *> release_queue; // wayland_commit_queue lock because that causes deadlocks.
std::vector<ResListEntry_t> tmp_queue;
{ {
std::lock_guard<std::mutex> lock( wayland_commit_lock ); std::lock_guard<std::mutex> lock( wayland_commit_lock );
tmp_queue = wayland_commit_queue;
wayland_commit_queue.clear();
}
for ( uint32_t i = 0; i < wayland_commit_queue.size(); i++ ) for ( uint32_t i = 0; i < tmp_queue.size(); i++ )
{ {
struct wlr_buffer *buf = wayland_commit_queue[ i ].buf; struct wlr_buffer *buf = tmp_queue[ i ].buf;
win *w = find_win( wayland_commit_queue[ i ].surf ); win *w = find_win( tmp_queue[ i ].surf );
if ( w == nullptr ) if ( w == nullptr )
{ {
release_queue.push_back( buf ); wlserver_lock();
wlr_buffer_unlock( buf );
wlserver_unlock();
fprintf (stderr, "waylandres but no win\n"); fprintf (stderr, "waylandres but no win\n");
continue; continue;
} }
@ -2424,17 +2429,6 @@ void check_new_wayland_res( void )
// Wake up commit wait thread if chilling // Wake up commit wait thread if chilling
waitListSem.signal(); waitListSem.signal();
} }
wayland_commit_queue.clear();
}
wlserver_lock();
for ( uint32_t i = 0; i < release_queue.size(); i++ )
{
wlr_buffer_unlock( release_queue[ i ] );
}
wlserver_unlock();
release_queue.clear();
} }
int int