私はスケジューラクラスを実装したいと思います。オブジェクトはタイムアウトをスケジューリングし、必要に応じてキャンセルすることができます。タイムアウトが経過すると、この情報はその時点で非同期にタイムアウト設定/所有者に送信されます。Windowsでスケジューラクラスを実装する
したがって、私は2つの基本クラスWindowsTimeoutとWindowsSchedulerを持っています。
class WindowsTimeout
{
bool mCancelled;
int mTimerID; // Windows handle to identify the actual timer set.
ITimeoutReceiver* mSetter;
int cancel()
{
mCancelled = true;
if (timeKillEvent(mTimerID) == SUCCESS) // Line under question # 1
{
delete this; // Timeout instance is self-destroyed.
return 0; // ok. OS Timer resource given back.
}
return 1; // fail. OS Timer resource not given back.
}
WindowsTimeout(ITimeoutReceiver* setter, int timerID)
{
mSetter = setter;
mTimerID = timerID;
}
};
class WindowsScheduler
{
static void CALLBACK timerFunction(UINT uID,UINT uMsg,DWORD dwUser,DWORD dw1,DWORD dw2)
{
WindowsTimeout* timeout = (WindowsTimeout*) uMsg;
if (timeout->mCancelled)
delete timeout;
else
timeout->mDestination->GEN(evTimeout(timeout));
}
WindowsTimeout* schedule(ITimeoutReceiver* setter, TimeUnit t)
{
int timerID = timeSetEvent(...);
if (timerID == SUCCESS)
{
return WindowsTimeout(setter, timerID);
}
return 0;
}
};
私の質問は以下のとおりです。
Q.1。 WindowsScheduler :: timerFunction()呼び出しが行われると、この呼び出しはどのコンテキストで実行されますか?これは単なるコールバック関数であり、OSコンテキストによって実行されると思います。そうであれば、この呼び出しはすでに実行中の他のタスクを先取りしますか?コールバックの優先度は他のどのユーザータスクよりも高いのですか?
Q.2。タイムアウト設定がタイムアウトをキャンセルしたい場合、WindowsTimeout :: cancel()を呼び出します。 しかし、キャンセル操作を先取りして、例えば、mCancelled = trueステートメントの直後など、OSによってコールバックされるtimerFunction静的呼び出しが常に存在する可能性があります。このような場合、タイムアウトインスタンスはコールバック関数によって削除されます。 コールバック関数の実行が完了したあとで、先取りされたcancel()関数が再び呼び出されると、削除されたインスタンス(mTimerID)の属性にアクセスしようとします。コード。
どうすればこのようなケースを回避できますか? - 私はそれがタイマーAPIによって割り当てられたスレッド内で呼び出されると信じてい Windows multimedia timer with callback argument
どうかありますか? – bethoven25