wxSocket event handling memory leak in wxGTK-2.8

Petr Chládek pchladek at retia.cz
Wed Jun 6 00:58:02 PDT 2007


Hi,
I'm using wxGTK-2.8.3 and I noticed increasing memory allocation (I can see it 
with top or htop) by handling events (receiving TCP sockets). Increasing of 
memory allocation in my example is very fast. I adjusted examples/sockets/ 
client.cpp and server.cpp for better demonstration (see below). When I'm 
using wxGTK-2.6.3 there's no problem.
Thanks
Petr Chladek

Using example: Connect a client to server and run Test1. After 1 minute you'll 
see growing memory allocation for server.

Changes:

client.cpp
----------------------------------------------------------------------------------

...
#include "wx/utils.h"
...

void MyFrame::OnTest1(wxCommandEvent& WXUNUSED(event))
{
  const wxChar *buf1;
  wxChar       *buf2;
  unsigned char len;

while( 1 )
{
  // Disable socket menu entries (exception: Close Session)
  m_busy = true;
  UpdateStatusBar();

  m_text->AppendText(_("\n=== Test 1 begins ===\n"));

  // Tell the server which test we are running
  unsigned char c = 0xBE;
  m_sock->Write(&c, 1);

  // Send some data and read it back. We know the size of the
  // buffer, so we can specify the exact number of bytes to be
  // sent or received and use the wxSOCKET_WAITALL flag. Also,
  // we have disabled menu entries which could interfere with
  // the test, so we can safely avoid the wxSOCKET_BLOCK flag.
  //
  // First we send a byte with the length of the string, then
  // we send the string itself (do NOT try to send any integral
  // value larger than a byte "as is" across the network, or
  // you might be in trouble! Ever heard about big and little
  // endian computers?)

  m_sock->SetFlags(wxSOCKET_WAITALL);

  buf1 = _("Test string (less than 256 chars!)");
  len  = (unsigned char)((wxStrlen(buf1) + 1) * sizeof(wxChar));
  buf2 = new wxChar[wxStrlen(buf1) + 1];

  m_text->AppendText(_("Sending a test buffer to the server ..."));
  m_sock->Write(&len, 1);
  m_sock->Write(buf1, len);
  m_text->AppendText(m_sock->Error() ? _("failed !\n") : _("done\n"));

  m_text->AppendText(_("Receiving the buffer back from server ..."));
  m_sock->Read(buf2, len);
  m_text->AppendText(m_sock->Error() ? _("failed !\n") : _("done\n"));

  m_text->AppendText(_("Comparing the two buffers ..."));
  if (memcmp(buf1, buf2, len) != 0)
  {
    m_text->AppendText(_("failed!\n"));
    m_text->AppendText(_("Test 1 failed !\n"));
  }
  else
  {
    m_text->AppendText(_("done\n"));
    m_text->AppendText(_("Test 1 passed !\n"));
  }
  m_text->AppendText(_("=== Test 1 ends ===\n"));

  delete[] buf2;
  m_busy = false;
  UpdateStatusBar();

  wxMilliSleep( 32 );
}
}


server.cpp
----------------------------------------------------------------------------------

void MyFrame::Test1(wxSocketBase *sock)
{
  unsigned char len;
  char *buf;

  //m_text->AppendText(_("Test 1 begins\n"));

  // Receive data from socket and send it back. We will first
  // get a byte with the buffer size, so we can specify the
  // exact size and use the wxSOCKET_WAITALL flag. Also, we
  // disabled input events so we won't have unwanted reentrance.
  // This way we can avoid the infamous wxSOCKET_BLOCK flag.

  sock->SetFlags(wxSOCKET_WAITALL);

  // Read the size
  sock->Read(&len, 1);
  buf = new char[len];

  // Read the data
  sock->Read(buf, len);
  //m_text->AppendText(_("Got the data, sending it back\n"));

  // Write it back
  sock->Write(buf, len);
  delete[] buf;

  //m_text->AppendText(_("Test 1 ends\n\n"));
}

....

void MyFrame::OnSocketEvent(wxSocketEvent& event)
{
  wxString s = _("OnSocketEvent: ");
  wxSocketBase *sock = event.GetSocket();

  // First, print a message
  switch(event.GetSocketEvent())
  {
    case wxSOCKET_INPUT : s.Append(_("wxSOCKET_INPUT\n")); break;
    case wxSOCKET_LOST  : s.Append(_("wxSOCKET_LOST\n")); break;
    default             : s.Append(_("Unexpected event !\n")); break;
  }

  //m_text->AppendText(s);

....




More information about the wx-dev mailing list