wxSocketWriteGuard write reentrancy assert

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
mec
In need of some credit
In need of some credit
Posts: 2
Joined: Mon Dec 12, 2016 11:13 am

wxSocketWriteGuard write reentrancy assert

Post by mec »

Hi all!!
I'm new with wxWidgets so please help me.
Sometimes, I got the debug alert below when running a release build, but I'm pretty shure that wxSocketClient::write() is called exclusively.

Thanks in advance!
------------------------------------------------------------------------
Windows 7 Pro SP1 x64
Visual Studio 2013(Version 12.0.40629.00 Update 5)
wxWidgets-3.0.2
------------------------------------------------------------------------
wxWidgets Debug Alert
..\..\src\common\socket.cpp(236): assert
"!m_socket->m_writing" failed in
wxSocketWriteGuard::wxSocketWriteGuard(): write reentrancy?

Call stack:
[00]000000013F78AAF7
[01]000000013F78A4D3
[02]000000013F78A0CB
[03]000000013F7953DA
[04]000000013F787C49
[05]000000013F794DE6
[06]000000013F7A6838
[07]000000013F7AEE50
[08]000000013F7AF032
[09]000000013F7AE675
[10]000000013F7AEA10
[11]000000013F7A8606
[12]000000013F860F04
[13]GetKeyboardLayoutList
[14]SystemParametersInfoW
[15]IsProcessDPIAware
[16]KiUserCallbackDispatcher
[17]PeekMessageW
[18]PeekMessageW
[19]000000013F7FE54E
[20]000000013F8DD866
Do you want to stop the program?
You can also choose [Cancel] to suppress further warnings.
------------------------------------------------------------------------
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7477
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: wxSocketWriteGuard write reentrancy assert

Post by ONEEYEMAN »

Hi,
Please recompile your program as a debug binary with the debug build of wxWidgets and post _miningful_ backtrace.
Also, you may consider posting some code you use or a way to reproduce you issue in the socket sample.

Thank you.
mec
In need of some credit
In need of some credit
Posts: 2
Joined: Mon Dec 12, 2016 11:13 am

Re: wxSocketWriteGuard write reentrancy assert

Post by mec »

Sorry for being completely away...
I still having the same problem but cannot reproduce it.
Here is some additional info about my case...

This application has 3 different wxSockect clients, created on the main thread without the wxSOCKET_BLOCK flag...

I've just learned from the wxWidgets Reference the next.
Notice that if the object is created from a worker thread or if it is created from the main thread but the event loop is not running, flags parameter must include wxSOCKET_BLOCK as non-blocking sockets require dispatching events, which can only be done in the main thread.
Is it possible that my reentrancy problem is because of the lack of the wxSOCKET_BLOCK flag?

Any help would be really appreciated.
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7477
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: wxSocketWriteGuard write reentrancy assert

Post by ONEEYEMAN »

Hi,
Without seeing the code it is hard to tell....

Is event loop running by the time you create your socket? If you add this flag does the program behave correctly?

Thank you.
tigerbeard
Earned some good credits
Earned some good credits
Posts: 126
Joined: Sat Oct 07, 2006 1:56 pm

Re: wxSocketWriteGuard write reentrancy assert

Post by tigerbeard »

i know its an old post, but its the only I found with this assert


I got the problem as well and found that two conditions can cause it

A) as the assert says, when wxSocekt::Write() is in a function and that function is called at the same time from different locations - e.g. from the main thread and a worker thread - then the assert fires.

I this case a solution is to add a protection with a wxMutex like so

Code: Select all

    wxMutex    mWriteMutex;   
    ...
   int Send( char* pBuffer, int nSizeInBytes ) 
    {
     mWriteMutex->Lock();
     pSocket->Write( pBuffer, nSizeInBytes );
     int nCount = pSocket->LastWriteCount();
     mWriteMutex->Unlock();
     return nCount;
    }
    
   int Send( char* pBuffer, int nSizeInBytes )    // alternative
    {
    wxMutexLocket ( mWriteMutex );
     pSocket->Write( pBuffer, nSizeInBytes );
     int nCount = pSocket->LastWriteCount();
     return nCount;
    }
    

b) when the socket is created with wxSOCKET_NONE or wxSOCKET_WAITALL and its writing large buffers, the socket will write them in chunks and may become busy in between. Then Wait() internally waits for the socket to be ready for more output. This, however, seems to cause the wxWidgets event loop to run which could cause re-entrant behaviour in some cases.

For example: Incoming server messages trigger a notification event. The event handler SendMessage() processes these messages and sends replies. The reply function contains the wxSocket::Write() function like this

Code: Select all

 void OnNewMessage( wxCommandEvent& e)
   { 
    pDdata = DoSomeProcessing( e );
    SendReplyMessage( pData );
    }

 void SendReplyMessage( MyData* pData )
 {
    ...
   pSocket->Write( pData->buffer, pData->size() );
 }
When multiple events queue up during a longer Write() that situation occurs: Write() triggers the event loop while waiting for the socket to become available. OnNewMessage() is called. This calls SendReplyMessage() and enters Wait() while its still executing. This triggers the assert().


Case b) seems quite unlikely but that acutally was the cause for the assert in my case. Its a re-entrant behaviour from within a single thread caused by a recursive call by the event system. The code has been working fine before, just very large packets caused this behaviour. Maybe part of the problem was that the Application was based on wxAppConsole not wxApp. Events are processed a bit different according to the documentation, but I am not sure about exactly how.

The solution was easy. The onNewMessage() function gets a static counter to track any recursive incoming calls and completes them i a loop before finally returning.
System config: Xubuntu22.04, wxWidgets 3.0.5,gcc, C::B
Post Reply