I have noticed that the OSCReceiver thread doesn’t often exit cleanly. I think that the thread is stuck on socket->waitUntilReady (true, -1) which waits forever for the next packet to arrive. Would it be a good idea to add a timeout here?
Cheers,
Chris
void run() override
{
while (! threadShouldExit())
{
jassert (socket != nullptr);
char buffer[oscBufferSize];
socket->waitUntilReady (true, -1);
if (threadShouldExit())
return;
The disconnect method calls socket->shutdown(), which will interrupt it if waiting… If you can find a situation where you think this is blocking, can you get a stack trace of where the threads are at that point?
I am hitting this assert everytime the OSCReceiver is deleted.
Thread::~Thread()
{
if (deleteOnThreadEnd)
return;
/* If your thread class's destructor has been called without first stopping the thread, that
means that this partially destructed object is still performing some work - and that's
probably a Bad Thing!
To avoid this type of nastiness, always make sure you call stopThread() before or during
your subclass's destructor.
*/
jassert (! isThreadRunning());
The problem seems to go away if I add a timeout in OSCReceiver::run():
void run() override
{
while (! threadShouldExit())
{
jassert (socket != nullptr);
char buffer[oscBufferSize];
socket->waitUntilReady (true, 1000);
if (threadShouldExit())
return;
This is the call stack for the thread that is raising the error:
Testing.exe!juce::Thread::~Thread() Line 43 C++ Symbols loaded.
Testing.exe!juce::OSCReceiver::Pimpl::~Pimpl() Line 331 C++ Symbols loaded.
[External Code] Annotated Frame
Testing.exe!std::default_delete<juce::OSCReceiver::Pimpl>::operator()(juce::OSCReceiver::Pimpl * _Ptr) Line 1999 C++ Symbols loaded.
Testing.exe!std::unique_ptr<juce::OSCReceiver::Pimpl,std::default_delete<juce::OSCReceiver::Pimpl> >::reset(juce::OSCReceiver::Pimpl * _Ptr) Line 2239 C++ Symbols loaded.
Testing.exe!juce::OSCReceiver::~OSCReceiver() Line 600 C++ Symbols loaded.
This is the call stack for the OSCReceiver thread:
Testing.exe!juce::SocketHelpers::waitForReadiness(std::atomic<int> & handle, juce::CriticalSection & readLock, bool forReading, int timeoutMsecs) Line 280 C++ Symbols loaded.
Testing.exe!juce::DatagramSocket::waitUntilReady(bool readyForReading, int timeoutMsecs) Line 670 C++ Symbols loaded.
Testing.exe!juce::OSCReceiver::Pimpl::run() Line 468 C++ Symbols loaded.
It seems that SocketHelpers::waitForReadiness never returns. I am running on the latest Win10 with all the default Projucer settings. Let me know if you need anything else.