ToolTalk ユーザーズガイド

第 8 章 メッセージの送信

この章では、メッセージの経路を指定する方法と ToolTalk メッセージの属性とアルゴリズムについて説明します。メッセージの作成、メッセージ内容の書き込み、要求へのコールバックの付加、およびメッセージの送信方法についても説明します。

ToolTalk サービスによるメッセージのルーティング方法

アプリケーションは、「通知」と「要求」という 2 つのクラスの ToolTalk メッセージを送信できます。通知は情報メッセージであり、アプリケーションがイベントについて連絡する手段です。通知を受信したアプリケーションは、結果を送信側へ返さずにメッセージを吸収します。要求とは、処理を求めるメッセージです。処理の結果がメッセージに記録され、それが応答として送信側に返されます。

通知の送信

通知メッセージは、一方方向で送信されます。この様子を図 8-1 に示します。

図 8-1 通知のルーティング

Graphic

送信側プロセスは、メッセージを作成し、属性値を書き込んでから送信します。ToolTalk サービスは、メッセージとパターン属性値を照合して、1 つのハンドラと、一致するすべてのオブザーバにメッセージを送信します。ファイルに配信範囲指定したメッセージは、セッションの境界を越えて、ファイルを処理対象として宣言しているプロセスに自動転送されます。

要求の送信

要求メッセージを送信する場合、要求は送信側とハンドラの間を往復します。要求メッセージのコピーは、処理の対象としているオブザーバへ一方方向で送信されます。図 8-2 は、要求のルーティングの手順を示しています。

図 8-2 要求のルーティング

Graphic

ToolTalk サービスは、1 つのハンドラだけに要求を送信します。ハンドラは、メッセージに結果を追加して返信します。その他のプロセスは、要求が処理される前後、またはその両方の時点で、要求を監視できます。オブザーバは、要求を送り返さずに要求を吸収します。

オファの送信

オファは要求に似たメッセージですが、データを送信しても応答は期待できません。また、メッセージの送信時に、その受信者数をあらかじめ予測できます。また、これらの受信者がそのメッセージを受信、拒絶、または忌避したかを知ることができます。したがって、オファは通知や要求に比べて、一般性が低いと言えます。

送信したメッセージの状態の変化

送信した要求を追跡できるよう、要求の状態が変化するたびに送信側にメッセージが送られます。状態の変化を知らせるこのメッセージは、パターンを登録していなくても、メッセージのコールバックを指定していなくても送られます。

メッセージの属性

ToolTalk メッセージには、メッセージ情報を格納して配信情報を ToolTalk サービスに提供する属性が含まれています。配信情報は、メッセージを適切な受信側へルーティングするために使用されます。

ToolTalk メッセージは、アドレス、サブジェクト (「操作」や「引数」など)、および配信情報 (「クラス」や「配信範囲」など) の属性を含む単純な構造体です。メッセージの属性を表 8-1 に示します。

表 8-1 ToolTalk メッセージの属性

メッセージの属性 

値 

機能 

使用できる人 

引数 

引数または結果 

操作に使用する引数を指定する。メッセージが応答である場合、これらの引数は操作の結果を含む 

送信側と受信側 

クラス 

TT_NOTICE, TT_REQUEST, TT_OFFER

受信側が操作を実行する必要があるかどうかを指定する 

送信側 

ファイル 

char *pathname

操作に関連するファイルを指定する。メッセージの配信範囲がファイルに関係しない場合、このメッセージ属性は無効である 

送信側と ToolTalk 

オブジェクト 

char *objid

操作に関係するオブジェクトを指定する 

送信側と ToolTalk 

操作 

char *opname

実行する操作名を指定する 

送信側 

otype 

char *otype

操作に関係するオブジェクトの型を指定する 

送信側と ToolTalk 

アドレス 

TT_PROCEDURE, TT_OBJECT, TT_HANDLER, TT_OTYPE

メッセージを送信する場所を指定する 

送信側 

ハンドラ 

char *procid

受信側プロセスを指定する 

送信側と ToolTalk 

handler_ptype 

char *ptype

受信側プロセスの型を指定する 

送信側と ToolTalk 

処置 

TT_DISCARD, TT_QUEUE, TT_START

TT_START+TT_QUEUE

実行中のプロセスがメッセージを受信できない場合に取るべき手段を指定する 

送信側と ToolTalk 

配信範囲 

TT_SESSION, TT_FILE, TT_BOTH, TT_FILE_IN_SESSION

セッションまたはファイルに対して登録された内容に基づいて、受信する可能性のあるアプリケーションを指定する 

送信側と ToolTalk 

sender_ptype 

char *ptype

送信側プロセスの型を指定する 

送信側と ToolTalk 

セッション 

char *sessid

送信側プロセスのセッションを指定する 

