Mutex inside templated struct causes segmentation fault - c++

For exchanging data between classes, I use a kind of "main-hub-class", from which each other class can access the data.
Now, to make this thread-safe I came up with a templated struct that holds a variable and a boost::shared_mutex for that variable:
class DataExchange {
[...]
template <typename T>
struct ShareDataEntry {
T value;
boost::shared_mutex _mutex;
};
SharedDataEntry<int> ultraSonicValue;
[...]
}
In the .cpp I am trying to use that like this:
void DataExchange::setUltrasSonicValue(int _value) {
boost::unique_lock<boost::shared_mutex> lock ( ultraSonicValue._mutex ); // <-- this segfaults
ultraSonicValue.value = _value;
lock.unlock();
}
From gdb, I get the error
__GI____pthread_mutex_lock (mutex=0x58) at pthread_mutex_lock.c:66
66 pthread_mutex_lock.c: No such file or directory
What am I doing wrong? My guess is that the mutex isn't initialized? But how (and where) would I do that?
EDIT
Updated code sample, now showing everything I use, also with a test for the problem I described:
DataExchange.hpp:
#pragma once
#include <boost/thread.hpp>
class DataExchange {
private:
DataExchange();
DataExchange(DataExchange const&) {};
DataExchange& operator=(DataExchangeconst&) { return *instance; };
static DataExchange* instance;
template <typename T>
struct ShareDataEntry {
T value;
boost::shared_mutex _mutex;
};
// simple int with extra mutex
int testIntOne;
boost::shared_mutex testIntOne_M;
// int in my struct
SharedDataEntry<int> testIntTwo;
public:
static DataExchange* getInstance();
~DataExchange() { delete instance; };
void setTestIntOne(int _tmp);
int getTestIntOne();
void setTestIntTwo(int _tmp);
int getTestIntTwo();
}
DataExchange.cpp:
#include "infrastructure/DataExchange.hpp"
DataExchange* DataExchange::instance = NULL;
DataExchange::DataExchange() {};
DataExchange* DataExchange::getInstance() {
if (instance == NULL) instance = new DataExchange;
return instance;
}
void DataExchange::setTestIntOne(int _tmp) {
boost::unique_lock<boost::shared_mutex> lock ( testIntOne_M ); // this is now where the segfault occurs
testIntOne = _tmp;
lock.unlock();
}
int DataExchange::getTestIntOne() {
boost::shared_lock<boost::shared_mutex> lock ( testIntOne_M );
return testIntOne;
}
void DataExchange::setTestIntTwo(int _tmp) {
boost::unique_lock<boost::shared_mutex> lock ( testIntTwo._mutex );
testIntTwo.value = _tmp;
lock.unlock();
}
int DataExchange::getTestIntTwo() {
boost::shared_lock<boost::shared_mutex> lock ( testIntTwo._mutex );
return testIntTwo.value;
}
main.cpp:
#inlcude "infarstructure/DataExchange.hpp"
int main(int argc, char *argv[]) {
DataExchange* dataExchange = DataExchange::getInstance();
// this line segfaults already, altough I was pretty sure it worked before
dataExchange->setTestIntOne(5);
cout << dataExchange->getTestIntOne() << "\n";
dataExchange->setTestIntTwo(-5);
cout << dataExchange->getTestIntTwo() << "\n";
return 0;
}
Does it segfault because the mutex wasn't initialized?
Also, I am very sure it worked earlier, at least the first way (without the struct).
Second Edit:
Alright, everything is working fine now. It was a stupid mistake on my part. Both approaches work flawlessly - as long as one initializes the DataExchange object.

Related

Writing a thread safe optimized Datastore class

