
On Sat, Nov 06, 2010 at 12:41:11AM +0100, Matthias Bolte wrote:
2010/11/2 Daniel P. Berrange <berrange@redhat.com>:
+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 :|