ブロック手続

イベントが起こるのを待った上でプログラムの実行を再開する READWAITONMOUSEEVENT (どちらもユーザー入力を待ちます) などの手続は,待っているイベントが起こるまでプログラムの実行をブロックするので,ブロック手続と呼ばれます。QuickWin の子プロセスは,複数のコールバック・ルーチンを含むことができます。たとえば,個々のメニュー選択と個々の種類のマウス・クリック (左ボタン,右ボタン,ダブルクリックなど) について,異なるルーチンを呼び出させることができます。

プロセスとそのコールバック・ルーチン,または同じプロセス中の 2 つのコールバック・ルーチンが,両方ともブロック手続を含んでいると,問題が生じることがあります。これは,個々の QuickWin 子プロセスが第 1 スレッドと第 2 スレッドをサポートしているのが原因です。

プロセスの主スレッドがブロック手続を呼び出した後に,メニュー項目を選択した結果としてメニュー手続がやはりブロック手続を呼び出すというようなことが起こることがあります。たとえば,ファイルをロードするためのオプションを含んでいる「File」メニューを作成したとしましょう。「LOAD」オプションを選択すると,ファイル名の入力を求め,ユーザーが名前を入力するまで待機するブロック関数が呼び出されます。一方,ユーザーが「LOAD」オプションを選択した時点で,主プロセスが WAITONMOUSEEVENT などのブロック呼び出しで実行を中断していたとすると,2 つのブロック関数が開始されたことになります。

QuickWin は,2 つのブロック呼び出しが実行を中断していると,先に行われたブロック呼び出しに対応するメッセージをステイタスバーに表示します。2 つのスレッド中に,他にもブロック手続を使用するコールバックがあった場合,ステイタスバーは実際に中断されている入力に対応しなくなる可能性があり,実行が実際とは別のスレッド上で起こっているように見え,ユーザーにとってわかりにくく,誤解を招くアプリケーションになりかねません。

このような混乱を避けるために,コールバック・ルーチン中ではブロック手続を使用しないようにするべきです。QuickWin は,同じ子ウィンドウから,ユーザー・コールバックを通して,同時に 2 つ以上の READ または INCHARQQ 要求は受け付けません。1 つの READ または INCHARQQ 要求が保留中になっていると,それ以降の READ または INCHARQQ 要求は無視され,呼び出し側に -1 が返されます。

ユーザーのシナリオによって,READ または INCHARQQ 要求を含んでいる複数のコールバック・ルーチンを呼び出す可能性がある子ウィンドウがある場合,返し値を検証して,要求が成功したかどうかを確認し,成功しなかった場合には再び要求を行うなどの適切な動作を実行するようにする必要があります。

この予防的な QuickWin の動作は,マウス入力オプションのマウス選択を通して複数のブロック呼び出しの発生は防ぎません。一般的な規則として,予期しない,解釈の難しいプログラムの流れを引き起こす可能性があるということから,コールバック・ルーチン中でブロック手続を使用することは勧められません。