SanderMertens / flecs

A fast entity component system (ECS) for C & C++

Home Page:https://www.flecs.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

_::type_name<T>() is not thread-safe, that will cause memory error!

Esp9527 opened this issue · comments

Describe the bug
_::type_name() is not thread-safe, that will cause memory error!

To Reproduce

`

#include "flecs.h"
#include <thread>
#include <map>

namespace component {
    struct Data {
        int i = 0;
    };
}
int main() {

    std::vector<std::shared_ptr<std::thread>>
        threads;

    for(int i = 0; i<10; i++) {
        threads.push_back(std::make_shared<std::thread>([](){
            while(true) {
                flecs::world world;
                world.component<component::Data>();
                world.component<std::map<uint64_t, component::Data>>();
            }
        }));
    }

    for(auto& t : threads)
        t->join();

    return 0;
}

`
this will crash!

Follow a simple solution

`
// modifier _::type_name()

template <typename T>
inline static const char* type_name() {
    static const size_t len = ECS_FUNC_TYPE_LEN(const char*, type_name, ECS_FUNC_NAME);
    static char result[len + 1] = {};
    static const size_t front_len = ECS_FUNC_NAME_FRONT(const char*, type_name);
    // old code:    return ecs_cpp_get_type_name(result, ECS_FUNC_NAME, len, front_len);
    static char* out = ecs_cpp_get_type_name(result, ECS_FUNC_NAME, len, front_len);
    return out;
} 

`
other function maybe also need, symbol_name() , enum_constant_to_name<E, E C> ...

That's correct, but the entire Flecs API is not thread safe :)

Anything that mutates the world should either happen when you have exclusive access to the world (e.g. component registration should happen on the main thread) or should be enqueued as command (e.g. ECS operations like add, remove, set, get_mut, etc).