Hi!
I'm trying to implement a multithreaded framework, in which output objects are created at the end of every frame that my networking thread runs, so that another thread can, at the beginning of its frame, obtain the most recent "completed output" pointer and know that it has safe and complete read-only access to any data stored within the output object.
My (very early) approach to this primarily involves the following blocks of code:
NetworkHandler -
void NetworkHandler::Tick()
{
// Tick on our io_service
m_ios.poll();
// Assemble new output data
this->AssembleOutput();
}
ClientNetworkHandler -
void ClientNetworkHandler::AssembleOutput()
{
std::tr1::shared_ptr<crusade::task::TaskOutput> newOutput(new crusade::task::TaskOutput());
newOutput->m_outputElements["connected"] = std::tr1::shared_ptr<crusade::task::TaskOutputElement>(new NetworkConnectedTaskOutputElement(this->m_isConnected));
this->m_latestOutput.swap(newOutput);
}
PyCruHandler -
void PyCruHandler::Tick()
{
printf("PyCruHandler\n");
// Get any necessary inputs from other threads
m_latestNetworkOutput.swap(crusade::task::THManager::GetInstance()->GetTaskHandler(crusade::task::THManager::TH_NETWORK)->GetLatestOutput());
// Other unrelated processing to go here
}
Basically, ClientNetworkHandler and PyCruHandler run independently on separate threads. PyCruHandler never actually does anything with its copy of m_latestNetworkOutput; I've commented out every other instance where it is accessed in any way, and I still have the following issue:
If I allow both threads to call swap (or the operator= equivalent), then eventually (usually within 2 seconds of running, but sometimes it takes a few minutes) I will get the following error on either an operator new or allocator deletion of some sort:
"HEAP: Free Heap block 2bab3b0 modified at 2bab3dc after it was freed Windows has triggered a breakpoint.
This may be due to a corruption of the heap, which indicates a bug... etc."
I am only a newbie, but to me this seems to indicate some sort of issue with thread-safety and timing-sensitive access issues between the shared_ptr objects. However, I have been embarassingly confused by the explanations (both here and elsewhere) of the nuances of shared_ptr thread-safety - one piece of reading indicates that the reference count is thread safe, so it's safe to copy shared_ptrs around (but their inner objects won't be thread safe), other pieces of reading indicate that there is effectively NO thread-safety of any usefulness in shared_ptr. I've read the boost documentation on thread safety of shared_ptrs, but that still didn't clarify in my mind whether this should be an issue in my code or not.
My question is, can anyone here detect any obvious flaw in what I'm doing? My goal is that I can access the latest output object still stored by the owning thread, and then that object won't be deleted (even after the owning thread has moved on to later outputs) until every user of the output is done with it as well. Shared pointer seemed perfect for this in my mind... but after 3 hours of banging my head against this I'm starting to wonder...
Thank you very much in advance, and I apologize if I posted this incorrectly somehow; it's my first time here and the FAQ seemed pretty laid-back as far as protocol goes!