送信側と ToolTalk 

状態 

int status, char *status_str

メッセージの状態に関する追加情報を指定する 

受信側と ToolTalk 

アドレス属性

他のアプリケーションにアドレス指定されたメッセージは、特定のプロセス、またはメッセージに一致するパターンを登録してあるプロセスにアドレス指定できます。メッセージをプロセスにアドレス指定するときは、他のアプリケーションのプロセス ID (procid) を知っている必要があります。ただしプロセスは、通常は互いの procid を知りません。ほとんどの場合、送信側はどのプロセスが操作 (要求メッセージ) を実行するのか、またはどのプロセスがイベント (通知メッセージ) を認識するのかを知らなくてもかまいません。

配信範囲属性

通常、ToolTalk サービスを使用して通信するアプリケーションには共通点があります。アプリケーションが同じセッションで実行されていたり、同じファイルまたはデータを対象としていたりします。アプリケーションは、処理の対象を登録するために、ToolTalk サービスにセッションまたはファイル (あるいはその両方) を結合します。ファイル情報とセッション情報は、メッセージパターンが指定された ToolTalk サービスが、メッセージを受信するアプリケーションを判定するために使用します。


注 -

配信範囲属性機能を使用できるのは、NFS ファイルシステムと UFS ファイルシステムだけです。tmpfs ファイルシステムでは、ファイルへの配信範囲は指定できません。


ファイル配信範囲

メッセージをファイルに配信範囲指定した場合は、そのファイルを結合している (かつ残りの属性に一致している) アプリケーションだけがメッセージを受信します。1 つのファイルを処理の対象として共有するアプリケーションは、同じセッションで実行している必要はありません。

パターンへの設定

メッセージがファイル配信範囲であることをパターンに指定する際、使用できる型を表 8-2 に示します。

表 8-2 メッセージのファイル配信範囲をパターンに指定する際の型

配信範囲の型 

説明 

TT_FILE

指定したファイルだけを配信範囲とする。同時にセッション属性も設定すればセッション中のファイルと同様な配信範囲を指定できるが、配信範囲が TT_FILE になっていると、tt_session_join を呼び出してもそのパターンのセッション属性は更新されない

TT_BOTH

処理の対象となるファイルとセッションの「論理和」を配信範囲とする。ファイル、セッション、またはその両方を配信範囲とするメッセージに一致するのは、この配信範囲を指定したパターンだけである 

TT_FILE_IN_SESSION

処理の対象となるファイルとセッションの「論理積」を配信範囲とする。ファイルとセッションを同時に配信範囲とするメッセージにだけ一致するのは、この配信範囲を指定したパターンだけである 

TT_FILE_IN_SESSIONTT_SESSION の論理和を配信範囲に指定するには、例 8-1 のように両方の配信範囲を同じパターンに追加します。


例 8-1 TT_FILE_IN_SESSIONTT_SESSION の論理和を配信範囲に指定する場合

	tt_open();

	Tt_pattern pat = tt_create_pattern();
	tt_pattern_scope_add(pat, TT_FILE_IN_SESSION);
	tt_pattern_scope_add(pat, TT_SESSION);
	tt_pattern_file_add(pat, file);
	tt_pattern_session_add(pat, tt_default_session());
	tt_pattern_register(pat);


メッセージへの設定

メッセージのファイル配信範囲の型も、パターンと同じです。この型を表 8-3 に示します。

表 8-3 メッセージ用の配信範囲

配信範囲の型 

説明 

TT_FILE

処理対象のファイルを登録した全クライアントをメッセージの配信範囲とする 

TT_BOTH

処理対象のセッション、ファイル、またはセッションとファイルの両方を登録した全クライアントをメッセージの配信範囲とする 

TT_FILE_IN_SESSION

処理対象のファイルとセッションを同時に登録した全クライアントをメッセージの配信範囲とする 

TT_SESSION + tt_message_file_set()

処理対象のセッションを登録した全クライアントをメッセージの配信範囲とする。パターンが一致するクライアントは、メッセージを受信すると tt_message_file を呼び出して、そのファイル名を入手できる

メッセージの配信範囲が TT_FILE または TT_BOTH の場合は、ToolTalk クライアントライブラリが、そのファイルを処理対象とするクライアントのセッションをデータベースサーバーからすべて探し出し、それらの ToolTalk セッションにメッセージを送信します。ToolTalk セッションは、その後でメッセージとクライアントを照合します。メッセージの送信側は、tt_file_join を明示的に呼び出す必要はありません。

配信範囲が TT_FILE_IN_SESSION または TT_SESSION のメッセージにファイルを指定しても、ToolTalk データベースサーバーには連絡されず、メッセージは指定したセッション配信範囲のクライアントにしか送信されません。

セッション配信範囲

