Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Core: Fixed a bug that may have caused drops in the SHM Layer #1198

Merged
merged 2 commits into from
Sep 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 24 additions & 15 deletions ecal/core/src/io/ecal_memfile_pool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ namespace eCAL
m_created(false),
m_do_stop(false),
m_is_observing(false),
m_timeout_read(0)
m_time_of_last_life_signal(std::chrono::steady_clock::now())
{
}

Expand Down Expand Up @@ -137,7 +137,7 @@ namespace eCAL
{
if (!m_is_observing) return false;

m_timeout_read = 0;
m_time_of_last_life_signal = std::chrono::steady_clock::now();

return true;
}
Expand All @@ -150,21 +150,38 @@ namespace eCAL
// buffer to store memory file content
std::vector<char> receive_buffer;

// Boolean that tells whether the SHM file has new data that we have NOT already accessed
bool has_unprocessed_data = false;

// runs as long as there is no timeout and no external stop request
while((m_timeout_read < timeout_) && !m_do_stop)
while(std::chrono::steady_clock::now() - std::chrono::steady_clock::time_point(m_time_of_last_life_signal) < std::chrono::milliseconds(timeout_)
&& !m_do_stop)
{
// loop start in ms
auto loop_start = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
if (!has_unprocessed_data)
{
// Only wait for the new-data-event, if we haven't processed the data, yet
// check for memory file update event from shm writer (20 ms)
has_unprocessed_data = gWaitForEvent(m_event_snd, 20);

if (has_unprocessed_data)
{
// We got a signal from the publisher! It is alive! So we reset the time since the last live signal
m_time_of_last_life_signal = std::chrono::steady_clock::now();
}
}

// check for memory file update event from shm writer (20 ms)
if(gWaitForEvent(m_event_snd, 20))
// If we have unprocessed data, we try to access (and process!) it
if(has_unprocessed_data)
{
// last chance to stop ..
if(m_do_stop) break;

// try to open memory file (timeout 5 ms)
if(m_memfile.GetReadAccess(5))
{
// We have gotten access! Now the data qualifies as processed, so next loop we will wait for the signal for new data, again.
has_unprocessed_data = false;

// read the file header
SMemFileHeader mfile_hdr;
ReadFileHeader(mfile_hdr);
Expand Down Expand Up @@ -240,14 +257,6 @@ namespace eCAL
}
}
}

// reset timeout
m_timeout_read = 0;
}
else
{
// increase timeout in ms
m_timeout_read += std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count() - loop_start;
}
}

Expand Down
2 changes: 1 addition & 1 deletion ecal/core/src/io/ecal_memfile_pool.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ namespace eCAL
std::atomic<bool> m_do_stop;
std::atomic<bool> m_is_observing;

std::atomic<long long> m_timeout_read;
std::atomic<std::chrono::steady_clock::time_point> m_time_of_last_life_signal;

MemFileDataCallbackT m_data_callback;

Expand Down
Loading