Cannot lock Qt mutex (QReadWriteLock) Access violation writing - c++

Some background for this question is my previous question:
non-member function pointer as a callback in API to member function (it may well be irrelevant).
The callback launches a thread that writes some data. There is another thread that reads the same data, and that results in some crashes.
I just took a crash course in multi-threading (thanks SO), and here is my attempt to guarantee that the data isn't accessed by the writer and the reader at the same time. I'm using some mutex mechanism from Qt (QReadWriteLock).
#include <QSharedPointer>
#include <QReadWriteLock>
Class MyClass
{
public:
MyClass();
bool open();
float getData();
void streamCB(void* userdata);
protected:
float private_data_;
QSharedPointer<QReadWriteLock> lock_;
};
// callback wrapper from non-member C API to member function void
__stdcall streamCBWrapper(void* userdata)
{
static_cast<MyClass*>(userdata)->streamCB(userdata);
}
// constructor
MyClass::MyClass()
{
lock_ = QSharedPointer<QReadWriteLock>(new QReadWriteLock());
lock_->lockForWrite();
private_data_ = getData();
lock_->unlock();
}
// member callback
void MyClass:streamCB(void* userdata)
{
float a = getData();
lock_->lockForWrite(); //*** fails here
private_data_ = a;
lock_->unlock();
}
I have a segmentation fault while running the program. The VS debugger says Access violation writing location 0x00fedbed. on the line that I marked //*** fails here.
The lock worked in the constructor, but not in the callback.
Any idea what goes wrong? What should I look at? (and how can I refine my question)
Thanks!
Other relevant thread
Cannot access private member declared in class 'QReadWriteLock'Error 1 error C2248: 'QReadWriteLock::QReadWriteLock' (I used the QSharedPointer suggestion)
Edit 1:
The callback is set up
bool MyClass::open()
{
// stuffs
int mid = 0;
set_stream_callback(&streamCBWrapper, &mid);
// more stuffs
return true;
}
Edit 2:
Thank you for all the suggestions.
So my mistake(s) may not be due at all to the mutex, but to my lack of understanding of the API? I'm quite confused.. Here is the API doc for the set_stream_callback.
typedef void (__stdcall *STREAM_CALLBACK)(void *userdata);
/*! #brief Register a callback to be invoked when all subscribed fields have been updated
*
* #param streamCB pointer to callback function
* #param userdata pointer to private data to be passed back as argument to callback
* #return 0 if successful, error code otherwise
*/
__declspec(dllimport) int __stdcall set_stream_callback(
STREAM_CALLBACK streamCB, void *userdata);

Good example why sufficient code example is required.
If I interpret your callback syntax correctly,
set_stream_callback(&streamCBWrapper, &mid);
sets streamCBWrapper as callback function, while &mid is the pointer to userdata.
In the callback, you are actually now casting a pointer to int to MyClass, then try to access a member variable of a non-existant object.
Make sure to pass an instance of MyClass to your callback. I assume this would be this in your case.

Sounds fundamentally like a threading issue to me. Since you're using the Qt mutexing anyway, you might consider using Qt's threading mechanisms and sending signals and slots between the threads. They're pretty well documented and easy to use as long as you follow the suggestions here and here.

Related

C++ Use a class non-static method as a function pointer callback in freeRTOS xTimerCreate

