Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using shared_ptr with FreeRTOS queue

I use ESP-32 and need to pass std::shared_ptr using FreeRTOS queue. However, it loose one link. I think that this is source of a problem:

#include <iostream>
#include <memory>
#define PRINT_USE_COUNT(p) std::cout << "Use count: " << p.use_count() << std::endl;

extern "C" {
    #include <freertos/FreeRTOS.h>
    #include <freertos/task.h>
    #include <freertos/queue.h>
}

class testClass {
    public:
        testClass() {
            std::cout << "Class is constructed" << std::endl;
        };
        virtual ~testClass() {
            std::cout << "Class is destructed" << std::endl;
        };
};

struct container {
    std::shared_ptr<testClass> field;
};

extern "C" void app_main(void) {
    auto queue = xQueueCreate(1, sizeof(container));
    auto p = std::make_shared<testClass>();
    PRINT_USE_COUNT(p); // 1
    {
        container c;
        c.field = p;
        PRINT_USE_COUNT(p); // 2
        xQueueSendToBack(queue, &c, 0);
        PRINT_USE_COUNT(p); // 2
    }
    PRINT_USE_COUNT(p); // 1 (Ooops!)
    {
        container c;
        assert(xQueueReceive(queue, &c, 0) == pdTRUE);
        PRINT_USE_COUNT(c.field); // 1
    }
    // Class is destructed
    std::cout << "Test finished" << std::endl;
    vQueueDelete(queue);
}

So there is a pointer in queue, but it isn't counted!

How can I solve this issue (and keep using FreeRTOS queue if possible)? Using std::move doesn't help.

like image 903
val is still with Monica Avatar asked Oct 17 '22 15:10

val is still with Monica


1 Answers

A C-style queue of raw pointers will only works for C++ shared_ptr iff std::is_trivial<T>::value is true (mainly POD or trivially copyable object).

Since there are memcpy and other plain C operation manipulating memory the reference count will not be handled properly (because it is C-code behind the scene and it does not call destructor among other thing) and you could end up with a memory leak.

There is no easy way to circumvent this, but the best way is to manage the memory yourself.

See this question also : Shared pointers and queues in FreeRTOS

like image 113
Clonk Avatar answered Oct 21 '22 02:10

Clonk