メッセージをセッションに配信範囲指定した場合は、そのセッションに接続しているアプリケーションだけが受信可能側であると見なされます。


例 8-2 セッションの設定

Tt_message m= tt_message_create();
tt_message_scope_set(m, TT_SESSION);
tt_message_file_set(m, file);


最初の行でメッセージを作成しています。2 行目ではメッセージの配信範囲を追加し、3 行目ではメッセージの範囲に影響を与えないファイル属性を追加しています。

セッション中のファイル配信範囲

アプリケーションは、メッセージ配信範囲として TT_FILE_IN_SESSION を指定することによって、メッセージ配布の範囲をかなり限定できます。指定したファイルとセッションの両方を結合しているアプリケーションだけが受信可能側であると見なされます。

また、アプリケーションは、メッセージのセッションを処理対象として登録しているすべてのクライアントを、TT_SESSIONtt_message_file_set を指定することによって、メッセージの配信範囲とすることもできます。パターンが一致するクライアントがメッセージを受信した場合、その受信側クライアントは tt_message_file を呼び出すことによってファイル名を取得できます。


例 8-3 ファイルの設定

Tt_message m= tt_message_create();
tt_message_scope_set(m, TT_FILE_IN_SESSION);
tt_message_file_set(m, file);


最初の行でメッセージを作成しています。2 行目ではメッセージの配信範囲を追加し、3 行目ではメッセージ配信範囲にファイルを追加しています。

構造化データのシリアル化

ToolTalk サービスではメッセージ引数のデータ型として、整数、NULL 終了文字列、バイト文字列の 3 種類をサポートしています。

ToolTalk メッセージで他のデータ型を送信する際、クライアントはデータをシリアル化して文字列またはバイト文字列に変換し、受信時はそのシリアル化を解除しなければなりません。今回の ToolTalk サービスとともに新しく提供する XDR 引数 API 呼び出しでは、これらの処理を関数として提供します。クライアントが用意するのは、XDR ルーチンとデータへのポインタだけです。ToolTalk サービスは、データをシリアル化して内部バッファに入れた後、そのデータをバイトストリームと同じように処理します。

ToolTalk のメッセージ配信アルゴリズム

この節では、ToolTalk サービスがメッセージの受信側を判定する方法について理解できるように、プロセス指向メッセージとオブジェクト指向メッセージの両方について、作成と配信方法を説明します。

プロセス指向メッセージの配信

プロセス指向メッセージに関して、メッセージを処理すべきプロセスの ptype または procid が送信側アプリケーションにわかっている場合があります。これに該当しないメッセージに関して、ToolTalk サービスはメッセージの操作と引数からハンドラを判定します。

  1. 初期化

    送信側はメッセージハンドルを取得し、アドレス属性、配信範囲属性、およびクラス属性を書き込みます。

    送信側は、操作属性と引数属性を書き込みます。

    送信側が ptype を 1 つだけ宣言した場合、ToolTalk サービスはデフォルトとして sender_ptype を書き込みます。それ以外の場合は、送信側が sender_ptype を書き込まなければなりません。

    配信範囲が TT_FILE の場合は、ファイル名を書き込む必要があります。書き込まない場合は、デフォルトのファイル名が使用されます。配信範囲が TT_SESSION の場合は、セッション名を書き込む必要があります。書き込まない場合は、デフォルトのファイル名が使用されます。配信範囲が TT_BOTH または TT_FILE_IN_SESSION の場合は、ファイル名とセッション名の両方を書き込む必要があります。書き込まない場合は、デフォルトのファイル名とセッション名が使用されます。


    注 -

    配信に関して検査される一連のパターンは、メッセージの配信範囲によって異なります。配信範囲が TT_SESSION の場合は、同じセッション内のプロセスのパターンだけが検査されます。配信範囲が TT_FILE の場合は、ファイルを監視するすべてのプロセスのパターンが検査されます。配信範囲が TT_FILE_IN_SESSION または TT_BOTH の場合は、その両者に該当するプロセスが検査されます。


    送信側は、handler_ptype がわかっている場合は書き込んでもかまいません。ただしその場合は、ある ptype のプロセスを別の ptype に置き換えられなくなるので、柔軟性がかなり低くなります。またこの場合、送信側が処置属性を指定しなければなりません。

  2. ハンドラへのディスパッチ

    ToolTalk サービスは、アドレス、配信範囲、メッセージクラス、操作、および引数のモードと型を、各 ptype の Handle セクションのすべてのシグニチャと比較します。

    操作と引数に一致し、ハンドルを指定するメッセージパターンを含んでいる ptype は、通常 1 つだけです。ToolTalk サービスは、ハンドラの ptype を検索すると、ptype のメッセージパターンから opnumhandler_ptype、および「処置」を書き込みます。

    アドレスが TT_HANDLER の場合、ToolTalk サービスは指定された procid を探索し、ハンドラのメッセージ待ち行列にメッセージを追加します。パターン照合は行わないので、TT_HANDLER メッセージを監視できません。

  3. オブザーバへのディスパッチ

    ToolTalk サービスは、配信範囲、クラス、操作、および引数の型を、各 ptype の Observe セクションのすべてのメッセージパターンと比較します。

    メッセージに一致して、TT_QUEUE または TT_START を指定するすべての監視シグニチャに関して、ToolTalk サービスは、ptype と待ち行列を指定するメッセージまたは開始オプションを指定するメッセージに、レコード (「約束監視」と呼ばれます) を付加します。その後 ToolTalk サービスは、内部の ObserverPtypeList に ptype を追加します。

  4. ハンドラへの配信

    実行中のプロセスがメッセージに一致する登録済みハンドラメッセージパターンを持っている場合、ToolTalk サービスはメッセージをそのプロセスに配信します。それ以外の場合、ToolTalk サービスは、処置 (開始または待ち行列) オプションに従います。

    ハンドラ情報に一致する動的パターンを複数のプロセスが登録している場合は、より限定的なパターン (ワイルドカード以外に一致しているものの数を数えることによって判定する) が優先されます。2 つのパターンが同等に限定的である場合、ハンドラが任意に選択します。

  5. オブザーバへの配信

    ToolTalk サービスは実行中のプロセスのうち、メッセージに一致するオブザーバパターンを登録したすべてのプロセスにメッセージを渡します。ToolTalk サービスは配信のたびに、オブザーバの ptype について約束監視の完了状態を検査します。このプロセスが終わった時点で未完了の約束監視が残っている場合、ToolTalk サービスは、その約束に指定されている開始オプションと待ち行列オプションに従います。

