Entries

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

timeSetEventとクリティカルセクション

タグ: WindowsCE C++
#include <windows.h>
#include <stdio.h>

CRITICAL_SECTION cs;

void CALLBACK TimerProc(UINT /*uTimerID*/, UINT /*uMsg*/, DWORD dwUser, DWORD /*dw1*/, DWORD /*dw2*/)
{
    ::wprintf(L" %d will lock...\n", dwUser);
    ::EnterCriticalSection(&cs);
    ::wprintf(L" %d locked\n", dwUser);
    ::wprintf(L" %d unlock\n", dwUser);
    ::LeaveCriticalSection(&cs);
}

#ifdef WINCE
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
#else
int main()
#endif // WINCE
{
    ::InitializeCriticalSection(&cs);
    for(int i = 0; i < 3; i++)
    {
        ::wprintf(L"%d will lock...\n", i);
        ::EnterCriticalSection(&cs);
        ::wprintf(L"%d locked\n", i);
        ::Sleep(300);
        ::timeSetEvent(200, 1, TimerProc, i, TIME_ONESHOT);
        ::wprintf(L"%d unlock\n", i);
        ::LeaveCriticalSection(&cs);
    }
    ::Sleep(10000);
    ::DeleteCriticalSection(&cs);
    return 0;
}

このコード、Windows XP SP2では問題なく動作するが、

0 will lock...
0 locked
0 unlock
1 will lock...
1 locked
 0 will lock...
1 unlock
 0 locked
 0 unlock
2 will lock...
2 locked
 1 will lock...
2 unlock
 1 locked
 1 unlock
 2 will lock...
 2 locked
 2 unlock

Windows CE 5.0で動かすとデッドロックする。

0 will lock...
0 locked
0 unlock
1 will lock...
1 locked
 0 will lock...

固まり方を見るに、どうやらCE 5.0では「TimerProc呼出し」と「timeSetEvent呼出し」は排他関係にあるらしい。

waveOut*** 系の罠:Code & Note

「コールバック関数内からこういった関数を呼ぶな」、ということは、

「中で排他制御してるから、それを考慮してやれよ」ということなのだ。

むぅ……「『EnterCriticalSectionは使える』と書いてあるから遠慮無く使わせてもらおう」と短絡的に考えるのは浅はかである、と。
奥が深い。

でももうちょっと分かりやすく書いてほしいよMSDN(´・ω・`)

スポンサーサイト

コメント

コメントの投稿

コメントの投稿
管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://idlysphere.blog66.fc2.com/tb.php/241-5ede6350
この記事にトラックバックする(FC2ブログユーザー)

Appendix

タグ

Blog内検索

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。