POSIX Thread - Memory leak

Hi all!

I am implementing an http server in c++ using the posix thread, but i am having a memory leak and i cannot find the reason.

I have already commented out the section that initializes the threads and i found out, the problem is when i initialize/run the threads.

In the threads i have already checked for every possible point to free the memory, but even inserting delete xxxx didnt work....

I am closing the socket, deleting its reference when not needed anymore, deleting every variable i am using to handle the data.... and so on...

Here is:

My main calls the pthread_create and passes as argument a pointer to a pthread_t. The main is responsible for this variable (creation and deleting).
Inside the thread i cast the argument (void*) to a (pthread_t *), i am using also two mutex (as global variables), accepting a connection (socket server), receiving data and responding, closing the connection.
The socket variable i am using as a pointer, cause i can delete after using it. Therefore, the leak is not related to the socket, i think...

But despite doing all of this when running the http server each new connection adds 8kb of memory to the used memory...
Each connection means a new thread....

I cannot find the bug, can anyone please help me?

Thanks in advance!

The code is down here:

#include <iostream>
#include "ServerSocket.h"
#include "SocketException.h"
#include <string>
#include <pthread.h>
#define MAX_CONNECTIONS 5
#define DEBUG

pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; //to keep one thread for each connection
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER; //to change the variable nThreads
int nThreads = 0;

using namespace std;

// Create the socket
ServerSocket server ( 8080 );
/*
//-------creating
  m_sock = socket ( AF_INET,
		    SOCK_STREAM,
		    0 );

  if ( ! (m_sock != -1) )
    return false;

  // TIME_WAIT - argh
  int on = 1;
  if ( setsockopt ( m_sock, SOL_SOCKET, SO_REUSEADDR, ( const char* ) &on, sizeof ( on ) ) == -1 )
    throw SocketException ( "Could not create server socket." );
//--------end creating

//--------start binding
  m_addr.sin_family = AF_INET;
  m_addr.sin_addr.s_addr = INADDR_ANY;
  m_addr.sin_port = htons ( port );

  int bind_return = ::bind ( m_sock,
			     ( struct sockaddr * ) &m_addr,
			     sizeof ( m_addr ) );

  if ( bind_return == -1 )
    {
      throw SocketException ( "Could not bind to port." );
    }

//--------end binding
//--------start listening
int listen_return = ::listen ( m_sock, MAXCONNECTIONS );

  if ( listen_return == -1 )
    {
      throw SocketException ( "Could not listen to socket." );
    }
//--------end binding
*/

enum thread_status
{
	INIT = 0
	,RUNNING
	,FINISHED
};

struct threads
{
	pthread_t	*thread;
	thread_status	status;
	int		id;
};

void *listen( void * ptr )
{
	threads *stThread = (threads*) ptr; //casting
	stThread->status = RUNNING; //changing status
	//creating new socket
	ServerSocket *new_sock = new ServerSocket();
	/*
	//do nothing
	ServerSocket(){};
	*/
	try
	{
		pthread_mutex_lock( &mutex1 );	
		server.accept ( *new_sock );
		/*
		int addr_length = sizeof ( m_addr );
		new_socket.m_sock = ::accept ( m_sock, ( sockaddr * ) &m_addr, ( socklen_t * ) &addr_length );
		*/
		pthread_mutex_unlock( &mutex1 );
		try
		{
			std::string data;
			(*new_sock) >> data; //receive data
			data = "<html><body>The content of the body element is displayed in your browser.<img src=\"http://www.google.com.br/intl/en/images/about_logo.gif\">thread</body></html>";
			(*new_sock) << data;//send data
			new_sock->close(); //closing socket
			/*
			::close ( m_sock );
			*/
		}
		catch ( SocketException& ex )
		{
			cout << strThread << "Exception was caught:" << ex.description() << "\nExiting.\n" << endl;
		}
	}
	catch ( SocketException& e )
	{
		cout << strThread << "Exception was caught:" << e.description() << "\nExiting.\n" << endl;
	}
	pthread_mutex_lock( &mutex2 );
	if( nThreads > 0 )
		nThreads--;
	pthread_mutex_unlock( &mutex2 );
	if( new_sock )
		delete new_sock;
	stThread->status = FINISHED;
	pthread_exit(NULL);
}

int main ( int argc, int argv[] )
{
  threads stThreads[MAX_CONNECTIONS];
  for( int i = 0; i < MAX_CONNECTIONS; i++ )
  {
  	stThreads.status = INIT;
  	stThreads.id = i;
  }
  int threadsIndex = 0; // an index to the circular vector of stThreads
  
  while( true )
  {
  	if( nThreads < MAX_CONNECTIONS )
  	{
		pthread_mutex_lock( &mutex2 );
		nThreads++;
		pthread_mutex_unlock( &mutex2 );
		for( int i = 0; i < MAX_CONNECTIONS; i++ )
		{
			if( stThreads.status == FINISHED )
			{
				threadsIndex = i; //the thread to be created must be at the position 'i'
				delete stThreads.thread; //cleaning the thread
				stThreads.status = INIT; //changing its status
				break;
			}
		}
		stThreads[threadsIndex].thread = new pthread_t; //create the thread
		pthread_create(stThreads[threadsIndex].thread, 0, listen, &stThreads[threadsIndex] );
		threadsIndex++;
  	}
  	usleep(100);
  }
  pthread_exit(NULL);
}

Hello all!

I found the cause for it..

(from Further Threads Programming:Thread Attributes (POSIX))

When i initialized the threadattr whit the parameter PTHREAD_CREATE_DETACHED there was no memory leak anymore!
!!!!!
:):):):):):slight_smile:

*just to remember that this socket implementation is not a good one for producing, since it creates one thread per each new connection accepted...
The best way to implemented is to limit a maximum number of connections.