この例では、デバッガはエディタを使用して、ToolTalk メッセージを介してブレークポイント周辺のソースを表示します。

エディタは、ptype の中に次のハンドルパターンを持っています。

(HandlerPtype: TextEditor;
  Op: ShowLine;
  Scope: TT_SESSION;
  Session: my_session_id;
  File: /home/butterfly/astrid/src/ebe.c)

  1. デバッガはブレークポイントに到達すると、操作属性 (ShowLine)、引数属性 (行番号)、ファイル属性 (ファイル名)、セッション属性 (現在のセッション ID)、および配信範囲属性 (TT_SESSION) を含むメッセージを送信します。

  2. ToolTalk サービスは、登録されているすべてのパターンとメッセージを照合して、エディタが登録したパターンを検索します。

  3. ToolTalk サービスは、エディタにメッセージを配信します。

  4. その後エディタは、引数で示した行へスクロールします。

オブジェクト指向メッセージの配信

ToolTalk サービスが処理するメッセージの多くはオブジェクト宛てですが、実際にはオブジェクトを管理するプロセスに配信されます。メッセージは、特定のメッセージを処理できるプロセスの ptype を含んだ otype にシグニチャを書き込み、ToolTalk サービスがオブジェクト指向メッセージを配信する必要があるプロセスを判定するのを助けます。

  1. 初期化

    送信側はクラス属性、操作属性、引数属性、および対象とする objid 属性を書き込みます。

    送信側属性は、ToolTalk サービスによって自動的に書き込まれます。送信側は、sender_ptype 属性とセッション属性を書き込むことも、ToolTalk サービスにデフォルト値を書き込ませることもできます。

    配信範囲が TT_FILE の場合は、ファイル名を書き込む必要があります。書き込まない場合は、デフォルトのファイル名が使用されます。配信範囲が TT_SESSION の場合は、セッション名を書き込む必要があります。書き込まない場合は、デフォルトのセッション名が使用されます。配信範囲が TT_BOTH または TT_FILE_IN_SESSION の場合は、ファイル名とセッション名の両方を書き込む必要があります。書き込まない場合は、デフォルトのファイル名とセッション名が使用されます。


    注 -

    配信に関して検査される一連のパターンは、メッセージの配信範囲によって異なります。配信範囲が TT_SESSION の場合は、同じセッション内のプロセスのパターンだけが検査されます。配信範囲が TT_FILE の場合は、ファイルを監視するすべてのプロセスのパターンが検査されます。配信範囲が TT_FILE_IN_SESSION または TT_BOTH の場合は、その両者に該当するプロセスが検査されます。


  2. 解釈処理

    ToolTalk サービスは、ToolTalk データベースで objid を検索し、otype 属性とファイル属性を書き込みます。

  3. ハンドラへのディスパッチ

    ToolTalk は、otype 定義内でメッセージの操作属性と引数属性に一致するハンドラのメッセージパターンを検索します。一致するものが見つかると、ToolTalk サービスは otype のメッセージパターンから、配信範囲属性、opnum 属性、handler_ptype 属性、および処置属性を書き込みます。

  4. オブジェクト指向オブザーバへのディスパッチ

    ToolTalk サービスは、メッセージのクラス属性、操作属性、および引数属性を、otype のすべての Observe メッセージのパターンと比較します。一致するものが見つかると、メッセージパターンが TT_QUEUE または TT_START を指定している場合には、ToolTalk サービスは ptype と待ち行列を指定するメッセージ、または開始オプションを指定するメッセージに、レコード (「約束監視」と呼ばれる) を付加します。

  5. 手順オブザーバへのディスパッチ

    ToolTalk サービスは、メッセージのクラス属性、操作属性、および引数属性を、すべての ptypes のすべての Observe メッセージのパターンと比較します。一致するものが見つかると、シグニチャが TT_QUEUE または TT_START を指定している場合には、ToolTalk サービスは ptype と待ち行列を指定するメッセージ、または開始オプションを指定するメッセージに、約束監視のレコードを付加します。

  6. ハンドラへの配信

    実行中のプロセスがメッセージに一致した登録済みのハンドラパターンを持っている場合、ToolTalk サービスはメッセージをそのプロセスに配信します。それ以外の場合、ToolTalk サービスは、処置 (待ち行列または開始) オプションに従います。

    ハンドラ情報に一致する動的パターンを複数のプロセスが登録している場合は、より限定的なパターン (ワイルドカード以外に一致するものの数を数えることによって判定する) が優先されます。2 つのパターンが同時に限定的である場合は、ハンドラが任意に選択します。

  7. オブザーバへの配信

    ToolTalk サービスは、実行中のプロセスのうち、メッセージに一致するオブザーバパターンを登録したすべてのプロセスにメッセージを渡します。ToolTalk サービスは、配信のたびにオブザーバの ptype について約束監視の完了状態を検査します。このプロセスが終わった時点で未完了の約束監視がある場合、ToolTalk サービスは、その約束に指定されている処置 (待ち行列または開始) オプションに従います。

