Cannot get thread ID with Thread.getThis() in specific callback functions on Windows

Haruki Shigemori rayerd.wiz at gmail.com
Thu Dec 9 11:35:07 PST 2010


(2010/12/07 20:02), Max Samukha wrote:
> On 12/06/2010 10:47 PM, Mike Parker wrote:
>> On 12/7/2010 2:10 AM, Haruki Shigemori wrote:
>>> (2010/12/06 16:59), Denis Koroskin wrote:
>>>> Because D runtime doesn't know about the newly created thread, and
>>>> static constructors weren't called. Try calling the following in your
>>>> callbacks:
>>>>
>>>> if (Thread.getThis() is null) thread_attachThis(); // if
>>>> (dont_know_about_this_thread) initialize_it();
>>>
>>> Wow... Is this D's design?
>>> I want phobos or druntime to take care of this problem.
>>> Is it difficult?
>>
>> The problem is that the thread is created outside of druntime, internal
>> to the Windows API. How is druntime to know about it unless you tell it?
>
> This could be done by installing a kernel driver that would use
> PsSetCreateThreadNotifyRoutine (if I remember the name correctly) to
> register a callback that would use an IPC mechanism to notify druntime
> about new threads created by the system. Chances that this approach will
> be adopted by druntime are less than zero.

As you said, it seems difficult to run away from this problem.
But, this problem causes the phenomenon that is hard to reappear.

import win32.windows;
import win32.mmsystem;
import std.stdio;
import core.thread;

extern (Windows)
void waveInProc(in HWAVEIN handle, in uint message, in DWORD instance, 
in DWORD param1, in DWORD param2)
{
     int[] a;
     int[] b = a.dup; // Access violation occurs in druntime rarely.

     //auto tid = Thread.getThis();
     //assert(tid); // assertion failure
}

void main()
{
     foreach (_; 0..1000) // many times
     {
         WAVEFORMATEX formatEx;
         with (formatEx)
         {
                 wFormatTag = WAVE_FORMAT_PCM;
                 nChannels = 1;
                 nSamplesPerSec = 44100;
                 wBitsPerSample = 16;
                 nBlockAlign = cast(ushort)(wBitsPerSample * nChannels / 8);
                 nAvgBytesPerSec = nSamplesPerSec * nBlockAlign;
         }

         HWAVEIN handle;
         waveInOpen(&handle, WAVE_MAPPER, cast(WAVEFORMATEX*)&formatEx, 
cast(DWORD)&waveInProc, cast(DWORD)null, CALLBACK_FUNCTION);

         uint bufferSize = cast(uint)(formatEx.nAvgBytesPerSec * 
1/+second+/);
         WAVEHDR* hdr = new WAVEHDR;
         hdr.lpData = cast(LPSTR)new ushort[bufferSize];
         hdr.dwBufferLength = bufferSize;
         hdr.dwFlags = 0;
         hdr.dwLoops = 0;

         waveInPrepareHeader(handle, hdr, WAVEHDR.sizeof);
         waveInAddBuffer(handle, hdr, WAVEHDR.sizeof);
         waveInStart(handle);

         waveInClose(handle);
     }
}

Because the following "t" is null in core.thread.getThis rarely.
Why? I think that we should react to this problem.

core.thread.d(1214): t = thread_findByAddr( GetCurrentThreadId() );


More information about the Digitalmars-d mailing list