c11/threads: Don't implement thrd_current on Windows.

GetCurrentThread() returns a pseudo-handle (a constant which only makes
sense when used within the calling thread) and not a real handle.

DuplicateHandle() will return a real handle, but it will create a new
handle every time we call.  Calling DuplicateHandle() here means we will
leak handles, which can cause serious problems.

In short, the Windows implementation of thrd_t needs a thorough make
over, and it won't be pretty.  It looks like C11 committee
over-simplified things: it would be much better to have seperate objects
for threads and thread IDs like C++11 does.

For now, just comment out the thrd_current() implementation, so we get
build errors if anybody tries to use it.

Thanks to Brian Paul for spotting and diagnosing this problem.

Cc: "10.0" "10.1" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Brian Paul <brianp@vmware.com>
This commit is contained in:
José Fonseca
2014-03-03 15:06:19 +00:00
parent e8d85034da
commit a61d859519

View File

@@ -492,12 +492,42 @@ thrd_create(thrd_t *thr, thrd_start_t func, void *arg)
return thrd_success; return thrd_success;
} }
#if 0
// 7.25.5.2 // 7.25.5.2
static inline thrd_t static inline thrd_t
thrd_current(void) thrd_current(void)
{ {
return GetCurrentThread(); HANDLE hCurrentThread;
BOOL bRet;
/* GetCurrentThread() returns a pseudo-handle, which is useless. We need
* to call DuplicateHandle to get a real handle. However the handle value
* will not match the one returned by thread_create.
*
* Other potential solutions would be:
* - define thrd_t as a thread Ids, but this would mean we'd need to OpenThread for many operations
* - use malloc'ed memory for thrd_t. This would imply using TLS for current thread.
*
* Neither is particularly nice.
*
* Life would be much easier if C11 threads had different abstractions for
* threads and thread IDs, just like C++11 threads does...
*/
bRet = DuplicateHandle(GetCurrentProcess(), // source process (pseudo) handle
GetCurrentThread(), // source (pseudo) handle
GetCurrentProcess(), // target process
&hCurrentThread, // target handle
0,
FALSE,
DUPLICATE_SAME_ACCESS);
assert(bRet);
if (!bRet) {
hCurrentThread = GetCurrentThread();
}
return hCurrentThread;
} }
#endif
// 7.25.5.3 // 7.25.5.3
static inline int static inline int
@@ -511,7 +541,7 @@ thrd_detach(thrd_t thr)
static inline int static inline int
thrd_equal(thrd_t thr0, thrd_t thr1) thrd_equal(thrd_t thr0, thrd_t thr1)
{ {
return (thr0 == thr1); return GetThreadId(thr0) == GetThreadId(thr1);
} }
// 7.25.5.5 // 7.25.5.5