Skip to content

Fixed freeze in the polling loop#1688

Merged
aleksandr-voitenko merged 1 commit intostagingfrom
fix-freeze-in-polling-loop
May 6, 2026
Merged

Fixed freeze in the polling loop#1688
aleksandr-voitenko merged 1 commit intostagingfrom
fix-freeze-in-polling-loop

Conversation

@aleksandr-voitenko
Copy link
Copy Markdown
Collaborator

@aleksandr-voitenko aleksandr-voitenko commented May 6, 2026

Description

This PR fixes a rare freeze/stall condition in OBS client polling workers caused by millisecond sleep arithmetic underflowing when a poll cycle takes longer than the configured interval.

Motivation and Context

In worker-signals.hpp and similarly in nodeobs_service.cpp the loop does roughly:

auto dur = elapsed_time_for_this_poll;
totalSleepMS = sleepIntervalMS - dur.count();
std::this_thread::sleep_for(std::chrono::milliseconds(totalSleepMS));

The intent is fine:

target interval:  33ms
work took:        10ms
sleep:            23ms

The bug appears when the work takes longer than the target interval:

target interval:   33ms
work took:         80ms
desired sleep:     0ms
actual expression: 33 - 80 = -47

But totalSleepMS is declared as size_t, which is unsigned. A negative value assigned to an unsigned integer wraps to a huge positive value. On a 64-bit build, -47 can become something like:
18446744073709551569

A minimal program that reproduces the issue looks like this:

#include <iostream>
#include <chrono>
#include <thread>

int main()
{
    std::size_t totalSleepMS = 0;
    uint32_t sleepIntervalMS = 33; // 33ms expected polling interval
    
    auto tp_start = std::chrono::high_resolution_clock::now();
    
    std::this_thread::sleep_for(std::chrono::milliseconds(50)); // Doing heavy work | 50ms > 33ms
    
    auto tp_end = std::chrono::high_resolution_clock::now();
	auto dur = std::chrono::duration_cast<std::chrono::milliseconds>(tp_end - tp_start);
	totalSleepMS = sleepIntervalMS - dur.count();
    
    std::cout << "totalSleepMS: " << totalSleepMS << std::endl; // totalSleepMS: 18446744073709551599
    // https://media.makeameme.org/created/to-infinity-and-5c0a9f.jpg
    //std::this_thread::sleep_for(std::chrono::milliseconds(totalSleepMS));
}

How Has This Been Tested?

Separate minimal test program.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)

@aleksandr-voitenko aleksandr-voitenko merged commit e106057 into staging May 6, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants