~albaguirre/mir/add-hwc14-support-0.12

« back to all changes in this revision

Viewing changes to src/server/frontend/surface_tracker.cpp

  • Committer: Alexandros Frantzis
  • Author(s): Alberto Aguirre
  • Date: 2015-03-19 11:09:45 UTC
  • mfrom: (2296.1.5 0.12)
  • Revision ID: alexandros.frantzis@canonical.com-20150319110945-iyk2scbil2ko11gv
Avoid unlocking a mutex in a thread that does not own it (LP: #1427976).
    
SessionMediator unlocks its session_mutex before invoking rpc callbacks. This
becomes cumbersome when SessionMediator needs to call Surface::swap_buffers, as
the completion function may be executed in an entirely different thread.
  
The session_mutex should only be unlocked if the completion function is invoked
during Surface::swap_buffers.
  
Backported from lp:mir r2379.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright © 2013 Canonical Ltd.
 
2
 * Copyright © 2013-2015 Canonical Ltd.
3
3
 *
4
4
 * This program is free software: you can redistribute it and/or modify
5
5
 * it under the terms of the GNU General Public License version 3 as
17
17
 */
18
18
 
19
19
#include "surface_tracker.h"
 
20
#include "client_buffer_tracker.h"
 
21
 
20
22
#include "mir/graphics/buffer.h"
21
23
#include "mir/graphics/buffer_id.h"
 
24
 
22
25
#include <boost/throw_exception.hpp>
23
26
#include <stdexcept>
24
27
 
32
35
 
33
36
bool mf::SurfaceTracker::track_buffer(SurfaceId surface_id, mg::Buffer* buffer)
34
37
{
 
38
    std::lock_guard<decltype(mutex)> lock{mutex};
35
39
    auto& tracker = client_buffer_tracker[surface_id];
36
40
    if (!tracker)
37
41
        tracker = std::make_shared<ClientBufferTracker>(client_cache_size);
53
57
 
54
58
void mf::SurfaceTracker::remove_surface(SurfaceId surface_id)
55
59
{
 
60
    std::lock_guard<decltype(mutex)> lock{mutex};
56
61
    auto it = client_buffer_tracker.find(surface_id);
57
62
    if (it != client_buffer_tracker.end())
58
63
        client_buffer_tracker.erase(it);
64
69
 
65
70
mg::Buffer* mf::SurfaceTracker::last_buffer(SurfaceId surface_id) const
66
71
{
 
72
    std::lock_guard<decltype(mutex)> lock{mutex};
67
73
    auto it = client_buffer_resource.find(surface_id);
68
74
    if (it != client_buffer_resource.end())
69
75
        return it->second;
74
80
 
75
81
mg::Buffer* mf::SurfaceTracker::buffer_from(mg::BufferID buffer_id) const
76
82
{
 
83
    std::lock_guard<decltype(mutex)> lock{mutex};
77
84
    for (auto const& tracker : client_buffer_tracker)
78
85
    {
79
86
        auto buffer = tracker.second->buffer_from(buffer_id);