MSDN states, with regard to CreateCompatibleDC(HDC hdc):
If hdc is NULL, the thread that calls CreateCompatibleDC owns the HDC that is created. When this thread is destroyed, the HDC is no longer valid. Thus, if you create the HDC and pass it to another thread, then exit the first thread, the second thread will not be able to use the HDC.
This was noticed because a recent test bot on Chromium caught this with the following error message
12:39:22 drmemory_analyze.py [INFO] Found 1 error reports
12:39:22 drmemory_analyze.py [INFO] Report #1
GDI USAGE ERROR: DC 0x710107bc used for select was created by now-exited thread 4540 by duplicating NULL, which makes it a thread-private DC
# 0 skia.dll!HDCOffscreen::draw [third_party\skia\src\ports\skfonthost_win.cpp:512]
# 1 skia.dll!SkScalerContext_GDI::generateImage [third_party\skia\src\ports\skfonthost_win.cpp:1296]
# 2 skia.dll!SkScalerContext::getImage [third_party\skia\src\core\skscalercontext.cpp:692]
# 3 skia.dll!SkGlyphCache::findImage [third_party\skia\src\core\skglyphcache.cpp:327]
# 4 skia.dll!D1G_NoBounder_RectClip [third_party\skia\src\core\skdraw.cpp:1493]
# 5 skia.dll!SkDraw::drawText [third_party\skia\src\core\skdraw.cpp:1751]
# 6 skia.dll!SkBitmapDevice::drawText [third_party\skia\src\core\skdevice.cpp:471]
# 7 skia.dll!SkCanvas::drawText [third_party\skia\src\core\skcanvas.cpp:1979]
# 8 media.dll!media::FakeVideoCaptureDevice::OnCaptureTask [media\video\capture\fake_video_capture_device.cc:202]
# 9 media.dll!base::internal::RunnableAdapter<void (__thiscall media::FakeVideoCaptureDevice::*)(void)>::Run [base\bind_internal.h:134]
Note: @0:01:18.938 in thread 7928
Note: DC was allocated here:
Note: # 0 system call NtGdiCreateCompatibleDC
Note: # 1 GDI32.dll!CreateCompatibleDC+0xf (0x770a5504 <GDI32.dll+0x15504>)
Note: # 2 skia.dll!HDCOffscreen::draw [third_party\skia\src\ports\skfonthost_win.cpp:465]
Note: # 3 skia.dll!SkScalerContext_GDI::generateImage [third_party\skia\src\ports\skfonthost_win.cpp:1296]
Note: # 4 skia.dll!SkScalerContext::getImage [third_party\skia\src\core\skscalercontext.cpp:692]
Note: # 5 skia.dll!SkGlyphCache::findImage [third_party\skia\src\core\skglyphcache.cpp:327]
Note: # 6 skia.dll!D1G_NoBounder_RectClip [third_party\skia\src\core\skdraw.cpp:1493]
Note: # 7 skia.dll!SkDraw::drawText [third_party\skia\src\core\skdraw.cpp:1751]
Note: # 8 skia.dll!SkBitmapDevice::drawText [third_party\skia\src\core\skdevice.cpp:471]
Note: # 9 skia.dll!SkCanvas::drawText [third_party\skia\src\core\skcanvas.cpp:1979]
Note: #10 media.dll!media::FakeVideoCaptureDevice::OnCaptureTask [media\video\capture\fake_video_capture_device.cc:202]
Note: #11 media.dll!base::internal::RunnableAdapter<void (__thiscall media::FakeVideoCaptureDevice::*)(void)>::Run [base\bind_internal.h:134]
Comment 1 by hcm@google.com
, Sep 22 2014