Re: [PATCH 07/11] Introduce portability APIs for creating threads

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]