I am trying to write a thread safe datastore class.
This class object is shared with between many threads in Generator and Consumer, where the class members can be set or get.
By calling setDatastore() the object is set for usage at different threads.
Below is my code,
#ifndef IF_DATA_STORE_H
#define IF_DATA_STORE_H
#include <mutex>
#include <shared_mutex>
#include <memory>
class DataType1{public:int value;};
class DataType2{public:int value;};
class DataStore
{
public:
DataStore(): _member1(), _member2(){}
~DataStore(){}
// for member1
void setMember1(const DataType1& val)
{
std::unique_lock lock(_mtx1); // no one can read/write!
_member1 = val;
}
const DataType1& getMember1() const
{
std::shared_lock lock(_mtx1); // multiple threads can read!
return _member1;
}
// for member2
void setMember2(const DataType2& val)
{
std::unique_lock lock(_mtx2); // no one can read/write!
_member2 = val;
}
const DataType2& getMember2() const
{
std::shared_lock lock(_mtx2); // multiple threads can read!
return _member2;
}
private:
mutable std::shared_mutex _mtx1;
mutable std::shared_mutex _mtx2;
DataType1 _member1;
DataType2 _member2;
// different other member!
};
// now see where data is generated/consumed!
class Generator
{
public:
void start(){/* start thread!*/}
void setDataStore(std::shared_ptr<DataStore> store)
{
_store = store;
}
void threadRoutine() //this is called from different thread and updating values
{
// some code...
{
_data.value = 10; // keep a local updated copy of data!
_store->setMember1(_data);
}
}
private:
std::shared_ptr<DataStore> _store;
DataType1 _data;
};
class Consumer
{
public:
void start(){/* start thread!*/}
void setDataStore(std::shared_ptr<DataStore> store)
{
_store = store;
}
void threadRoutine() // running a check on datastore every 1sec
{
// some code...
auto val = _store->getMember1();
// do something..
}
private:
std::shared_ptr<DataStore> _store;
};
// fianlly start all!
int main()
{
// somewhere in main thread
std::shared_ptr<DataStore> store;
Consumer c; Generator g;
c.setDataStore(store); c.start();
g.setDataStore(store); g.start();
}
#endif
Questions:
Is there any other way than creating multiple shared mutex for each member?
In Generator.threadRoutine() if I keep a local copy of DataType1 does this cause high memory issues (I see high cpu and memory) when this block called frequently, don't if this is the root cause of it.
Any other better way suggested?

losing data when using dynamic_cast to derive object