この例では、ToolTalk サービスに FinnogaCalc という架空のスプレッドシートアプリケーションを統合します。

  1. FinnogaCalc は ToolTalk サービスを起動し、FinnogaCalc という ptype を宣言してデフォルトのセッションに参加することによって ToolTalk へ登録します。

  2. FinnogaCalc は、hatsize.wks ワークシートをロードし、ワークシートファイルに結合することによって、ワークシートを監視することを ToolTalk サービスに通知します。

  3. 第 2 のインスタンスの FinnogaCalc (FinnogaCalc2 と呼びます) が起動し、ワークシート wardrobe.wks をロードし、同じ方法で ToolTalk に登録します。

  4. hatsize.wks のセル B2 の値を、wardrobe.wks のセル C14 に代入します。

  5. FinnogaCalc2 は、FinnogaCalc が FinnogaCalc2 に値を送信できるように ToolTalk 関数を呼び出して、セル C14 のオブジェクト仕様を作成します。このオブジェクトは、objid によって識別されます。

  6. その後 FinnogaCalc2 は、FinnogaCalc にその objid を (たとえばクリップボードを介して) 指示します。

  7. FinnogaCalc は、この objid によって識別されるオブジェクトにセル B2 を表示し、値を持つメッセージを送信することを記憶します。

  8. ToolTalk はメッセージの経路を指定します。ToolTalk サービスは、メッセージを配信するために次のことを行います。

    1. objid に関連付けられている仕様を検査して、objid の型が FinnogaCalc_cell であることと、対応するオブジェクトが wardrobe.wks ファイルの中にあることを確認します。

    2. FinnogaCalc_cell について otype の定義を参照します。ToolTalk サービスは otype から、ptype である FinnogaCalc のプロセスがこのメッセージを監視することと、メッセージの配信範囲が TT_FILE であることを判定します。

    3. メッセージを登録済みのパターンと照合して、適切なファイルを監視しているプロセスのうち、この ptype を持つすべてのプロセスを検索します。FinnogaCalc2 は一致しますが、FinnogaCalc は一致しません。

    4. FinnogaCalc2 にメッセージを配信します。

  9. FinnogaCalc2 は、セル C14 に対応するオブジェクトがメッセージに入っていることを認識します。FinnogaCalc2 は、wardrobe.wks の値を更新し、新しい値を表示します。

otype のアドレス指定

objid が不明なままオブジェクト指向メッセージを送信しなければならない場合があります。このような場合に備えて、ToolTalk サービスでは otype のアドレス指定ができます。このアドレス指定モードでは、送信側が操作、引数、配信範囲、および otype を指定する必要があります。ToolTalk サービスは、メッセージの操作と引数に一致するメッセージパターンについて指定した otype の定義を調べ、処理プロセスと監視プロセスを検索します。その後、特定のオブジェクト宛てのメッセージの場合と同様に、ディスパッチと配信を続けます。

ToolTalk メッセージを送信するためのアプリケーションの変更

アプリケーションは、ToolTalk メッセージを送信するために、いくつかの操作を実行しなければなりません。つまり、ToolTalk メッセージの作成と完了、メッセージコールバックルーチンの追加、および完了したメッセージの送信などの操作が必要です。

メッセージの作成

ToolTalk サービスは、メッセージを作成し完了するために次の 3 通りの方法を用意しています。

  1. 汎用関数

    • tt_message_create ( )

  2. プロセス指向の通知関数と要求関数

    • tt_pnotice_create ( )

    • tt_prequest_create ( )

  3. オブジェクト指向の通知関数と要求関数

    • tt_onotice_create ( )

    • tt_orequest_create ( )

プロセス指向およびオブジェクト指向の通知関数と要求関数を使用すると、一般的なメッセージが簡単に作成できます。これらの関数は、機能的には他の tt_message_create ( ) および tt_message_attribute_set ( ) 呼び出しの文字列と同じですが、より簡単に書き込みと読み取りができます。表 8-4表 8-5 は、メッセージの作成および完成用に使用する ToolTalk 関数を示しています。

表 8-4 メッセージ作成用の関数

ToolTalk 関数 

機能 

tt_onotice_create(const char *objid, const char *op)

オブジェクト指向の通知を作成する 

tt_orequest_create(const char *objid, const char *op)

オブジェクト指向の要求を作成する 

tt_pnotice_create(Tt_scope scope, const char *op)

プロセス指向の通知を作成する 

tt_prequest_create(Tt_scope scope, const char *op)

プロセス指向の要求を作成する 

tt_message_create(void)

メッセージを作成する。この関数は、メッセージ作成用の ToolTalk 汎用関数である 


注 -

すべての作成用関数が返す型は Tt_message です。


表 8-5 メッセージ完成用の関数

ToolTalk 関数 

機能 

tt_message_address_set(Tt_message m, Tt_address p)

アドレス指定モードを設定する (たとえば、ポイントツーポイント) 

tt_message_arg_add(Tt_message m, Tt_mode n, const char *vtype, const char *value)

NULL 終了文字列の引数を追加する 

tt_message_arg_bval_set(Tt_message m, int n, const unsigned char *value, int len)

引数の値を、指定されたバイト配列に設定する 

tt_message_arg_ival_set(Tt_message m, int n, int value)

引数の値を、指定された整数に設定する 

tt_message_arg_val_set(Tt_message m, int n, const char *value)

引数の値を、指定された NULL 終了文字列に設定する 

tt_message_barg_add(Tt_message m, Tt_mode n, const char *vtype, const unsigned char *value, int len)

バイト配列の引数を追加する 

tt_message_iarg_add(Tt_message m, Tt_mode n, const char *vtype, int value)

整数の引数を追加する 

tt_message_context_bval(Tt_message m, const char *slotname, unsigned char **value, int *len);

コンテキストの値を、指定されたバイト配列に取得する 

tt_message_context_ival(Tt_message m, const char *slotname, int *value);

コンテキストの値を、指定された整数に取得する 

tt_message_context_val(Tt_message m, const char *slotname);

コンテキストの値を、指定された文字列に取得する 

tt_message_icontext_set(Tt_message m, const char *slotname, int value);

コンテキストを、指定された整数に設定する 

tt_message_bcontext_set(Tt_message m, const char *slotname, unsigned char *value, int length);

コンテキストを、指定されたバイト配列に設定する. 

tt_message_context_set(Tt_message m, const char *slotname, const char *value);

コンテキストを、指定された NULL 終了文字列に設定する 

tt_message_class_set(Tt_message m, Tt_class c)

メッセージの型 (通知または要求) を設定する 

tt_message_file_set(Tt_message m, const char *file)

メッセージの配信範囲として指定するファイルを設定する 

tt_message_handler_ptype_set(Tt_message m, const char *ptid)

メッセージを受信する ptype を設定する 

tt_message_handler_set(Tt_message m, const char *procid)

メッセージを受信する procid を設定する 

tt_message_object_set(Tt_message m, const char *objid)

メッセージを受信するオブジェクトを設定する 

tt_message_op_set(Tt_message m, const char *opname)

メッセージを受信する操作を設定する 

tt_message_otype_set(Tt_message m, const char *otype)

メッセージを受信するオブジェクト型を設定する 

tt_message_scope_set(Tt_message m, Tt_scope s)

メッセージを受信する受信側 (ファイルまたはセッション、あるいはその両方) を設定する 

tt_message_sender_ptype_set(Tt_message m, const char *ptid)

