(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() );

Reply via email to