Skip to main content
Code Review

Return to Answer

replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link

Does moving leave the object in a usable state? Does moving leave the object in a usable state?

According to this your m_Queue object is valid, yet in an unspecified state. The easiest way to make the state specified again might be calling m_Queue.clear() directly after local_queue = std::move(m_Queue); or even reinitializing m_Queue with new object.

I tried to find out whether just clearing m_Queue is sufficient, yet I couldn't find anything definate apart from comments. I think it is at least "more safe" to use than you current approach.


For readability reasons I would have also changed the structure of your private_start to something like this

void private_start()
{
 m_Thread = std::thread([this]
 {
 for (;;)
 {
 decltype(m_Queue) local_queue;
 {
 std::unique_lock<std::mutex> lk(m_Mutex);
 m_Condition.wait(lk, [&] { return !m_Queue.empty() + !m_Running; });
 if (!m_Running)
 {
 for (auto& func : m_Queue)
 func();
 m_Queue.clear();
 return;
 }
 //Move to local
 local_queue = std::move(m_Queue);
 m_Queue.clear();
 }
 //Process local
 for (auto& func : local_queue)
 {
 func();
 }
 }
 });
}

But that's more of a personnal preference.


As a last comment I would recommend updating your example to call stop on all workers so your application doesn't end prematurely.

Does moving leave the object in a usable state?

According to this your m_Queue object is valid, yet in an unspecified state. The easiest way to make the state specified again might be calling m_Queue.clear() directly after local_queue = std::move(m_Queue); or even reinitializing m_Queue with new object.

I tried to find out whether just clearing m_Queue is sufficient, yet I couldn't find anything definate apart from comments. I think it is at least "more safe" to use than you current approach.


For readability reasons I would have also changed the structure of your private_start to something like this

void private_start()
{
 m_Thread = std::thread([this]
 {
 for (;;)
 {
 decltype(m_Queue) local_queue;
 {
 std::unique_lock<std::mutex> lk(m_Mutex);
 m_Condition.wait(lk, [&] { return !m_Queue.empty() + !m_Running; });
 if (!m_Running)
 {
 for (auto& func : m_Queue)
 func();
 m_Queue.clear();
 return;
 }
 //Move to local
 local_queue = std::move(m_Queue);
 m_Queue.clear();
 }
 //Process local
 for (auto& func : local_queue)
 {
 func();
 }
 }
 });
}

But that's more of a personnal preference.


As a last comment I would recommend updating your example to call stop on all workers so your application doesn't end prematurely.

Does moving leave the object in a usable state?

According to this your m_Queue object is valid, yet in an unspecified state. The easiest way to make the state specified again might be calling m_Queue.clear() directly after local_queue = std::move(m_Queue); or even reinitializing m_Queue with new object.

I tried to find out whether just clearing m_Queue is sufficient, yet I couldn't find anything definate apart from comments. I think it is at least "more safe" to use than you current approach.


For readability reasons I would have also changed the structure of your private_start to something like this

void private_start()
{
 m_Thread = std::thread([this]
 {
 for (;;)
 {
 decltype(m_Queue) local_queue;
 {
 std::unique_lock<std::mutex> lk(m_Mutex);
 m_Condition.wait(lk, [&] { return !m_Queue.empty() + !m_Running; });
 if (!m_Running)
 {
 for (auto& func : m_Queue)
 func();
 m_Queue.clear();
 return;
 }
 //Move to local
 local_queue = std::move(m_Queue);
 m_Queue.clear();
 }
 //Process local
 for (auto& func : local_queue)
 {
 func();
 }
 }
 });
}

But that's more of a personnal preference.


As a last comment I would recommend updating your example to call stop on all workers so your application doesn't end prematurely.

Source Link

Does moving leave the object in a usable state?

According to this your m_Queue object is valid, yet in an unspecified state. The easiest way to make the state specified again might be calling m_Queue.clear() directly after local_queue = std::move(m_Queue); or even reinitializing m_Queue with new object.

I tried to find out whether just clearing m_Queue is sufficient, yet I couldn't find anything definate apart from comments. I think it is at least "more safe" to use than you current approach.


For readability reasons I would have also changed the structure of your private_start to something like this

void private_start()
{
 m_Thread = std::thread([this]
 {
 for (;;)
 {
 decltype(m_Queue) local_queue;
 {
 std::unique_lock<std::mutex> lk(m_Mutex);
 m_Condition.wait(lk, [&] { return !m_Queue.empty() + !m_Running; });
 if (!m_Running)
 {
 for (auto& func : m_Queue)
 func();
 m_Queue.clear();
 return;
 }
 //Move to local
 local_queue = std::move(m_Queue);
 m_Queue.clear();
 }
 //Process local
 for (auto& func : local_queue)
 {
 func();
 }
 }
 });
}

But that's more of a personnal preference.


As a last comment I would recommend updating your example to call stop on all workers so your application doesn't end prematurely.

lang-cpp

AltStyle によって変換されたページ (->オリジナル) /