On Sat, Nov 06, 2010 at 12:41:11AM +0100, Matthias Bolte wrote: > 2010/11/2 Daniel P. Berrange <berrange@xxxxxxxxxx>: > > +struct virThreadArgs { > > + Â ÂvirThreadFunc func; > > + Â Âvoid *opaque; > > +}; > > + > > +static unsigned int __stdcall virThreadHelper(void *data) > > +{ > > + Â Âstruct virThreadArgs *args = data; > > + Â Âargs->func(args->opaque); > > + Â Âreturn 0; > > +} > > + > > +int virThreadCreate(virThreadPtr thread, > > + Â Â Â Â Â Â Â Â Â Âbool joinable ATTRIBUTE_UNUSED, > > + Â Â Â Â Â Â Â Â Â ÂvirThreadFunc func, > > + Â Â Â Â Â Â Â Â Â Âvoid *opaque) > > +{ > > + Â Âstruct virThreadArgs args = { func, opaque }; > > + Â Âthread->thread = (HANDLE)_beginthreadex(NULL, 0, virThreadHelper, &args, 0, NULL); > > + Â Âreturn 0; > > +} > > When you create a non-joinable thread then you won't call > virThreadJoin on it and you''ll leak the handle. Therefore, we should > use _beginthread here instead of _beginthreadex when creating a > non-joinable thread, because _endthread will close the thread's handle > when the thread's function returns. > > See http://msdn.microsoft.com/en-us/library/kdzttdcb(VS.71).aspx > > > + > > +void virThreadSelf(virThreadPtr thread) > > +{ > > + Â ÂHANDLE handle = GetCurrentThread(); > > + Â ÂHANDLE process = GetCurrentProcess(); > > + > > + Â ÂDuplicateHandle(process, handle, process, > > + Â Â Â Â Â Â Â Â Â Â&thread->thread, 0, FALSE, > > + Â Â Â Â Â Â Â Â Â ÂDUPLICATE_SAME_ACCESS); > > +} > > If virThreadJoin is not called on virThreadPtr initialized by > virThreadSelf then the duplicated handle leaks. > > See http://msdn.microsoft.com/en-us/library/ms683182(VS.85).aspx To deal with this, I'm using the same trick that GLib2 uses for libgthread, and storing the 'self' HANDLE in a thread local that we then close when the thread exits. > > +void virThreadJoin(virThreadPtr thread) > > +{ > > + Â ÂWaitForSingleObject(thread->thread, INFINITE); > > + Â ÂCloseHandle(thread->thread); > > +} > > + > > This might create really subtle double-CloseHandle bugs when you call > it twice on the same virThreadPtr or call it accidentally on an > non-joinable thread that already exited and _endthread had close the > handle. In both cases Windows might already reused the closed handle > and the second call to CloseHandle might close something completely > unrelated. Initializing thread->thread back to 0 should take care of that problem. Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list