Skip to content

Commit

Permalink
Copy commit queue in check_new_wayland_res
Browse files Browse the repository at this point in the history
This will allow us to call wlr_buffer_lock/unlock in import_commit without
causing a deadlock.
  • Loading branch information
emersion committed Jul 23, 2020
1 parent a8d1248 commit fa2827f
Showing 1 changed file with 46 additions and 52 deletions.
98 changes: 46 additions & 52 deletions src/steamcompmgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2074,73 +2074,67 @@ void handle_done_commits( void )

void check_new_wayland_res( void )
{
// We need to release buffers without having a commit queue lock, otherwise
// we won't be able to lock wlserver without a deadlock
std::vector<struct wlr_buffer *> release_queue;

// When importing buffer, we'll potentially need to perform operations with
// a wlserver lock (e.g. wlr_buffer_lock). We can't do this with a
// wayland_commit_queue lock because that causes deadlocks.
std::vector<ResListEntry_t> tmp_queue;
{
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++ )
{
struct wlr_buffer *buf = wayland_commit_queue[ i ].buf;
for ( uint32_t i = 0; i < tmp_queue.size(); i++ )
{
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 )
{
release_queue.push_back( buf );
fprintf (stderr, "waylandres but no win\n");
continue;
}
if ( w == nullptr )
{
wlserver_lock();
wlr_buffer_unlock( buf );
wlserver_unlock();
fprintf (stderr, "waylandres but no win\n");
continue;
}

struct wlr_dmabuf_attributes dmabuf = {};
bool result = False;
if ( wlr_buffer_get_dmabuf( buf, &dmabuf ) ) {
result = true;
for ( int i = 0; i < dmabuf.n_planes; i++ ) {
dmabuf.fd[i] = dup( dmabuf.fd[i] );
assert( dmabuf.fd[i] >= 0 );
}
} else {
struct wlr_client_buffer *client_buf = (struct wlr_client_buffer *) buf;
result = wlr_texture_to_dmabuf( client_buf->texture, &dmabuf );
struct wlr_dmabuf_attributes dmabuf = {};
bool result = False;
if ( wlr_buffer_get_dmabuf( buf, &dmabuf ) ) {
result = true;
for ( int i = 0; i < dmabuf.n_planes; i++ ) {
dmabuf.fd[i] = dup( dmabuf.fd[i] );
assert( dmabuf.fd[i] >= 0 );
}
assert( result == true );
} else {
struct wlr_client_buffer *client_buf = (struct wlr_client_buffer *) buf;
result = wlr_texture_to_dmabuf( client_buf->texture, &dmabuf );
}
assert( result == true );

commit_t newCommit = {};
bool bSuccess = import_commit( buf, &dmabuf, newCommit );
wlr_dmabuf_attributes_finish( &dmabuf );
commit_t newCommit = {};
bool bSuccess = import_commit( buf, &dmabuf, newCommit );
wlr_dmabuf_attributes_finish( &dmabuf );

if ( bSuccess == true )
{
newCommit.commitID = ++maxCommmitID;
w->commit_queue.push_back( newCommit );
}
if ( bSuccess == true )
{
newCommit.commitID = ++maxCommmitID;
w->commit_queue.push_back( newCommit );
}

uint32_t fence = vulkan_get_texture_fence( newCommit.vulkanTex );
uint32_t fence = vulkan_get_texture_fence( newCommit.vulkanTex );

gpuvis_trace_printf( "pushing wait for commit %lu\n", newCommit.commitID );
{
std::unique_lock< std::mutex > lock( waitListLock );

waitList.push_back( std::make_pair( fence, newCommit.commitID ) );
}
gpuvis_trace_printf( "pushing wait for commit %lu\n", newCommit.commitID );
{
std::unique_lock< std::mutex > lock( waitListLock );

// Wake up commit wait thread if chilling
waitListSem.signal();
waitList.push_back( std::make_pair( fence, newCommit.commitID ) );
}

wayland_commit_queue.clear();
}

wlserver_lock();
for ( uint32_t i = 0; i < release_queue.size(); i++ )
{
wlr_buffer_unlock( release_queue[ i ] );
// Wake up commit wait thread if chilling
waitListSem.signal();
}
wlserver_unlock();
release_queue.clear();
}

int
Expand Down

0 comments on commit fa2827f

Please sign in to comment.