wxSocket: wxYield called recursively

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
sago
Earned a small fee
Earned a small fee
Posts: 18
Joined: Tue Oct 21, 2008 7:59 am

wxSocket: wxYield called recursively

Post by sago » Thu Oct 30, 2008 9:53 am

Hi!

I have a problem with the use of wxTCPServer and wxTCPConnection classes.

At execution of the program, if 2 clients start each an event (for example the event OnDisonnect) at the same time, I have this error on server side:

Code: Select all

assert "wxAsserFailure" failed: wxYield called recursively
In accordance with others topic, which treat this problem, I have to create a thread for each socket :
http://forums.wxwidgets.org/viewtopic.php?p=92682#92682
I've tried it, but the assert always appears.

For 4 days , I've tried to resolve this problem, but no result ...
It would seem that this problem also appears with the example of wxWidgets (the repertory ipc) by launching 2 clients.

Thanks for any ideas.

sago
Earned a small fee
Earned a small fee
Posts: 18
Joined: Tue Oct 21, 2008 7:59 am

Post by sago » Fri Oct 31, 2008 11:29 am

I've tried to resolve by using a mutex (in static) in order to protect the calling of the macro PROCESS_EVENTS in the class wxSocketBase used by wxTCPConnection, which calls the function wxYield(), but no result. I have the same error.

FireMail
Earned some good credits
Earned some good credits
Posts: 122
Joined: Fri Jun 10, 2005 8:34 am
Location: Austria
Contact:

Post by FireMail » Mon Nov 03, 2008 9:42 am

can you show me some code (Thread creation, thread code itself, flags of the socket)
-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GB/CS/CM/IT !d++ s+:-- a-- C++++$ UBL*++++$ P--- L++++$ !E-- !W+++$? !N-- !o K--? w++()$ !O M$ !V !PS? !PE? !Y? !PGP !t !5 !X R+++ tv++ !b? DI D++ G e+++ h++ r++ y+
------END GEEK CODE BLOCK------

sago
Earned a small fee
Earned a small fee
Posts: 18
Joined: Tue Oct 21, 2008 7:59 am

Post by sago » Tue Nov 04, 2008 8:47 am

Sorry I have deleted all the code concerning the threads..

But I use the classes wxTCPServer, wxTCPClient, and wxTCPConnection, so the flag of the sockets is wxSOCKET_WAITALL.

I have decided to modifiy theses classes and not my code. Because yestarday I've observed a private class named "wxTCPEventHandlerModule". And I added this line in the function OnInit():

Code: Select all

wxSocketBase::Initialize(); 
Now I can say that the assert concerning the "wxYield called recusrively" appears less than before.
But it is not yet perfect.
So today I'm going to try to use the threads or maybe mutex in theses classes (not in my code which derived from theses classes)

sago
Earned a small fee
Earned a small fee
Posts: 18
Joined: Tue Oct 21, 2008 7:59 am

Post by sago » Tue Nov 04, 2008 10:02 am

I had to create the thread just after we have the event "wxSOCKET_CONNECTION" ?

wxTCPServerThread is my thread class:

Code: Select all

#define TCPSERVERTHREAD
#ifdef TCPSERVERTHREAD
// --------------------------------------------------------------------------
// wxTCPEventHandler stuff (private class)
// --------------------------------------------------------------------------

