Page 1 of 1

wxSocket: wxYield called recursively

Posted: Thu Oct 30, 2008 9:53 am
by sago
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.

Posted: Fri Oct 31, 2008 11:29 am
by sago
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.

Posted: Mon Nov 03, 2008 9:42 am
by FireMail
can you show me some code (Thread creation, thread code itself, flags of the socket)

Posted: Tue Nov 04, 2008 8:47 am
by sago
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)

Posted: Tue Nov 04, 2008 10:02 am
by sago
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

Posted: Tue Nov 04, 2008 2:12 pm
by sago
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 ?