Merge lp:~marcustomlinson/unity-scopes-shell/lp-1567429 into lp:unity-scopes-shell
- lp-1567429
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Paweł Stołowski | ||||
Approved revision: | 315 | ||||
Merged at revision: | 313 | ||||
Proposed branch: | lp:~marcustomlinson/unity-scopes-shell/lp-1567429 | ||||
Merge into: | lp:unity-scopes-shell | ||||
Diff against target: |
275 lines (+65/-16) 5 files modified
src/Unity/scope.cpp (+25/-6) src/Unity/scope.h (+5/-0) src/Unity/scopes.cpp (+2/-0) src/Unity/settingsmodel.cpp (+31/-10) src/Unity/settingsmodel.h (+2/-0) |
||||
To merge this branch: | bzr merge lp:~marcustomlinson/unity-scopes-shell/lp-1567429 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Paweł Stołowski (community) | Approve | ||
PS Jenkins bot (community) | continuous-integration | Needs Fixing | |
Review via email: mp+291480@code.launchpad.net |
Commit message
Update child scopes in a background thread to greatly improve the performance of Scope::settings()
Description of the change
PS Jenkins bot (ps-jenkins) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:304
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Paweł Stołowski (stolowski) wrote : | # |
Looks good, I think it will improve the perceived performance of Settings page quite a bit already. I yet need to check the silo and how it impacts search.
I think there is one other potential improvement we could make though: make the call to m_scopeProxy-
Marcus Tomlinson (marcustomlinson) wrote : | # |
> Looks good, I think it will improve the perceived performance of Settings page
> quite a bit already. I yet need to check the silo and how it impacts search.
>
> I think there is one other potential improvement we could make though: make
> the call to m_scopeProxy-
> it blocks the main thread we may see the loading bar animation struggling
> during search. What do you think about starting the call in a separate thread
> and *only* waiting for the call to finish when the settings are actually
> accessed/needed (e.g. in call to data() if there is no better place)?
Good point. Ok I've moved the child scopes update to a background thread, expected to complete upon a call to settings()
Paweł Stołowski (stolowski) wrote : | # |
Thanks, great stuff with QFuture! This looks very good, but I think with these changes we need to address the following now:
- m_settingsModel
- the destructor of Scope needs to wait for m_childScopesFu
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:305
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Marcus Tomlinson (marcustomlinson) wrote : | # |
> Thanks, great stuff with QFuture! This looks very good, but I think with these
> changes we need to address the following now:
>
> - m_settingsModel
> now called from a new thread, so m_settingsModel needs to synchronize access
> to its members. We may have a situation where Settings page is already opened
> by the UI and registry change triggers the update of child scopes at the same
> time.
> - the destructor of Scope needs to wait for m_childScopesFu
> cancel() first (according to QFuture docs, the destructor of QFuture doesn't
> wait for it to finish). Alternatively use QFutureSynchron
Very true. k, done.
Paweł Stołowski (stolowski) wrote : | # |
Ok, looks good now, thanks!
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:306
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:308
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Albert Astals Cid (aacid) wrote : | # |
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:309
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Albert Astals Cid (aacid) wrote : | # |
New patch brigns down the thing to 0msec now, seems much nicer and can't see it regressing in any obvious way
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:311
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:312
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 313. By Marcus Tomlinson
-
Remove unnecessary sync() call
- 314. By Marcus Tomlinson
-
Don't emit settingsChanged() unless settings actually change
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:314
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 315. By Marcus Tomlinson
-
Emit settingsChanged when child scope state changes
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:315
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'src/Unity/scope.cpp' | |||
2 | --- src/Unity/scope.cpp 2016-03-17 22:35:44 +0000 | |||
3 | +++ src/Unity/scope.cpp 2016-04-19 08:05:18 +0000 | |||
4 | @@ -91,6 +91,7 @@ | |||
5 | 91 | , m_hasNavigation(false) | 91 | , m_hasNavigation(false) |
6 | 92 | , m_favorite(false) | 92 | , m_favorite(false) |
7 | 93 | , m_initialQueryDone(false) | 93 | , m_initialQueryDone(false) |
8 | 94 | , m_childScopesDirty(true) | ||
9 | 94 | , m_searchController(new CollectionController) | 95 | , m_searchController(new CollectionController) |
10 | 95 | , m_activationController(new CollectionController) | 96 | , m_activationController(new CollectionController) |
11 | 96 | , m_status(Status::Okay) | 97 | , m_status(Status::Okay) |
12 | @@ -125,6 +126,7 @@ | |||
13 | 125 | 126 | ||
14 | 126 | Scope::~Scope() | 127 | Scope::~Scope() |
15 | 127 | { | 128 | { |
16 | 129 | m_childScopesFuture.waitForFinished(); | ||
17 | 128 | } | 130 | } |
18 | 129 | 131 | ||
19 | 130 | void Scope::processSearchChunk(PushEvent* pushEvent) | 132 | void Scope::processSearchChunk(PushEvent* pushEvent) |
20 | @@ -247,6 +249,7 @@ | |||
21 | 247 | { | 249 | { |
22 | 248 | // refresh Settings view if needed | 250 | // refresh Settings view if needed |
23 | 249 | if (require_child_scopes_refresh()) { | 251 | if (require_child_scopes_refresh()) { |
24 | 252 | m_childScopesDirty = true; | ||
25 | 250 | update_child_scopes(); | 253 | update_child_scopes(); |
26 | 251 | } | 254 | } |
27 | 252 | 255 | ||
28 | @@ -721,6 +724,10 @@ | |||
29 | 721 | 724 | ||
30 | 722 | setSearchInProgress(true); | 725 | setSearchInProgress(true); |
31 | 723 | 726 | ||
32 | 727 | // If applicable, update this scope's child scopes now, as part of the search process | ||
33 | 728 | // (i.e. while the loading bar is visible). | ||
34 | 729 | update_child_scopes(); | ||
35 | 730 | |||
36 | 724 | if (m_proxy) { | 731 | if (m_proxy) { |
37 | 725 | scopes::SearchMetadata meta(QLocale::system().name().toStdString(), m_formFactor.toStdString()); | 732 | scopes::SearchMetadata meta(QLocale::system().name().toStdString(), m_formFactor.toStdString()); |
38 | 726 | auto const userAgent = m_scopesInstance->userAgentString(); | 733 | auto const userAgent = m_scopesInstance->userAgentString(); |
39 | @@ -888,10 +895,6 @@ | |||
40 | 888 | 895 | ||
41 | 889 | unity::shell::scopes::SettingsModelInterface* Scope::settings() const | 896 | unity::shell::scopes::SettingsModelInterface* Scope::settings() const |
42 | 890 | { | 897 | { |
43 | 891 | if (m_settingsModel && m_scopesInstance) | ||
44 | 892 | { | ||
45 | 893 | m_settingsModel->update_child_scopes(m_scopesInstance->getAllMetadata()); | ||
46 | 894 | } | ||
47 | 895 | return m_settingsModel.data(); | 898 | return m_settingsModel.data(); |
48 | 896 | } | 899 | } |
49 | 897 | 900 | ||
50 | @@ -906,9 +909,20 @@ | |||
51 | 906 | 909 | ||
52 | 907 | void Scope::update_child_scopes() | 910 | void Scope::update_child_scopes() |
53 | 908 | { | 911 | { |
55 | 909 | if (m_settingsModel && m_scopesInstance) | 912 | // only run the update if child scopes have changed |
56 | 913 | if (m_childScopesDirty && m_settingsModel && m_scopesInstance) | ||
57 | 910 | { | 914 | { |
59 | 911 | m_settingsModel->update_child_scopes(m_scopesInstance->getAllMetadata()); | 915 | // reset the flag so that re-entering this method won't restart the update unnecessarily |
60 | 916 | m_childScopesDirty = false; | ||
61 | 917 | |||
62 | 918 | // just in case we have another update still running, wait here for it to complete | ||
63 | 919 | m_childScopesFuture.waitForFinished(); | ||
64 | 920 | |||
65 | 921 | // run the update in a seperate thread | ||
66 | 922 | m_childScopesFuture = QtConcurrent::run([this] | ||
67 | 923 | { | ||
68 | 924 | m_settingsModel->update_child_scopes(m_scopesInstance->getAllMetadata()); | ||
69 | 925 | }); | ||
70 | 912 | } | 926 | } |
71 | 913 | } | 927 | } |
72 | 914 | 928 | ||
73 | @@ -1258,6 +1272,11 @@ | |||
74 | 1258 | m_activationController->invalidate(); | 1272 | m_activationController->invalidate(); |
75 | 1259 | } | 1273 | } |
76 | 1260 | 1274 | ||
77 | 1275 | void Scope::invalidateChildScopes() | ||
78 | 1276 | { | ||
79 | 1277 | m_childScopesDirty = true; | ||
80 | 1278 | } | ||
81 | 1279 | |||
82 | 1261 | void Scope::invalidateResults() | 1280 | void Scope::invalidateResults() |
83 | 1262 | { | 1281 | { |
84 | 1263 | if (m_isActive) { | 1282 | if (m_isActive) { |
85 | 1264 | 1283 | ||
86 | === modified file 'src/Unity/scope.h' | |||
87 | --- src/Unity/scope.h 2016-03-07 08:29:14 +0000 | |||
88 | +++ src/Unity/scope.h 2016-04-19 08:05:18 +0000 | |||
89 | @@ -21,6 +21,7 @@ | |||
90 | 21 | #define NG_SCOPE_H | 21 | #define NG_SCOPE_H |
91 | 22 | 22 | ||
92 | 23 | // Qt | 23 | // Qt |
93 | 24 | #include <QFuture> | ||
94 | 24 | #include <QObject> | 25 | #include <QObject> |
95 | 25 | #include <QString> | 26 | #include <QString> |
96 | 26 | #include <QTimer> | 27 | #include <QTimer> |
97 | @@ -180,6 +181,7 @@ | |||
98 | 180 | void setSearchQueryString(const QString& search_query); | 181 | void setSearchQueryString(const QString& search_query); |
99 | 181 | 182 | ||
100 | 182 | public Q_SLOTS: | 183 | public Q_SLOTS: |
101 | 184 | void invalidateChildScopes(); | ||
102 | 183 | void invalidateResults(); | 185 | void invalidateResults(); |
103 | 184 | virtual void dispatchSearch(); | 186 | virtual void dispatchSearch(); |
104 | 185 | void setSearchInProgress(bool searchInProgress); | 187 | void setSearchInProgress(bool searchInProgress); |
105 | @@ -248,6 +250,9 @@ | |||
106 | 248 | bool m_favorite; | 250 | bool m_favorite; |
107 | 249 | bool m_initialQueryDone; | 251 | bool m_initialQueryDone; |
108 | 250 | 252 | ||
109 | 253 | bool m_childScopesDirty; | ||
110 | 254 | QFuture<void> m_childScopesFuture; | ||
111 | 255 | |||
112 | 251 | QMap<std::string, QList<std::shared_ptr<unity::scopes::CategorisedResult>>> m_category_results; | 256 | QMap<std::string, QList<std::shared_ptr<unity::scopes::CategorisedResult>>> m_category_results; |
113 | 252 | std::unique_ptr<CollectionController> m_searchController; | 257 | std::unique_ptr<CollectionController> m_searchController; |
114 | 253 | std::unique_ptr<CollectionController> m_activationController; | 258 | std::unique_ptr<CollectionController> m_activationController; |
115 | 254 | 259 | ||
116 | === modified file 'src/Unity/scopes.cpp' | |||
117 | --- src/Unity/scopes.cpp 2016-02-04 11:43:34 +0000 | |||
118 | +++ src/Unity/scopes.cpp 2016-04-19 08:05:18 +0000 | |||
119 | @@ -550,10 +550,12 @@ | |||
120 | 550 | qDebug() << "Refreshing scope metadata"; | 550 | qDebug() << "Refreshing scope metadata"; |
121 | 551 | refreshScopeMetadata(); | 551 | refreshScopeMetadata(); |
122 | 552 | Q_FOREACH(Scope::Ptr scope, m_scopes) { | 552 | Q_FOREACH(Scope::Ptr scope, m_scopes) { |
123 | 553 | scope->invalidateChildScopes(); | ||
124 | 553 | scope->invalidateResults(); | 554 | scope->invalidateResults(); |
125 | 554 | } | 555 | } |
126 | 555 | 556 | ||
127 | 556 | Q_FOREACH(Scope::Ptr scope, m_tempScopes) { | 557 | Q_FOREACH(Scope::Ptr scope, m_tempScopes) { |
128 | 558 | scope->invalidateChildScopes(); | ||
129 | 557 | scope->invalidateResults(); | 559 | scope->invalidateResults(); |
130 | 558 | } | 560 | } |
131 | 559 | } | 561 | } |
132 | 560 | 562 | ||
133 | === modified file 'src/Unity/settingsmodel.cpp' | |||
134 | --- src/Unity/settingsmodel.cpp 2016-03-30 12:34:12 +0000 | |||
135 | +++ src/Unity/settingsmodel.cpp 2016-04-19 08:05:18 +0000 | |||
136 | @@ -152,6 +152,8 @@ | |||
137 | 152 | 152 | ||
138 | 153 | QVariant SettingsModel::data(const QModelIndex& index, int role) const | 153 | QVariant SettingsModel::data(const QModelIndex& index, int role) const |
139 | 154 | { | 154 | { |
140 | 155 | QMutexLocker locker(&m_mutex); | ||
141 | 156 | |||
142 | 155 | int row = index.row(); | 157 | int row = index.row(); |
143 | 156 | QVariant result; | 158 | QVariant result; |
144 | 157 | 159 | ||
145 | @@ -247,6 +249,8 @@ | |||
146 | 247 | 249 | ||
147 | 248 | QVariant SettingsModel::value(const QString& id) const | 250 | QVariant SettingsModel::value(const QString& id) const |
148 | 249 | { | 251 | { |
149 | 252 | QMutexLocker locker(&m_mutex); | ||
150 | 253 | |||
151 | 250 | // Check for the setting id in the child scopes list first, in case the | 254 | // Check for the setting id in the child scopes list first, in case the |
152 | 251 | // aggregator is incorrectly using a scope id as a settings as well. | 255 | // aggregator is incorrectly using a scope id as a settings as well. |
153 | 252 | if (m_child_scopes_data_by_id.contains(id)) | 256 | if (m_child_scopes_data_by_id.contains(id)) |
154 | @@ -303,6 +307,8 @@ | |||
155 | 303 | 307 | ||
156 | 304 | void SettingsModel::update_child_scopes(QMap<QString, sc::ScopeMetadata::SPtr> const& scopes_metadata) | 308 | void SettingsModel::update_child_scopes(QMap<QString, sc::ScopeMetadata::SPtr> const& scopes_metadata) |
157 | 305 | { | 309 | { |
158 | 310 | QMutexLocker locker(&m_mutex); | ||
159 | 311 | |||
160 | 306 | if (!scopes_metadata.contains(m_scopeId) || | 312 | if (!scopes_metadata.contains(m_scopeId) || |
161 | 307 | !scopes_metadata[m_scopeId]->is_aggregator()) | 313 | !scopes_metadata[m_scopeId]->is_aggregator()) |
162 | 308 | { | 314 | { |
163 | @@ -346,15 +352,6 @@ | |||
164 | 346 | } | 352 | } |
165 | 347 | QString displayName = QString::fromStdString(_("Display results from %1")).arg(QString(scopes_metadata[id]->display_name().c_str())); | 353 | QString displayName = QString::fromStdString(_("Display results from %1")).arg(QString(scopes_metadata[id]->display_name().c_str())); |
166 | 348 | 354 | ||
167 | 349 | QSharedPointer<QTimer> timer(new QTimer()); | ||
168 | 350 | timer->setProperty("setting_id", id); | ||
169 | 351 | timer->setSingleShot(true); | ||
170 | 352 | timer->setInterval(m_settingsTimeout); | ||
171 | 353 | timer->setTimerType(Qt::VeryCoarseTimer); | ||
172 | 354 | connect(timer.data(), SIGNAL(timeout()), this, | ||
173 | 355 | SLOT(settings_timeout())); | ||
174 | 356 | m_child_scopes_timers[id] = timer; | ||
175 | 357 | |||
176 | 358 | QSharedPointer<Data> setting( | 355 | QSharedPointer<Data> setting( |
177 | 359 | new Data(id, displayName, QStringLiteral("boolean"), QVariantMap(), QVariant(), QVariant::Bool)); | 356 | new Data(id, displayName, QStringLiteral("boolean"), QVariantMap(), QVariant(), QVariant::Bool)); |
178 | 360 | 357 | ||
179 | @@ -364,13 +361,17 @@ | |||
180 | 364 | 361 | ||
181 | 365 | if (reset) { | 362 | if (reset) { |
182 | 366 | endResetModel(); | 363 | endResetModel(); |
183 | 367 | Q_EMIT countChanged(); | ||
184 | 368 | } | 364 | } |
185 | 365 | |||
186 | 366 | locker.unlock(); | ||
187 | 367 | Q_EMIT countChanged(); | ||
188 | 369 | } | 368 | } |
189 | 370 | 369 | ||
190 | 371 | bool SettingsModel::setData(const QModelIndex &index, const QVariant &value, | 370 | bool SettingsModel::setData(const QModelIndex &index, const QVariant &value, |
191 | 372 | int role) | 371 | int role) |
192 | 373 | { | 372 | { |
193 | 373 | QMutexLocker locker(&m_mutex); | ||
194 | 374 | |||
195 | 374 | int row = index.row(); | 375 | int row = index.row(); |
196 | 375 | QVariant result; | 376 | QVariant result; |
197 | 376 | 377 | ||
198 | @@ -400,6 +401,18 @@ | |||
199 | 400 | { | 401 | { |
200 | 401 | case Roles::RoleValue: | 402 | case Roles::RoleValue: |
201 | 402 | { | 403 | { |
202 | 404 | if (!m_child_scopes_timers.contains(data->id)) | ||
203 | 405 | { | ||
204 | 406 | QSharedPointer<QTimer> timer(new QTimer()); | ||
205 | 407 | timer->setProperty("setting_id", data->id); | ||
206 | 408 | timer->setSingleShot(true); | ||
207 | 409 | timer->setInterval(m_settingsTimeout); | ||
208 | 410 | timer->setTimerType(Qt::VeryCoarseTimer); | ||
209 | 411 | connect(timer.data(), SIGNAL(timeout()), this, | ||
210 | 412 | SLOT(settings_timeout())); | ||
211 | 413 | m_child_scopes_timers[data->id] = timer; | ||
212 | 414 | } | ||
213 | 415 | |||
214 | 403 | QSharedPointer<QTimer> timer = m_child_scopes_timers[data->id]; | 416 | QSharedPointer<QTimer> timer = m_child_scopes_timers[data->id]; |
215 | 404 | timer->setProperty("index", row - m_data.size()); | 417 | timer->setProperty("index", row - m_data.size()); |
216 | 405 | timer->setProperty("value", value); | 418 | timer->setProperty("value", value); |
217 | @@ -422,16 +435,20 @@ | |||
218 | 422 | 435 | ||
219 | 423 | int SettingsModel::count() const | 436 | int SettingsModel::count() const |
220 | 424 | { | 437 | { |
221 | 438 | QMutexLocker locker(&m_mutex); | ||
222 | 425 | return m_data.size() + m_child_scopes_data.size(); | 439 | return m_data.size() + m_child_scopes_data.size(); |
223 | 426 | } | 440 | } |
224 | 427 | 441 | ||
225 | 428 | bool SettingsModel::require_child_scopes_refresh() const | 442 | bool SettingsModel::require_child_scopes_refresh() const |
226 | 429 | { | 443 | { |
227 | 444 | QMutexLocker locker(&m_mutex); | ||
228 | 430 | return m_requireChildScopesRefresh; | 445 | return m_requireChildScopesRefresh; |
229 | 431 | } | 446 | } |
230 | 432 | 447 | ||
231 | 433 | void SettingsModel::settings_timeout() | 448 | void SettingsModel::settings_timeout() |
232 | 434 | { | 449 | { |
233 | 450 | QMutexLocker locker(&m_mutex); | ||
234 | 451 | |||
235 | 435 | QObject *timer = sender(); | 452 | QObject *timer = sender(); |
236 | 436 | if (!timer) | 453 | if (!timer) |
237 | 437 | { | 454 | { |
238 | @@ -454,6 +471,9 @@ | |||
239 | 454 | try | 471 | try |
240 | 455 | { | 472 | { |
241 | 456 | m_scopeProxy->set_child_scopes(m_child_scopes); | 473 | m_scopeProxy->set_child_scopes(m_child_scopes); |
242 | 474 | |||
243 | 475 | locker.unlock(); | ||
244 | 476 | Q_EMIT settingsChanged(); | ||
245 | 457 | } | 477 | } |
246 | 458 | catch (std::exception const& e) | 478 | catch (std::exception const& e) |
247 | 459 | { | 479 | { |
248 | @@ -488,6 +508,7 @@ | |||
249 | 488 | FileLock lock = unixLock(m_settings_path, true); | 508 | FileLock lock = unixLock(m_settings_path, true); |
250 | 489 | m_settings->sync(); // make sure the change to setting value is synced to fs | 509 | m_settings->sync(); // make sure the change to setting value is synced to fs |
251 | 490 | 510 | ||
252 | 511 | locker.unlock(); | ||
253 | 491 | Q_EMIT settingsChanged(); | 512 | Q_EMIT settingsChanged(); |
254 | 492 | } | 513 | } |
255 | 493 | catch(const unity::FileException& e) | 514 | catch(const unity::FileException& e) |
256 | 494 | 515 | ||
257 | === modified file 'src/Unity/settingsmodel.h' | |||
258 | --- src/Unity/settingsmodel.h 2016-03-30 12:34:12 +0000 | |||
259 | +++ src/Unity/settingsmodel.h 2016-04-19 08:05:18 +0000 | |||
260 | @@ -29,6 +29,7 @@ | |||
261 | 29 | 29 | ||
262 | 30 | #include <QAbstractListModel> | 30 | #include <QAbstractListModel> |
263 | 31 | #include <QList> | 31 | #include <QList> |
264 | 32 | #include <QMutex> | ||
265 | 32 | #include <QSharedPointer> | 33 | #include <QSharedPointer> |
266 | 33 | 34 | ||
267 | 34 | QT_BEGIN_NAMESPACE | 35 | QT_BEGIN_NAMESPACE |
268 | @@ -93,6 +94,7 @@ | |||
269 | 93 | void tryLoadSettings() const; | 94 | void tryLoadSettings() const; |
270 | 94 | 95 | ||
271 | 95 | protected: | 96 | protected: |
272 | 97 | mutable QMutex m_mutex; | ||
273 | 96 | QString m_scopeId; | 98 | QString m_scopeId; |
274 | 97 | unity::scopes::ScopeProxy m_scopeProxy; | 99 | unity::scopes::ScopeProxy m_scopeProxy; |
275 | 98 | int m_settingsTimeout; | 100 | int m_settingsTimeout; |
FAILED: Continuous integration, rev:302 jenkins. qa.ubuntu. com/job/ unity-scopes- shell-ci/ 433/ jenkins. qa.ubuntu. com/job/ unity-scopes- shell-vivid- amd64-ci/ 127 jenkins. qa.ubuntu. com/job/ unity-scopes- shell-vivid- armhf-ci/ 127 jenkins. qa.ubuntu. com/job/ unity-scopes- shell-vivid- armhf-ci/ 127/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ unity-scopes- shell-vivid- i386-ci/ 127 jenkins. qa.ubuntu. com/job/ unity-scopes- shell-wily- amd64-ci/ 90/console jenkins. qa.ubuntu. com/job/ unity-scopes- shell-wily- armhf-ci/ 90/console jenkins. qa.ubuntu. com/job/ unity-scopes- shell-wily- i386-ci/ 90/console
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/unity- scopes- shell-ci/ 433/rebuild
http://