class wxTCPServerThread : public wxThread
{
public:
	wxTCPServerThread(wxTCPServer* xp_server, wxSocketBase* xp_socket) : wxThread(), mp_server(xp_server), mp_socket(xp_socket) {}
	virtual ~wxTCPServerThread() {}
    virtual void* Entry()
	{
		wxSocketStream *stream     = new wxSocketStream(*mp_socket);
		wxDataInputStream *codeci  = new wxDataInputStream(*stream);
		wxDataOutputStream *codeco = new wxDataOutputStream(*stream);

		int msg;
		msg = codeci->Read8();

		if (msg == IPC_CONNECT)
		{
			wxString topic_name;
			topic_name = codeci->ReadString();

			wxTCPConnection *new_connection =
				(wxTCPConnection *) mp_server->OnAcceptConnection (topic_name);

			if (new_connection)
			{
			  if (new_connection->IsKindOf(CLASSINFO(wxTCPConnection)))
			  {
				// Acknowledge success
				codeco->Write8(IPC_CONNECT);
				new_connection->m_topic = topic_name;
				new_connection->m_sock = mp_socket;
				new_connection->m_sockstrm = stream;
				new_connection->m_codeci = codeci;
				new_connection->m_codeco = codeco;
				mp_socket->SetEventHandler(*gs_handler, _CLIENT_ONREQUEST_ID);
				mp_socket->SetClientData(new_connection);
				mp_socket->SetNotify(wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG);
				mp_socket->Notify(TRUE);
				return (void*) TRUE;
			  }
			  else
			  {
				delete new_connection;
				// and fall through to delete everything else
			  }
			}
		}

		// Something went wrong, send failure message and delete everything
		codeco->Write8(IPC_FAIL);

		delete codeco;
		delete codeci;
		delete stream;
		mp_socket->Destroy();
		
		return (void*) TRUE;
	}
    virtual void OnExit() {}
	
private:
	wxTCPServer* mp_server;
	wxSocketBase* mp_socket;
};
#endif
And here is when I create the thread (wxTCPEventHandler is a wxWidgets class):

Code: Select all


void wxTCPEventHandler::Server_OnRequest(wxSocketEvent &event)
{
  wxSocketServer *server = (wxSocketServer *) event.GetSocket();
  wxTCPServer *ipcserv = (wxTCPServer *) server->GetClientData();

  // This socket is being deleted; skip this event
  if (!ipcserv)
    return;

  if (event.GetSocketEvent() != wxSOCKET_CONNECTION)
    return;

  // Accept the connection, getting a new socket
  wxSocketBase *sock = server->Accept();
  if (!sock->Ok())
  {
    sock->Destroy();
    return;
  }

#ifdef TCPSERVERTHREAD  
	wxTCPServerThread* p_serverThread = new wxTCPServerThread(ipcserv, sock);
	p_serverThread->Create();
	p_serverThread->Run();  
#else
  wxSocketStream *stream     = new wxSocketStream(*sock);
  wxDataInputStream *codeci  = new wxDataInputStream(*stream);
  wxDataOutputStream *codeco = new wxDataOutputStream(*stream);

  int msg;
  msg = codeci->Read8();

  if (msg == IPC_CONNECT)
  {
    wxString topic_name;
    topic_name = codeci->ReadString();

    wxTCPConnection *new_connection =
         (wxTCPConnection *)ipcserv->OnAcceptConnection (topic_name);

    if (new_connection)
    {
      if (new_connection->IsKindOf(CLASSINFO(wxTCPConnection)))
      {
        // Acknowledge success
        codeco->Write8(IPC_CONNECT);
        new_connection->m_topic = topic_name;
        new_connection->m_sock = sock;
        new_connection->m_sockstrm = stream;
        new_connection->m_codeci = codeci;
        new_connection->m_codeco = codeco;
        sock->SetEventHandler(*gs_handler, _CLIENT_ONREQUEST_ID);
        sock->SetClientData(new_connection);
        sock->SetNotify(wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG);
        sock->Notify(TRUE);
        return;
      }
      else
      {
        delete new_connection;
        // and fall through to delete everything else
      }
    }
  }

  // Something went wrong, send failure message and delete everything
  codeco->Write8(IPC_FAIL);

  delete codeco;
  delete codeci;
  delete stream;
  sock->Destroy();
#endif
}
For more details the others wxwidgets classes are in the file sckipc.h/sckipc.cpp

sago
Earned a small fee
Earned a small fee
Posts: 18
Joined: Tue Oct 21, 2008 7:59 am

Post by sago » Tue Nov 04, 2008 2:12 pm

FireMail wrote:can you show me some code (Thread creation, thread code itself, flags of the socket)
Could you give me an example please, because what I made does not work.

The thread must be joinable or detached ?

Post Reply