This is the mail archive of the pthreads-win32@sources.redhat.com mailing list for the pthreas-win32 project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Handle leak when using pthread mutex with win32 api threads


The problem has been found, fixed and tested, and was indeed a problem
in the library.

Each POSIX handle keeps a duplicate of the underlying Win32 thread's
handle. Deliberately, but mistakenly, this duplicate handle was not
being closed for implicitly created pthreads handles (those not created
via a call to pthread_create).

It will be in CVS soon, and a new snapshot will be available later
today.

Many thanks.
Ross

On Sat, 2005-03-05 at 15:31 +0200, Dmitrii Sernii wrote:
> > > >        static pthread_mutex_t mutex(PTHREAD_RECURSIVE_MUTEX_INITIALIZER);
> > >
> > > that line above is not thread safe.  you might initialize the same
> > > mutex multiple times.  Not good.
> > >
> > 
> > The handle leak comes about because, in pthreads-win32, pthread_mutex_t
> > is only a pointer, and the actual mutex struct is malloced by the
> > library, in this case, the first time you call pthread_mutex_lock().
> > That is, the library just calls pthread_mutex_init() for you. Also, you
> > must always call pthread_mutex_destroy() to clean up, just the same as
> > if you had called pthread_mutex_init() yourself.
> 
> I've made small corrections in test sample, so now mutex initialised
> only once, and i've added pthread_mutex_destroy() function call. But
> the problem still remains.
> Here is two test applications - one of them uses API threads, and the
> other pthreads. Program with pthreads don't have any leaks, while
> program with API threads produces lots of them.
> 
> //program with handle leaks
> #include <pthread.h>
> #include <windows.h>
> #include <conio.h>
> 
> pthread_mutex_t mutex(PTHREAD_RECURSIVE_MUTEX_INITIALIZER);
> 
> DWORD WINAPI threadProc(void *param)
> {
> 	pthread_mutex_lock(&mutex);
> 	pthread_mutex_unlock(&mutex);
> 	return 0;
> }
> 
> void main()
> {
> 	const int max_threads = 500;
> 	DWORD id;
> 	HANDLE th[max_threads];
> 	int i;
> 	for (i=0;i<max_threads;i++)
> 	th[i]=CreateThread(0,0,threadProc,0,0,&id);
> 
> 	for (i=0;i<max_threads;i++)
> 	{
> 		WaitForSingleObject(th[i],INFINITE);
> 		CloseHandle(th[i]);
> 	}
> 	pthread_mutex_destroy(&mutex);
> 	getch();
> }
> 
> ==========================
> 
> //program without handle leaks
> #include <pthread.h>
> #include <windows.h>
> #include <conio.h>
> 
> 
> pthread_mutex_t mutex(PTHREAD_RECURSIVE_MUTEX_INITIALIZER);
> 
> void* threadProc(void *param)
> {
> 	pthread_mutex_lock(&mutex);
> 	pthread_mutex_unlock(&mutex);
>     return 0;
> }
> 
> void main()
> {
> 	const int max_threads = 500;
> 	DWORD id;
> 	pthread_t th[max_threads];
> 	int i;
> 
> 	for (i=0;i<max_threads;i++)
> 			pthread_create(&(th[i]),0,threadProc,(void*)i);
> 
> 	for (i=0;i<max_threads;i++)
> 		pthread_join(th[i],(void**)&id);
> 
> 	pthread_mutex_destroy(&mutex);
> 	getch();
> }
> 
> Best regards,
> Dmitrii Sernii
> 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]