I am trying to use marvinroger/async-mqtt-client that in the provided examples is used together with freertos timers that use a callback that gets invoked whenever the timer expire. The full example is here.
I wanted to create a singleton class to enclose all the connection managing part and just expose the constructor (through a getInstance) and a begin function that other than setting the callbacks, creates the timers for reconnection.
The class looks like (I simplified by removing useless parts):
class MqttManager : public Singleton<MqttManager> {
public:
virtual ~MqttManager() = default;
void begin();
protected:
MqttManager();
void connectToMqtt(TimerHandle_t xTimer);
void WiFiEvent(WiFiEvent_t event);
void onConnect(bool sessionPresent);
std::unique_ptr<AsyncMqttClient> client;
TimerHandle_t mqttReconnectTimer;
TimerHandle_t wifiReconnectTimer;
};
While my issue is when I try to pass the connectToMqtt callback to the timer.
MqttManager::MqttManager() {
this->client = std::unique_ptr<AsyncMqttClient>(new AsyncMqttClient());
// use bind to use a class non-static method as a callback
// (works fine for mqtt callbacks and wifi callback)
this->client->onConnect(std::bind(&MqttManager::onConnect, this, std::placeholders::_1));
WiFi.onEvent(std::bind(&MqttManager::WiFiEvent, this, std::placeholders::_1));
// Here it fails
mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)nullptr, &MqttManager::connectToMqtt, this, std::placeholders::_1);
The error is:
cannot convert 'void (MqttManager::)(TimerHandle_t) {aka void (MqttManager::)(void*)}' to 'TimerCallbackFunction_t {aka void ()(void)}' for argument '5' to 'void* xTimerCreate(const char*, TickType_t, UBaseType_t, void*, TimerCallbackFunction_t)'
Now, from here, having in mind that the problem is around having a pointer to a non-static method that needs somehow to be casted to a free function pointer, three doubts arise:
Why on earth the std::bind "approach" works for WiFi.onEvent but not for xTimerCreate? They seem pretty similar to me... WiFi is typedef void (*WiFiEventCb)(system_event_id_t event); while the timer typedef void (*TimerCallbackFunction_t)( TimerHandle_t xTimer );
How can I make this work? Is there a cast or a better approach?
Is this bad practice? My goal here was to enclose mqtt and wifi functions and callbacks in a neat class easily recognizable, organized and maintainable; but I guess that sometimes you just obtain the opposite result without noticing...
FreeRTOS code is plain old C. It knows nothing about C++, instance methods, function objects, etc. It takes a pointer to a function, period. As Armandas pointed out, WiFi.onEvent on the other hand is C++, lovingly written by someone to accept output from std::bind().
There is a workaround. When you read the xTimerCreate API docs, there is a sneaky little parameter pvTimerID which is effectively user-specified data. You can use this to pass a pointer to your class and later retrieve it from inside the callback function using pvTimerGetTimerID(). With a class pointer you can then forward the callback to your C++ class. See example below.
It's good practice to try to hide private class methods and data. Unfortunately this only works well if you're working entirely in C++ :) If calling into C libraries (like FreeRTOS) I find myself breaking such idealistic principles occasionally.
Here's how I'd do it. I use a lambda (without context) as the actual callback function because it's throwaway wrapper code, and the C libraries happily accept it as a plain old function pointer.
auto onTimer = [](TimerHandle_t hTmr) {
MqttManager* mm = static_cast<MqttManager*>(pvTimerGetTimerID(hTmr)); // Retrieve the pointer to class
assert(mm); // Sanity check
mm->connectToMqtt(hTmr); // Forward to the real callback
}
mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(2000), pdFALSE, static_cast<void*>(this), onTimer);
std::bind returns a callable object, not a function pointer. It works with WiFi.onEvent because there is an overload taking a std::function:
typedef std::function<void(arduino_event_id_t event, arduino_event_info_t info)> WiFiEventFuncCb;
// ...
wifi_event_id_t onEvent(WiFiEventFuncCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX);
Solution
Create a static function for the timer callback and simply get the MqttManager instance as you would from anywhere else.

Using member shared_ptr from a member callback function running in different thread (ROS topic subscription)