メッセージの送信元であるアプリケーションの ptype を設定する 

tt_message_session_set(Tt_message m, const char *sessid)

メッセージの配信範囲として指定するセッションを設定する 

tt_message_status_set(Tt_message m, int status)

メッセージの状態を設定する。この状態は、受信側アプリケーションが参照する 

tt_message_status_string_set(Tt_message m, const char *status_str)

メッセージの状態を記述するテキストを設定する。このテキストは、受信側アプリケーションが参照する 

tt_message_user_set(Tt_message m, int key, void *v)

送信側アプリケーションの内部メッセージを設定する。この内部メッセージは、受信側アプリケーションが参照できない隠されたデータである 

tt_message_abstainer(Tt_message m, int n)

指定したメッセージの n 番目の忌避者の procid を返す 

tt_message_abstainers_count(Tt_message m)

オファを忌避した、TT_OFFER m に記録されている procid の数を返す

tt_message_accepter(Tt_message m,int n)

特定のメッセージを受信した n 番目の procid を返す 

tt_message_accepters_count(Tt_message m)

オファを受信した、TT_OFFER m に記録されている procid の数を返す

tt_message_rejecter(Tt_message m,int n)

指定したメッセージの n 番目の拒絶者の procid を返す 

tt_message_rejecters_count(Tt_message m)

 

オファを拒絶した、TT_OFFER m に記録されている procid の数を返す


注 -

メッセージの完成用に使用するすべての関数が返す型は Tt_status です。


汎用関数を使った ToolTalk メッセージの作成

汎用関数 tt_message_create ( ) を使用して、ToolTalk メッセージを作成し完成できます。tt_message_create ( ) を使用してプロセス指向またはオブジェクト指向のメッセージを作成する場合は、tt_message_attribute_set ( ) 呼び出しを使用して属性を設定します。

クラス

アドレス


注 -

オファは、TT_PROCEDURE アドレスでのみ送信可能です。それ以外のアドレスで送信しようとすると、TT_ERR_ADDRESS エラーとなります。


配信範囲

メッセージ配信の配信範囲を書き込みます。受信可能側は、次の値に結合できます。

ToolTalk サービスは、配信範囲に応じてデフォルトのセッションまたはファイル、あるいはその両方をメッセージに追加します。

オファは、TT_SESSION の配信範囲でのみ送信可能です。

操作

作成中の通知または要求について記述した操作を書き込みます。操作名を判定するには、ターゲットとなる受信側の ptype 定義またはメッセージプロトコル定義を参照します。

引数

操作に固有の引数を書き込みます。引数のデータ型に最も適した関数を使用します。

追加する引数ごとに、次の値を指定します (値の型には関係ありません)。


注 -

特に送信側と受信側で特定の vtype 名を定義し、受信側が他の形式で格納された値を検索できないようにしなければなりません。たとえば、整数として格納した値が、文字列として検索されないようにしなければなりません。


プロセス指向メッセージの作成

プロセス指向の通知と要求は、簡単に作成できます。手続き型の通知または要求について、新しいメッセージオブジェクトのハンドルまたは隠されたポインタを取得するには、tt_pnotice_create 関数または tt_prequest_create 関数を使用します。このハンドルは、以降の呼び出しでメッセージを参照するために使用できます。

tt_pnotice_create または tt_prequest_create を使用してメッセージを作成する場合は、引数として次の 2 つの属性を指定しなければなりません。

操作引数などの他のメッセージ属性を完成するには、tt_message_attribute_set ( ) 呼び出しを使用します。

オブジェクト指向メッセージの作成および完成

オブジェクト指向の通知と要求は、簡単に作成できます。オブジェクト指向の通知または要求について、新しいメッセージオブジェクトのハンドルまたは隠されたポインタを取得するには、tt_onotice_create 関数または tt_orequest_create 関数を使用します。このハンドルは、以降の呼び出しでメッセージを参照するために使用できます。

tt_onotice_create または tt_orequest_create を使用してメッセージを作成する場合は、引数として次の 2 つの属性を指定しなければなりません。

操作引数などの他のメッセージ属性を完成するには、tt_message_attribute_set ( ) 呼び出しを使用します。

メッセージコールバックの追加

ある要求がメッセージコールバックルーチンを含んでいる場合、コールバックルーチンは、応答が受信されると自動的に呼び出され、応答結果を調査して適切な処置を行います。


注 -

コールバックは、登録した順序と逆の順序で呼び出されます (つまり、最後に追加したコールバックが最初に呼び出されます)。


コールバックルーチンを要求に追加するには、tt_message_callback_add を使用します。応答が返され、コールバックルーチンが応答メッセージを処理し終わった場合、コールバックルーチンが TT_CALLBACK_PROCESSED を返す前に、その応答メッセージを破棄しなければなりません。応答メッセージを破棄するには、例 8-4 で示すように tt_message_destroy を使用します。


