Consider this code (extracted from Simple-Web-Server, but knowledge of the library shouldn't be necessary to answer this question):
HttpServer server;thread server_thread;server.config.port = 8080;server.default_resource["GET"] = [](shared_ptr<HttpServer::Response> response, shared_ptr<HttpServer::Request> request) { string content = "Hello world!" *response << "HTTP/1.1 200 OK\r\nContent-Length: "<< content.size() << "\r\n\r\n"<< content;};server_thread = thread([&server]() { server.start();});
HttpServer::default_resource
is a std::unordered_map, which, to my understanding, isn't thread-safe. port
is an unsigned short.
Assuming my understanding of C++ memory fences is correct, server
, as seen by the new thread, might not be in a valid state as the main thread might not have written the changes to port
and default_resource
to memory accessible from other threads. As such, server.start()
might not work properly.
To fix this, I would have to change the code by adding to atomic_thread_fence
s:
HttpServer server;thread server_thread;server.config.port = 8080;server.default_resource["GET"] = [](shared_ptr<HttpServer::Response> response, shared_ptr<HttpServer::Request> request) { string content = "Hello world!" *response << "HTTP/1.1 200 OK\r\nContent-Length: "<< content.size() << "\r\n\r\n"<< content;};atomic_thread_fence(memory_order_release);server_thread = thread([&server]() { atomic_thread_fence(memory_order_acquire); server.start();});
Is my understanding correct, and are both the atomic_thread_fence
s necessary?