Skip to content
This repository was archived by the owner on Dec 20, 2023. It is now read-only.

Commit 866a30f

Browse files
authored
Merge pull request #55 from openweave/bug/szewczyk/wrmp-long-inactivity
Fix timeout computation for WRMP after long inactivity
2 parents c5715bc + a9f517c commit 866a30f

File tree

1 file changed

+26
-6
lines changed

1 file changed

+26
-6
lines changed

src/lib/core/WeaveExchangeMgr.cpp

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1206,6 +1206,16 @@ void WeaveExchangeManager::RetransPendingAppGroupMsgs(uint64_t peerNodeId)
12061206
uint32_t WeaveExchangeManager::GetTickCounterFromTimeDelta (uint64_t newTime,
12071207
uint64_t oldTime)
12081208
{
1209+
// Note on math: we have a utility function that will compute U64 var / U32
1210+
// compile-time const => U32. At the moment, we are leaving
1211+
// mWRMPTimerInterval as a member variable in WeaveExchangeManager, however,
1212+
// given its current usage, it could be replaced by a compile time const.
1213+
// Should we make that change, I would recommend making the timeDelta a u64,
1214+
// and replacing the plain 32-bit division below with the utility function.
1215+
// Note that the 32bit timeDelta overflows at around 46 days; pursuing the
1216+
// above code strategy would extend that overflow by a factor if 200 given
1217+
// the default mWRMPPTimerInterval. If and when such change is made, please
1218+
// update the comment around line 1426.
12091219
uint32_t timeDelta = static_cast<uint32_t>(newTime - oldTime);
12101220

12111221
return (timeDelta / mWRMPTimerInterval);
@@ -1334,7 +1344,7 @@ void WeaveExchangeManager::WRMPExpireTicks(void)
13341344
{
13351345
uint64_t now = 0;
13361346
ExchangeContext* ec = NULL;
1337-
uint16_t deltaTicks;
1347+
uint32_t deltaTicks;
13381348

13391349
//Process Ack Tables for all ExchangeContexts
13401350
ec = (ExchangeContext *)ContextPool;
@@ -1345,8 +1355,14 @@ void WeaveExchangeManager::WRMPExpireTicks(void)
13451355
// to the previous tick. If we are between tick boundaries, the extra time since the
13461356
// last virtual tick is not accounted for here (it will be accounted for when resetting
13471357
// the WRMP timer)
1358+
13481359
deltaTicks = GetTickCounterFromTimeDelta(now, mWRMPTimeStampBase);
13491360

1361+
// Note on math involving deltaTicks: in the code below, deltaTicks, a
1362+
// 32-bit value, is being subtracted from 16-bit expiration times. In each
1363+
// case, we compare the expiration time prior to subtraction to guard
1364+
// against underflow.
1365+
13501366
#if defined(WRMP_TICKLESS_DEBUG)
13511367
WeaveLogProgress(ExchangeManager, "WRMPExpireTicks at %" PRIu64 ", %" PRIu64 ", %u", now, mWRMPTimeStampBase, deltaTicks);
13521368
#endif
@@ -1408,11 +1424,15 @@ void WeaveExchangeManager::WRMPExpireTicks(void)
14081424

14091425
// Re-Adjust the base time stamp to the most recent tick boundary
14101426

1411-
// Note on math: because we're really multiplying two 16-bit
1412-
// unsigned numbers, we know that the result will fit in a 32-bit
1413-
// unsigned without overflow. Consequently, casting operands to
1414-
// 32-bit, and performing 32-bit multiplication is correct.
1415-
mWRMPTimeStampBase += static_cast<uint64_t>( static_cast<uint32_t>(deltaTicks) * static_cast<uint32_t>(mWRMPTimerInterval));
1427+
// Note on math: we cast deltaTicks to a 64bit value to ensure that that we
1428+
// produce a full 64 bit product. At the moment this is a bit of a moot
1429+
// conversion: right now, the math in GetTickCounterFromTimeDelta ensures
1430+
// that the deltaTicks * mWRMPTimerTick fits in 32bits. However, I'm
1431+
// leaving the math in this form, because I'm leaving the door open to
1432+
// refactoring the division in GetTickCounterFromTimeDelta to use our
1433+
// specialized utility function that computes U64 var/ U32 compile-time
1434+
// const ==> U32
1435+
mWRMPTimeStampBase += static_cast<uint64_t>(deltaTicks) * mWRMPTimerInterval;
14161436
#if defined(WRMP_TICKLESS_DEBUG)
14171437
WeaveLogProgress(ExchangeManager, "WRMPExpireTicks mWRMPTimeStampBase to %" PRIu64, mWRMPTimeStampBase);
14181438
#endif

0 commit comments

Comments
 (0)