when I push fifoGroundEvtEntry data inside list_fifoGroundEvt from another thread using sender::GetInstance()->getDataCollector()->pushGroundEventFifo(entry); and when I debug puting one breakpoint inside pushGroundEventFifo function I can see the correct value of grdEvt.x and grdEvt.y inside list_fifoGroundEvt.
then when I call test method inside transmit methode and I pute breakpoint inside test. I see wrong values inside list_fifoGroundEvt-> grdEvt.y = 0x00F12751 for entry.y = 2 !
PS: transmit() is a thread and I start it using sender::GetInstance()->start() (I didn't put all functions I put only those who have a link with the problem )
the thread is starting after pushing entries inside list_fifoGroundEvt
#include "stdafx.h"
#include <iostream>
#include <list>
struct fifoEvtEntry {
virtual ~fifoEvtEntry() {}
int x;
};
struct fifoGroundEvtEntry : fifoEvtEntry
{
int y;
};
class collector {
public:
void pushGroundEventFifo(fifoEvtEntry& entry) {
if (fifoGroundEvtEntry* grdEvt = dynamic_cast<fifoGroundEvtEntry*>(&entry))
{
list_fifoGroundEvt.push_back(grdEvt);
}
}
void test() {
if (fifoGroundEvtEntry* grdEvt = dynamic_cast<fifoGroundEvtEntry*>(list_fifoGroundEvt.front()))
{
std::cout << grdEvt ->y << std::endl;
}
list_fifoGroundEvt.pop_front();
}
private:
std::list<fifoEvtEntry*> list_fifoGroundEvt;
};
class sender {
public:
sender(collector* data):_data(data) {};
~sender() {};
static void setInstance(collector* data) {
_instance = new sender(data);
}
static sender* GetInstance() {
return _instance;
}
void transmit() {
// this is a thread function
// ..
_data->test();
}
collector* getDataCollector(){
return _data;
}
static sender* _instance;
private:
collector* _data;
};
int main(){
return 0;
}

Trying to access an object that is being destroyed

I have an object which contains a thread which indirectly accesses this object like so:
#include <iostream>
#include <thread>
#include <atomic>
class A;
class Manager
{
public:
Manager(void) = default;
void StartA(void)
{
a = std::make_unique<A>(*this);
}
void StopA(void)
{
a = nullptr;
}
A& GetA(void)
{
return *a;
}
private:
std::unique_ptr<A> a;
};
class A
{
public:
A(Manager& manager)
: manager{manager},
shouldwork{true},
thread{[&]{ this->Run(); }}
{
}
~A(void)
{
shouldwork = false;
thread.join();
}
private:
Manager& manager;
std::atomic<bool> shouldwork;
std::thread thread;
void Run(void)
{
while (shouldwork)
{
// Here goes a lot of code which calls manager.GetA().
auto& a = manager.GetA();
}
}
};
int main(int argc, char* argv[])
try
{
Manager man;
man.StartA();
man.StopA();
}
catch (std::exception& e)
{
std::cerr << "Exception caught: " << e.what() << '\n';
}
catch (...)
{
std::cerr << "Unknown exception.\n";
}
The problem is that when one thread calls Manager::StopA and enters destructor of A, the thread inside A segfaults at Manager::GetA. How can I fix this?
In StopA() you set a = nullptr;, this in turn destroys the a object and all further access to its members result in undefined behaviour (a likely cause the segmentation fault).
Simply moving the a = nullptr; to the destructor of the Manager could resolve this problem. Even better, allow the RAII mechanism of the std::unique_ptr to destroy the a object when the destructor of the Manager runs (i.e. remove the line of code completely).
With active object implementations, careful control of the member variables is important, especially the "stop variable/control" (here the shouldwork = false;). Allow the manager to access the variable directly or via a method to stop the active object before its destruction.
Some of the code here looks out of place or obscure, e.g. a = std::make_unique<A>(*this);. A redesign could help simplify some of the code. The Manager class could be removed.
class A
{
public:
A(): shouldwork{true}, thread{[&]{ this->Run(); }}
{
}
void StopA()
{
shouldwork = false;
thread.join();
}
private:
std::atomic<bool> shouldwork;
std::thread thread;
void Run(void)
{
while (shouldwork)
{
// code...
}
}
};
The code is modelled along the lines of std::thread, were the stopping of the tread is more controlled before an attempt is made to join it. The destructor is left empty in this case, to mimic the termination (calling std::terminate) result, as is the case with the standard thread library. Threads must be explicitly joined (or detached) before destruction.
Re-introducing the Manager, the code could look as follows;
class A
{
public:
A() : shouldwork{true}, thread{[&]{ this->Run(); }} {}
void StopA() { shouldwork = false; thread.join(); }
private:
void Run();
std::atomic<bool> shouldwork;
std::thread thread;
};
class Manager
{
public:
Manager() = default;
void StartA(void)
{
a = std::make_unique<A>();
}
void StopA(void)
{
a->StopA();
}
A& GetA(void)
{
return *a;
}
private:
std::unique_ptr<A> a;
};
void A::Run()
{
while (shouldwork)
{
// Here goes a lot of code which calls manager.GetA().
auto& a = manager.GetA();
}
}
And your main remains as it is.

Possibility of segmentation fault with mutex in class with multithreading

With multiple threads (std::async) sharing an instance of the following class through a shared_ptr, is it possible to get a segmentation fault in this part of the code? If my understanding of std::mutex is correct, mutex.lock() causes all other threads trying to call mutex.lock() to block until mutex.unlock() is called, thus access to the vector should happen purely sequentially. Am I missing something here? If not, is there a better way of designing such a class (maybe with a std::atomic_flag)?
#include <mutex>
#include <vector>
class Foo
{
private:
std::mutex mutex;
std::vector<int> values;
public:
Foo();
void add(const int);
int get();
};
Foo::Foo() : mutex(), values() {}
void Foo::add(const int value)
{
mutex.lock();
values.push_back(value);
mutex.unlock();
}
int Foo::get()
{
mutex.lock();
int value;
if ( values.size() > 0 )
{
value = values.back();
values.pop_back();
}
else
{
value = 0;
}
mutex.unlock();
return value;
}
Disclaimer: The default value of 0 in get() is intended as it has a special meaning in the rest of the code.
Update: The above code is exactly as I use it, except for the typo push_Back of course.
Other than not using RAII to acquire the lock and using size() > 0 instead of !empty(), the code looks fine. This is exactly how a mutex is meant to be used and this is the quintessential example of how and where you need a mutex.
As Andy Prowl pointed out, instances can't be copy constructed or copy assigned.
Here is the "improved" version:
#include <mutex>
#include <vector>
class Foo {
private:
std::mutex mutex;
typedef std::lock_guard<std::mutex> lock;
std::vector<int> values;
public:
Foo();
void add(int);
int get();
};
Foo::Foo() : mutex(), values() {}
void Foo::add(int value) {
lock _(mutex);
values.push_back(value);
}
int Foo::get() {
lock _(mutex);
int value = 0;
if ( !values.empty() )
{
value = values.back();
values.pop_back();
}
return value;
}
with RAII for acquiring the mutex etc.

Remove the defines in this safeguard mutex example

-edit- i cant experiment ATM but will tonight. I am thinking maybe a typedef can be used to hold mut and can be used to declare a var. But my initial thought is typedefs don't play nice with templates so i'll have to check later tonight (for now, to class)
I was looking at this piece of code shown below and i was wondering how it might be possible to implement without using defines.
Since I cant compile the code (i don't have any mutex/multithreading libs currently installed) i'll just look at the code and think it out.
It seems like one can completely implement PROTECTED_WITH by inheriting a template class. The problem is now PROTECTED_MEMBER. It uses a name with ## to create a variable. This isnt much of a problem because we create a class which holds the variable with the () operator to make it appear as a function. However accessing is_held() the problem as i would like not to pass this or mut_ in.
My gut says with out of the box thinking its possible to solve this without defines and without passing in to each variable a this, function ptr or reference. I'll allow everyone to cheat and use c++0x features.
template<typename Mutex>
class TestableMutex {
public:
void lock() { m.lock(); id = this_thread::get_id(); }
void unlock() { id = 0; m.unlock(); }
bool try_lock() { bool b = m.try_lock();
if( b ) id = this_thread::get_id();
return b; }
bool is_held() { return id == this_thread::get_id(); }
private:
Mutex m;
atomic<thread::id> id;
// for recursive mutexes, add a count
};
#define PROTECTED_WITH(MutType) \
public: void lock() { mut_.lock(); } \
public: bool try_lock() { return mut_.try_lock(); } \
public: void unlock() { mut_.unlock(); } \
private: TestableMutex<MutType> mut_;
#define PROTECTED_MEMBER(Type,name) \
public: Type& name() { assert(mut_.is_held()); return name##_; } \
private: Type name##_;
struct MyData {
PROTECTED_WITH( some_mutex_type );
PROTECTED_MEMBER( vector<int>, v );
PROTECTED_MEMBER( Widget*, w );
};
You can use an explicit specialization containing using declarations to list the objects protected by the mutex. Then use a base class to "pass" the access out to the user via operator->, so object->member (with object not being a pointer) performs the mutex assertion.
This is easier done than said:
// Imagine that the members of this class must be locked by the mutex.
class a : public expose_locked_by_arrow< a > {
protected:
int i;
void f();
};
// Declare which members are conditionally locked. Pretty simple and idiomatic.
template<>
struct member_expose< a > : a {
using a::i;
using a::f;
};
#include <iostream>
// Access mutex-locked members with ->
int main() {
a x;
x->i = 5;
a const y( x );
std::cout << y->i << '\n';
}
The library code:
// This template is specialized for each mutex protection client.
template< class >
struct member_expose;
// Base class provides mutex; parameter is derived class (CRTP).
template< class c >
struct expose_locked_by_arrow {
member_expose< c > *
operator->() {
assert ( expose_lock_mutex.is_held() );
return static_cast< member_expose< c > * >( this );
}
member_expose< c > const *
operator->() const {
assert ( expose_lock_mutex.is_held() );
return static_cast< member_expose< c > const * >( this );
}
expose_locked_by_arrow( mutex const &m = mutex() )
: expose_lock_mutex( m ) {}
protected:
mutex expose_lock_mutex;
};
See it run.
The #defines aren't providing any protection as such, rather they are just reducing the amount of typing you'd have to do (in turn, they make sure all the "protected" members have the proper code in place).
There isn't a way that I am aware of to avoid having to put the checks into each getter function - and locking the whole object, as they are returning references to data stored within the protected object.
If however, they could all be returned by value (or not returning anything at all), then you could use a container that locks everything using a proxy object, something like the following (this could probably be done better, i've just quickly hacked it together):
#include <iostream>
struct Mutex
{
void lock()
{
std::cout << "Mutex::lock" << std::endl;
}
void unlock()
{
std::cout << "Mutex::unlock" << std::endl;
}
};
template <class Object>
class ThreadSafeObject
{
mutable Mutex d_mutex;
Object d_object;
public:
struct Proxy
{
mutable Mutex *d_mutex;
Object *d_object;
Proxy(Mutex *mutex, Object *object)
: d_mutex(mutex)
, d_object(object)
{
d_mutex->lock();
}
Proxy(const Proxy& proxy)
: d_mutex(proxy.d_mutex)
, d_object(proxy.d_object)
{
proxy.d_mutex = NULL;
}
~Proxy()
{
if (d_mutex)
{
d_mutex->unlock();
}
}
Object *operator->()
{
return d_object;
}
};
struct ConstProxy
{
mutable Mutex *d_mutex;
const Object *d_object;
ConstProxy(Mutex *mutex, const Object *object)
: d_mutex(mutex)
, d_object(object)
{
d_mutex->lock();
}
ConstProxy(const ConstProxy& proxy)
: d_mutex(proxy.d_mutex)
, d_object(proxy.d_object)
{
proxy.d_mutex = NULL;
}
~ConstProxy()
{
if (d_mutex)
{
d_mutex->unlock();
}
}
const Object *operator->() const
{
return d_object;
}
};
Proxy operator->()
{
return Proxy(&d_mutex, &d_object);
}
ConstProxy operator->() const
{
return ConstProxy(&d_mutex, &d_object);
}
};
struct Foo
{
void foo()
{
std::cout << "Foo::foo" << std::endl;
}
};
int main()
{
ThreadSafeObject<Foo> myFoo;
myFoo->foo();
return 0;
}
Which uses the operator->() trick (when operator-> doesnt reutrn a pointer type, the compiler will keep calling operator-> on the returned values until eventually a regular pointer type is returned) and gives the following output:
Mutex::lock
Foo::foo
Mutex::unlock
Generally speaking though, an object that needs to be used by multiple threads shouldn't be exposing its internals like that, it would be safer to have it accept parameters and use its internal values to act on them.