Merge lp:~marcustomlinson/unity-scope-click/lp-1591422 into lp:unity-scope-click

Proposed by Marcus Tomlinson
Status: Merged
Approved by: dobey
Approved revision: 463
Merged at revision: 463
Proposed branch: lp:~marcustomlinson/unity-scope-click/lp-1591422
Merge into: lp:unity-scope-click
Diff against target: 56 lines (+20/-4)
2 files modified
libclickscope/click/preview.cpp (+10/-2)
libclickscope/click/ubuntuone_credentials.cpp (+10/-2)
To merge this branch: bzr merge lp:~marcustomlinson/unity-scope-click/lp-1591422
Reviewer Review Type Date Requested Status
dobey (community) Approve
PS Jenkins bot continuous-integration Pending
Review via email: mp+297269@code.launchpad.net

Commit message

Ignore promise_already_satisfied exceptions thrown from getCredentials() signal handlers

To post a comment you must log in.
Revision history for this message
Marcus Tomlinson (marcustomlinson) wrote :

Looking at:

    https://errors.ubuntu.com/problem/f271ff40a203e6d22ab0bf36beb8f6f6adddb90a,

we can see that the crash originates from:

    ubuntuone_credentials.cpp:63 -> "promise.set_value(token);"

Digging a little deeper into the future source, _M_set_result() seems to only throw std::future_error for the promise_already_satisfied condition. This unhandled exception is tearing down the scope.

We have 2 places in code where getCredentials() is called:
    click::CredentialsService::getToken()
    & InstalledPreview::get_consumer_key()

I suspect that during "QCoreApplication::processEvents();" in click::CredentialsService::getToken(), we may risk processing 2 getCredentials() calls in parallel, causing multiple callbacks into the signal handler.

This change adds a safety net which may or may not make the issue go away completely, but it certainly shouldn't make things any worse.

Revision history for this message
dobey (dobey) wrote :

The basics of this look sound, but would be nice if the statements were structured consistent with the rest of the code, like so:

try {
    promise.set_value();
} catch (const std::future_error&) {
    // Ignore promise_already_satisfied
}

review: Needs Fixing
463. By Marcus Tomlinson

Fixed formatting

Revision history for this message
Marcus Tomlinson (marcustomlinson) wrote :

> The basics of this look sound, but would be nice if the statements were
> structured consistent with the rest of the code, like so:
>
> try {
> promise.set_value();
> } catch (const std::future_error&) {
> // Ignore promise_already_satisfied
> }

Sure, done.

Revision history for this message
dobey (dobey) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'libclickscope/click/preview.cpp'
--- libclickscope/click/preview.cpp 2016-06-01 13:36:55 +0000
+++ libclickscope/click/preview.cpp 2016-06-14 17:24:57 +0000
@@ -833,13 +833,21 @@
833 [&promise, &sso](const UbuntuOne::Token& token) {833 [&promise, &sso](const UbuntuOne::Token& token) {
834 qDebug() << "Credentials found";834 qDebug() << "Credentials found";
835 sso.clear();835 sso.clear();
836 promise.set_value(token.consumerKey().toStdString());836 try {
837 promise.set_value(token.consumerKey().toStdString());
838 } catch (const std::future_error&) {
839 // Ignore promise_already_satisfied
840 }
837 });841 });
838 QObject::connect(sso.data(), &click::CredentialsService::credentialsNotFound,842 QObject::connect(sso.data(), &click::CredentialsService::credentialsNotFound,
839 [&promise, &sso]() {843 [&promise, &sso]() {
840 qDebug() << "No credentials found";844 qDebug() << "No credentials found";
841 sso.clear();845 sso.clear();
842 promise.set_value("");846 try {
847 promise.set_value("");
848 } catch (const std::future_error&) {
849 // Ignore promise_already_satisfied
850 }
843 });851 });
844852
845 sso->getCredentials();853 sso->getCredentials();
846854
=== modified file 'libclickscope/click/ubuntuone_credentials.cpp'
--- libclickscope/click/ubuntuone_credentials.cpp 2016-05-10 13:42:12 +0000
+++ libclickscope/click/ubuntuone_credentials.cpp 2016-06-14 17:24:57 +0000
@@ -60,14 +60,22 @@
60 &u1::SSOService::credentialsFound,60 &u1::SSOService::credentialsFound,
61 [this, &promise](const u1::Token& token) {61 [this, &promise](const u1::Token& token) {
62 emit credentialsFound(_token);62 emit credentialsFound(_token);
63 promise.set_value(token);63 try {
64 promise.set_value(token);
65 } catch (const std::future_error&) {
66 // Ignore promise_already_satisfied
67 }
64 });68 });
65 auto notfound = QObject::connect(ssoService.data(),69 auto notfound = QObject::connect(ssoService.data(),
66 &u1::SSOService::credentialsNotFound,70 &u1::SSOService::credentialsNotFound,
67 [this, &promise]() {71 [this, &promise]() {
68 qWarning() << "No Ubuntu One token found.";72 qWarning() << "No Ubuntu One token found.";
69 emit credentialsNotFound();73 emit credentialsNotFound();
70 promise.set_value(u1::Token());74 try {
75 promise.set_value(u1::Token());
76 } catch (const std::future_error&) {
77 // Ignore promise_already_satisfied
78 }
71 });79 });
7280
73 getCredentials();81 getCredentials();

Subscribers

People subscribed via source and target branches