From 676ddfbfb5910128b2e65dffd1e48c4be1268050 Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 17 Mar 2020 23:33:03 +0100 Subject: [PATCH] removed waitToken from GxsTokenService since it was only used directly by rsGenExchange to export keys --- libretroshare/src/gxs/rsgenexchange.cc | 24 +++++++--- .../src/retroshare/rsgxsifacehelper.h | 47 ++++++++++++++++--- libretroshare/src/retroshare/rstokenservice.h | 6 ++- 3 files changed, 63 insertions(+), 14 deletions(-) diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index ff54d48a1..a6d995c26 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -3461,20 +3461,32 @@ bool RsGenExchange::exportGroupBase64( if(groupId.isNull()) return failure("groupId cannot be null"); + // We have no blocking API here, so we need to const std::list groupIds({groupId}); RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; uint32_t token; - mDataAccess->requestGroupInfo( - token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds); - RsTokenService::GxsRequestStatus wtStatus = mDataAccess->waitToken(token); - if(wtStatus != RsTokenService::COMPLETE) - return failure( "waitToken(...) failed with: " + - std::to_string(wtStatus) ); + mDataAccess->requestGroupInfo( token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds); + + // provide a sync response: actually wait for the token. + std::chrono::milliseconds maxWait = std::chrono::milliseconds(10000); + std::chrono::milliseconds checkEvery = std::chrono::milliseconds(100); + + auto timeout = std::chrono::steady_clock::now() + maxWait; // wait for 10 secs at most + auto st = mDataAccess->requestStatus(token); + + while( !(st == RsTokenService::FAILED || st >= RsTokenService::COMPLETE) && std::chrono::steady_clock::now() < timeout ) + { + std::this_thread::sleep_for(checkEvery); + st = mDataAccess->requestStatus(token); + } + if(st != RsTokenService::COMPLETE) + return failure( "waitToken(...) failed with: " + std::to_string(st) ); uint8_t* buf = nullptr; uint32_t size; RsGxsGroupId grpId; + if(!getSerializedGroupData(token, grpId, buf, size)) return failure("failed retrieving GXS data"); diff --git a/libretroshare/src/retroshare/rsgxsifacehelper.h b/libretroshare/src/retroshare/rsgxsifacehelper.h index c04f13306..33015e1f0 100644 --- a/libretroshare/src/retroshare/rsgxsifacehelper.h +++ b/libretroshare/src/retroshare/rsgxsifacehelper.h @@ -390,20 +390,55 @@ protected: RsTokenService::GxsRequestStatus waitToken( uint32_t token, std::chrono::milliseconds maxWait = std::chrono::milliseconds(10000), - std::chrono::milliseconds checkEvery = std::chrono::milliseconds(20), + std::chrono::milliseconds checkEvery = std::chrono::milliseconds(100), bool auto_delete_if_unsuccessful=true) { - RsTokenService::GxsRequestStatus res = mTokenService.waitToken(token, maxWait, checkEvery); + #if defined(__ANDROID__) && (__ANDROID_API__ < 24) + auto wkStartime = std::chrono::steady_clock::now(); + int maxWorkAroundCnt = 10; +LLwaitTokenBeginLabel: +#endif + auto timeout = std::chrono::steady_clock::now() + maxWait; + auto st = requestStatus(token); - if(res != RsTokenService::COMPLETE && auto_delete_if_unsuccessful) + while( !(st == RsTokenService::FAILED || st >= RsTokenService::COMPLETE) && std::chrono::steady_clock::now() < timeout ) + { + std::this_thread::sleep_for(checkEvery); + st = requestStatus(token); + } + if(st != RsTokenService::COMPLETE && auto_delete_if_unsuccessful) cancelRequest(token); - else - { + +#if defined(__ANDROID__) && (__ANDROID_API__ < 24) + /* Work around for very slow/old android devices, we don't expect this + * to be necessary on newer devices. If it take unreasonably long + * something worser is already happening elsewere and we return anyway. + */ + if( st > RsTokenService::FAILED && st < RsTokenService::COMPLETE + && maxWorkAroundCnt-- > 0 ) + { + maxWait *= 10; + checkEvery *= 3; + Dbg3() << __PRETTY_FUNCTION__ << " Slow Android device " + << " workaround st: " << st + << " maxWorkAroundCnt: " << maxWorkAroundCnt + << " maxWait: " << maxWait.count() + << " checkEvery: " << checkEvery.count() << std::endl; + goto LLwaitTokenBeginLabel; + } + Dbg3() << __PRETTY_FUNCTION__ << " lasted: " + << std::chrono::duration_cast( + std::chrono::steady_clock::now() - wkStartime ).count() + << "ms" << std::endl; + +#endif + + { RS_STACK_MUTEX(mMtx); mActiveTokens.erase(token); } - return res; + return st; } private: diff --git a/libretroshare/src/retroshare/rstokenservice.h b/libretroshare/src/retroshare/rstokenservice.h index e48df29ad..7f801927f 100644 --- a/libretroshare/src/retroshare/rstokenservice.h +++ b/libretroshare/src/retroshare/rstokenservice.h @@ -222,6 +222,7 @@ public: */ virtual bool cancelRequest(const uint32_t &token) = 0; +#ifdef TO_REMOVE /** * Block caller while request is being processed. * Useful for blocking API implementation. @@ -231,8 +232,8 @@ public: */ RsTokenService::GxsRequestStatus waitToken( uint32_t token, - std::chrono::milliseconds maxWait = std::chrono::milliseconds(500), - std::chrono::milliseconds checkEvery = std::chrono::milliseconds(2), + std::chrono::milliseconds maxWait = std::chrono::milliseconds(10000), + std::chrono::milliseconds checkEvery = std::chrono::milliseconds(20), bool auto_delete_if_unsuccessful=true) { #if defined(__ANDROID__) && (__ANDROID_API__ < 24) @@ -276,6 +277,7 @@ LLwaitTokenBeginLabel: return st; } +#endif RS_SET_CONTEXT_DEBUG_LEVEL(2) };