This is the mail archive of the
pthreads-win32@sources.redhat.com
mailing list for the pthreas-win32 project.
Re: Handle leak when using pthread mutex with win32 api threads
- From: Ross Johnson <rpj at callisto dot canberra dot edu dot au>
- To: Pthreads-Win32 list <pthreads-win32 at sources dot redhat dot com>
- Date: Tue, 08 Mar 2005 12:22:02 +1100
- Subject: Re: Handle leak when using pthread mutex with win32 api threads
- References: <acf63ee050305053177936d0b@mail.gmail.com>
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
>