例 8-4 メッセージの破棄

Tt_callback_action
sample_msg_callback(Tt_message m, Tt_pattern p)
{
	... process the reply msg ...

	tt_message_destroy(m);
	return TT_CALLBACK_PROCESSED;
}


次のコード例は、cntl_msg_callback というコールバックルーチンです。このルーチンは、応答の状態フィールドを調査し、状態が起動済み、処理済み、または失敗である場合に処理を実行します。

/*
 * Default callback for all the ToolTalk messages we send.
 */

Tt_callback_action
cntl_msg_callback(m, p)
     Tt_message m;
     Tt_pattern p;
{
	int		mark;
	char		msg[255];
	char		*errstr;


	mark = tt_mark();
	switch (tt_message_state(m)) {
	      case TT_STARTED:
		    xv_set(cntl_ui_base_window, FRAME_LEFT_FOOTER,
		       "Starting editor...", NULL);
		    break;
	      case TT_HANDLED:
		    xv_set(cntl_ui_base_window, FRAME_LEFT_FOOTER, "", NULL);
		    break;
	      case TT_FAILED:
		    errstr = tt_message_status_string(m);
		    if (tt_pointer_error(errstr) == TT_OK && errstr) {
			sprintf(msg,"%s failed: %s", tt_message_op(m), errstr);
		    } else if (tt_message_status(m) == TT_ERR_NO_MATCH) {
			sprintf(msg,"%s failed: Couldn't contact editor",
				tt_message_op(m),
				tt_status_message(tt_message_status(m)));
		    } else {
			sprintf(msg,"%s failed: %s",
				tt_message_op(m),
				tt_status_message(tt_message_status(m)));
		    }
		    xv_set(cntl_ui_base_window, FRAME_LEFT_FOOTER, msg, NULL);
		    break;
	      default:
		    break;
	}
	/*
	 * no further action required for this message. Destroy it
	 * and return TT_CALLBACK_PROCESSED so no other callbacks will
	 * be run for the message.
	 */
	tt_message_destroy(m);
	tt_release(mark);
	return TT_CALLBACK_PROCESSED;
}

ptype のシグニチャの opnum に接続すると、静的パターンにコールバックを追加することもできます。opnum を持つ静的パターンと一致したためにメッセージが配信されると、ToolTalk サービスはその opnum に付加されているコールバックをすべて調べて起動します。

メッセージの送信

メッセージが完成したら、tt_message_send を使用して送信します。

ToolTalk サービスが TT_WRN_STALE_OBJID を返した場合は、ToolTalk データベースで転送ポインタを検索したことを意味します。そのポインタは、メッセージに指定されたオブジェクトが移動したことを示します。ただし、ToolTalk サービスは、新しい objid を使用してメッセージを送信します。その後、tt_message_object を使用してメッセージから新しい objid を検索し、内部のデータ構造体に入れることができます。

将来必要としないメッセージ (たとえば通知など) がある場合は、tt_message_destroy を使用して、メッセージを削除して記憶領域を解放できます。


注 -

メッセージに対する応答がありそうな場合は、応答を処理する前にメッセージを破棄しないでください。


例 8-5 は、pnotice の作成方法と送信方法を示しています。


例 8-5 pnotice の作成と送信

	/*
	* Create and send a ToolTalk notice message
	* ttsample1_value(in int <new value)
	*/

	msg_out = tt_pnotice_create(TT_SESSION, "ttsample1_value");
	tt_message_arg_add(msg_out, TT_IN, "integer", NULL);
	tt_message_arg_ival_set(msg_out, 0, (int)xv_get(slider, 
	    PANEL_VALUE));
	tt_message_send(msg_out);

	/*
	* Since this message is a notice, we don't expect a reply, so
	* there's no reason to keep a handle for the message.
	*/

	tt_message_destroy(msg_out);


例 8-6 は、cntl_ui_hilite_button のコールバックルーチンを呼び出す場合の orequest の作成と送信方法を示しています。


例 8-6 orequest の作成と送信

/*
 * Notify callback function for `cntl_ui_hilite_button'.
 */
void
cntl_ui_hilite_button_handler(item, event)
	Panel_item		item;
	Event		*event;
{
	Tt_message		msg;
	
	if (cntl_objid == (char *)0) {
		xv_set(cntl_ui_base_window, FRAME_LEFT_FOOTER,
		 "No object id selected", NULL);
		return;
	}
	msg = tt_orequest_create(cntl_objid, "hilite_obj");
	tt_message_arg_add(msg, TT_IN, "string", cntl_objid);
	tt_message_callback_add(msg, cntl_msg_callback);
	tt_message_send(msg);
}