Skip to content

Device driver thread safety requirements/assumptions #1018

@diggit

Description

@diggit

While working on #1017 (generally RigolOscilloscope), I have noticed mutex locking in several places. So I guess some thread safety is required.

From reading of LeCroyOscilloscope I've got a feeling all runtime member data which are not constant since object creation (like m_transport) should have exclusive access.
But there are places where for example m_channelsEnabled access is exclusive

lock_guard<recursive_mutex> lock2(m_cacheMutex);
if(m_channelsEnabled.find(i) != m_channelsEnabled.end())
return m_channelsEnabled[i];
}
//Analog
if(i < m_analogChannelCount)
{
//See if the channel is enabled, hide it if not
string cmd = GetOscilloscopeChannel(i)->GetHwname() + ":TRACE?";
auto reply = m_transport->SendCommandQueuedWithReply(cmd);
lock_guard<recursive_mutex> lock2(m_cacheMutex);
if(reply.find("OFF") == 0) //may have a trailing newline, ignore that
m_channelsEnabled[i] = false;
else
m_channelsEnabled[i] = true;
}
//Digital
else if( (i >= m_digitalChannelBase) && (i < (m_digitalChannelBase + m_digitalChannelCount) ) )
{
//If the digital channel *group* is off, don't show anything
auto reply = Trim(m_transport->SendCommandQueuedWithReply("VBS? 'return = app.LogicAnalyzer.Digital1.UseGrid'"));
if(reply == "NotOnGrid")
{
lock_guard<recursive_mutex> lock2(m_cacheMutex);
m_channelsEnabled[i] = false;
return false;
}
//See if the channel is on
//Note that GetHwname() returns Dn, as used by triggers, not Digitaln, as used here
size_t nchan = i - m_digitalChannelBase;
reply = Trim(m_transport->SendCommandQueuedWithReply(
string("VBS? 'return = app.LogicAnalyzer.Digital1.Digital") + to_string(nchan) + "'"));
lock_guard<recursive_mutex> lock2(m_cacheMutex);
if(reply == "0")
m_channelsEnabled[i] = false;
else
m_channelsEnabled[i] = true;

, but not in other
return m_channelsEnabled[i];
}
(fame fcn though).

Description of mutex itself does not say much

//Mutexing for thread safety
std::recursive_mutex m_cacheMutex;

C++ concurrent access is tricky thing due to the C++ memory model. Today compilers are quite careful so the code often works, even though it does not follow the rules.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingdriverHardware drivers

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions