OSCReceiver Thread Timeout


#1

Hi guys,

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;

#2

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?


#3

Cheers Jules, sounds like a plan! I’ll try and reproduce and get a stacktrace for you! :slightly_smiling_face:


#4

Hi Jules,

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.

Cheers,

Chris


#5

Thanks for this! Yeah, I think it just needs a timeout, I’ll sort that out…


#6

Thanks Jules! Much appreciated! :slight_smile: