Last update: 2009-05-09 (土) 14:41:50
Symbianメモ:アクティブオブジェクト
アクティブオブジェクトと非同期サービスの概念ついて
アクティブオブジェクトっていうのは非同期サービス(非同期サービスプロバイダというらしい)のラッパーと考える。
で、非同期サービスプロバイダは、非同期の名の通り、アクティブオブジェクトとはプロセスかスレッドが違うもの。
非同期サービスプロバイダの一例として、よく使うRTimerを併記します。
①アクティブオブジェクトが非同期サービスプロバイダに要求を発行。
その際、アクティブオブジェクトのiStatusを非同期サービスプロバイダが変更できるように参照(かポインタ)で渡す。
RTimerの例)
iTimer.After( iStatus, [時間] );
②非同期サービスプロバイダは受け取ったアクティブオブジェクトのiStatusをKRequestPendingに変更して処理を行う。
iStatus = KRequestPending;
RTimerの例)
RTimer::After()のプロトタイプは
void After(TRequestStatus &aStatus, TTimeIntervalMicroSeconds32 anInterval );
となっていてiStatusは参照でaStatusとして受けているので内部で
aStatus = KRequestPending;
とかしてると思われます。
③アクティブオブジェクトは自分自身のSetActive()を呼び出して非同期サービス実行中(要求が未解決)であることをアクティブスケジューラに通知する。
④非同期サービスプロバイダは処理が完了したらUser::RequestComplete()を呼び出してアクティブスケジューラに完了イベントを通知、結果を渡す(ポストする)。
User::RequestComplete( &iStatus, [結果] );
結果のところにはKErrNoneとかポストする結果を入れます。
実際はポインタで渡すので変数を介するのがいいのか?
TRequestStatus * pStat = &iStatus; User::RequestComplete( pStat, KErrNone );
RTimerの例)
RTimer::After()の中で指定時間後に呼び出してると思われます。
⑤アクティブスケジューラは完了イベントを処理し、アクティブオブジェクトのRunL()を呼び出す。
補足
ちなみに同期、SetActive()後、すぐにRunL()を実行する場合は②を省略して自分自身で④をした後、③をするわけです。
RThreadで自分でスレッドを作った場合は②と④をちゃんと実行する必要があります。