I am not completely sure how to best title this question since I am not completely sure what the nature of the problem actually is (I guess "how fix segfault" is not a good title).
The situation is, I have written this code:
template <typename T> class LatchedSubscriber {
private:
ros::Subscriber sub;
std::shared_ptr<T> last_received_msg;
std::shared_ptr<std::mutex> mutex;
int test;
void callback(T msg) {
std::shared_ptr<std::mutex> thread_local_mutex = mutex;
std::shared_ptr<T> thread_local_msg = last_received_msg;
if (!thread_local_mutex) {
ROS_INFO("Mutex pointer is null in callback");
}
if (!thread_local_msg) {
ROS_INFO("lrm: pointer is null in callback");
}
ROS_INFO("Test is %d", test);
std::lock_guard<std::mutex> guard(*thread_local_mutex);
*thread_local_msg = msg;
}
public:
LatchedSubscriber() {
last_received_msg = std::make_shared<T>();
mutex = std::make_shared<std::mutex>();
test = 42;
if (!mutex) {
ROS_INFO("Mutex pointer is null in constructor");
}
else {
ROS_INFO("Mutex pointer is not null in constructor");
}
}
void start(ros::NodeHandle &nh, const std::string &topic) {
sub = nh.subscribe(topic, 1000, &LatchedSubscriber<T>::callback, this);
}
T get_last_msg() {
std::lock_guard<std::mutex> guard(*mutex);
return *last_received_msg;
}
};
Essentially what it is doing is subscribing to a topic (channel), meaning that a callback function is called each time a message arrives. The job of this class is to store the last received message so the user of the class can always access it.
In the constructor I allocate a shared_ptr to the message and for a mutex to synchronize access to this message. The reason for using heap memory here is so the LatchedSubscriber can be copied and the same latched message can still be read. (the Subscriber already implements this kind of behavior where copying it doesn't do anything except for the fact that the callback stops being called once the last instance goes out of scope).
The problem is basically that the code segfaults. I am pretty sure the reason for this is that my shared pointers become null in the callback function, despite not being null in the constructor.
The ROS_INFO calls print:
Mutex pointer is not null in constructor
Mutex pointer is null in callback
lrm: pointer is null in callback
Test is 42
I don't understand how this can happen. I guess I have either misunderstood something about shared pointers, ros topic subscriptions, or both.
Things I have done:
At first I had the subscribe call happening in the constructor. I think giving the this pointer to another thread before the constructor has returned can be bad, so I moved this into a start function which is called after the object has been constructed.
There are many aspects to the thread safety of shared_ptrs it seems. At first I used mutex and last_received_msg directly in the callback. Now I have copied them into local variables hoping this would help. But it doesn't seem to make a difference.
I have added a local integer variable. I can read the integer I assigned to this variable in the constructor from the callback. Just a sanity check to make sure that the callback is actually called on an instance created by my constructor.
I think I have figured out the problem.
When subscribing I am passing the this pointer to the subscribe function along with the callback. If the LatchedSubscriber is ever copied and the original deleted, that this pointer becomes invalid, but the sub still exists so the callback keeps being called.
I didn't think this happened anywhere in my code, but the LatcedSubscriber was stored as a member inside an object which was owned by a unique pointer. It looks like make_unique might be doing some copying internally? In any case it is wrong to use the this pointer for the callback.
I ended up doing the following instead
void start(ros::NodeHandle &nh, const std::string &topic) {
auto l_mutex = mutex;
auto l_last_received_msg = last_received_msg;
boost::function<void(const T)> callback =
[l_mutex, l_last_received_msg](const T msg) {
std::lock_guard<std::mutex> guard(*l_mutex);
*l_last_received_msg = msg;
};
sub = nh.subscribe<T>(topic, 1000, callback);
}
This way copies of the two smart pointers are used with the callback instead.
Assigning the closure to a variable of type boost::function<void(const T)> seems to be necessary. Probably due to the way the subscribe function is.
This appears to have fixed the issue. I might also move the subscription into the constructor again and get rid of the start method.

How to deal with multiple parameters of different types in C++98?

In order to implement a thread class(In C++98 and Windows.h). I have something like this:
Thread::Thread(_beginthreadex_proc_type fn)
{
m_raw = fn;
m_args = 0;
m_handle = 0;
m_id = 0;
}
The code above works fine it takes a function that not receive parameters, and with the next code it function is called by a new thread:
void Thread::Join()
{
m_handle = (HANDLE)_beginthreadex(0, 0, m_raw, (m_args ? m_args : 0), 0, 0);
if (m_handle) WaitForSingleObject(m_handle, INFINITE);
}
This code also works fine with functions that don't take any parameter.
Now my question is about how can i in C++98 receive variadic parameters in my constructor and save them.
And NO i can't use modern c++ if that was the case I din't need help. So plz don't give me solutions implemented with c++11 or higher.
Update
Now I'm trying a Java style solution in that every Thread is a IRunnable that have a pure virtual function named Run. And thread is almost the that this implementetation with the diff that is an abstract class. In this way can i avoid parameters because I don't pass the function instead of that I write another class that inherits from Thread and implements Run.
The code look like:
The interface
struct IRunnable
{
virtual void Run() = 0;
};
Thread class
class Thread : public IRunnable
{
HANDLE m_handle;
DWORD m_id;
typedef unsigned (__stdcall *Function)(void*);
_beginthreadex_proc_type m_raw;
void* m_args;
public:
Thread();
~Thread();
Thread(_beginthreadex_proc_type, void*);
Thread(_beginthreadex_proc_type);
unsigned GetId();
virtual void Run() = 0;
void Join();
unsigned int __stdcall call(void*);
};
Call only is a wrapper to call Run function member
unsigned int __stdcall Thread::call(void* data)
{
Run();
return 0;
}
My problem is here:
void Thread::Join()
{
m_handle = (HANDLE)_beginthreadex(0, 0, &this->call, 0, 0, 0);
if (m_handle) WaitForSingleObject(m_handle, INFINITE);
}
When i compiling in vs2019 the code above produce the next error:
error C2276: '&': illegal operation on bound member function expression
error C2660: '_beginthreadex': function does not take 5 arguments
For your edited question, the reason you're getting a compile error is because you're trying to send the address to a member function of your Thread object. You can't take pointers to member functions and use them without also keeping the object pointer around. Instead, you should make a global function that takes a Thread* as its argument, send a pointer to that function, and let it call your runnable.
unsigned thread_entry(void* thread_ptr)
{
Thread* thread = (Thread*) thread_ptr;
return thread->call();
}
void Thread::Join()
{
m_handle = (HANDLE)_beginthreadex(0, 0, thread_entry, this, 0, 0);
if (m_handle) WaitForSingleObject(m_handle, INFINITE);
}
P.S. It's usually best to ask new questions instead of editing old ones if the question is significantly different, which yours is.
If you look at pretty much any thread library, they very rarely support sending multiple arguments; you usually send a pointer to something, and if you want many things, you make a struct containing many things and send a pointer to it.
However, if you really want this, you could use the C varargs functions to iterate over all variadic arguments, and allocate a linked list with them, or allocate an array of them, or whatever other data structure you want. Then, send a pointer to that to your thread entry function. Your function would still be taking just one pointer, though.
In C, there is no easy way to construct a va_list, which is how variadic arguments are sent around. You can't just send the va_list you have on your main thread, because that memory won't be alive by the time it reaches your new thread. There is also no good way to expand a va_list to fill function arguments.
Btw, I realize you're using C++, but as far as C++98 goes, its varargs support is basically the same as in C, which is why I'm mentioning C in my answer.

How to call callback in member function thread?

I'am writing small class for RS232 port. It can sync write and async read. So, for async read I'm using second thread, that waiting input data. When data received, I want to call user callback (that I get as constructor argument) with input data. It's look like:
typedef int (*ReceivedCallback)(string data);
class RS232
{
RS232(string portName, ReceivedCallback dataReceived);
~RS232();
private:
ReceivedCallback dataReceivedCallback;
private:
static unsigned ReaderThread(void* data);
public:
SendData(string data);
}
My problem is: ReaderThread MUST be static to pass pointer to it to _beginthreadex() function. And in ReaderThread I want to call "dataReceivedCallback", obtained from the user in constructor. But I can't, cause I can't call non-static functions in static ReaderThread. Also, I can't make "dataReceivedCallback" static, cause I may have many instances of my class (for COM1, COM2, COM3) and every instance should have it's own callback, obtained by user.
Where is my architecture mistake? How would you implement it?
Thanks in advance!
P.S. Using Visual Studio 2005.
You need to pass a pointer to the instance of RS232 to ReaderThread, which will, in turn, either pass that pointer to a static callback, or directly call non-static methods on the RS232 object.
I would also use [CreateThread][1] rather than beginthreadex. My code samples will use CreateThread, but you can adapt the technique to beginthreadex if you so desire.
Simply, when kicking off the ReaderThread, pass it a pointer to the instance:
RS232* myObj = new RS232;
CreateThread (..., myObj);
...use reinterpret_cast to cast it back:
unsigned RS232::ReaderThread (void* data)
{
RS232* that = reinterpret_cast <RS232*> (data);
}
Change your callback function so that it can pass the instance as well:
typedef int (*ReceivedCallback)(string data, RS232* that);
And now in the callback you can call member functions:
that->DoSomethingCool (data);
You will need to pass an extra argument to the thread function (which you already have a void *data available for).
Now, add this as a private element in your class RS232:
class RS232
{
RS232(string portName, ReceivedCallback dataReceived);
~RS232();
private:
ReceivedCallback dataReceivedCallback;
private:
static unsigned ReaderThread(void* data);
public:
SendData(string data);
}
and in the constructor:
RS232::RS232(string portName, ReceivedCallback dataReceived)
{
... various stuff to initialize the serial port ...
_beginthreadex(securityarg, stacksize, ReaderThread, this, ...)
}
And in the ReaderThread function:
unsigned RS232::ReaderThread(void *data)
{
RS232 *self = static_cast<RS232*>(data);
.... stuff to read from serial port ...
... Now call the callback:
self->dataReceivedCallback(str);
....
}
To access the non-static object data in the static thread function you could use this extremely hacky and untested solution. But be warned --- it is for educational purposes only because it is extremely hacky. You should learn about locks and mutexes and probably boost threads. Note, this is a pthread style solution. I've no experience with the function _beginthreadex() but you can see that createThread does the job of creating your thread. Adapt as needed.
typedef int (*ReceivedCallback)(string data);
class RS232
{
public:
RS232(string portName, ReceivedCallback dataReceived);
~RS232();
SendData(string data);
createThread();
private:
ReceivedCallback dataReceivedCallback;
static unsigned ReaderThread(void* data);
thread m_someThread;
struct accessHelper
{
RS232* This;
void *actual_arg;
accessHelper(RS232 *t, void *p)
: This(t),
actual_arg(p)
{}
};
};
RS232::createThreaad()
{
int someData;
accessHelper ah(this, someData);
m_someThread.create(RS232::ReaderThread, &ah);
}
RS232::ReaderThread(void *data)
{
accessHelper *ah = static_cast<accessHelper*>(data);
RS232 *This = ah->This;
This->dataReceivedCallback......
}

multithreading and classes?

Here is the issue that I'm having with multithreading. The proc needs to be static which means the only way I see that 2 threads can communicate and share data is through the global scope. This does not seem very clean nor does it feel very OO. I know I can create a static proc function in a class but that's still static.
What I'd like to for example do is have thread procs in the class somehow so that ex: I could create an MD5 checksum class and have an array of these objects, each on their own thread checking its hash, while the UI thread is not impaired by this and another class could simply keep track of the handles and wait for multiple objects before saying "Complete" or something. How is this limitation usually overcome?
You cannot avoid using a static function if you want to start a thread there. You can however (using Windows) pass the this pointer as a parameter and use it on the other side to enter the class instance.
#include <windows.h>
class Threaded {
static DWORD WINAPI StaticThreadEntry(LPVOID me) {
reinterpret_cast<Threaded*>(me)->ThreadEntry();
return 0;
}
void ThreadEntry() {
// Stuff here.
}
public:
void DoSomething() {
::CreateThread(0, 0, StaticThreadEntry, this, 0, 0);
}
};
In C++, Boost.Thread solves the problem nicely. A thread is represented by a functor, meaning that the (non-static) operator() is the thread's entry point.
For example, a thread can be created like this:
// define the thread functor
struct MyThread {
MyThread(int& i) : i(i) {}
void operator()(){...}
private:
int& i;
};
// create the thread
int j;
boost::thread thr(MyThread(j));
by passing data to the thread functor's constructor, we can pass parameters to the thread without having to rely on globals. (In this case, the thread is given a reference to the integer j declared outside the thread.)
With other libraries or APIs, it's up to you to make the jump from a (typically static) entry point to sharing non-static data.
The thread function typically takes a (sometimes optional) parameter (often of type void*), which you can use to pass instance data to the thread.
If you use this to pass a pointer to some object to the thread, then the thread can simply cast the pointer back to the object type, and access the data, without having to rely on globals.
For example, (in pseudocode), this would have roughly the same effect as the Boost example above:
void MyThreadFunc(void* params) {
int& i = *(int*)params;
...
}
int j;
CreateThread(MyThreadFunc, &j);
Or the parameter can be a pointer to an object whose (non-static) member function you wish to call, allowing you to execute a class member function instead of a nonmember.
I'm not sure I understood well... I give it a try. Are you looking for thread local storage ?
Thread creation routines usually allow you to pass a parameter to the function which will run in a new thread. This is true for both Posix pthread_create(...) and Win32 CreateThread(...). Here is a an example using Pthreads:
void* func (void* arg) {
queue_t* pqueue = (queue_t*)arg;
// pull messages off the queue
val = queue_pull(pqueue);
return 0;
}
int main (int argc, char* argv[]) {
pthread_t thread;
queue_t queue = queue_init();
pthread_create(&thread, 0, func, &queue);
// push messages on the queue for the thread to process
queue_push(&queue, 123);
void* ignored;
pthread_join(&thread, &ignored);
return 0;
}
No statics anywhere. In a C++ program you could pass a pointer to an instance of a class.