Hitachi

OpenTP1 Version 7 分散トランザクション処理機能 OpenTP1 プログラム作成リファレンス C言語編


tpreturn

〈このページの構成〉

名称

サービス関数からのリターン

形式

ANSI C,C++の形式

#include <xatmi.h>
void  tpreturn(int rval,long rcode,char *data,long  len,
               long flags)

K&R版 Cの形式

#include <xatmi.h>
void  tpreturn(rval,rcode,data,len,flags)
int     rval;
long    rcode;
char    *data;
long    len;
long    flags;

機能

関数tpreturn()は,サービス関数が完了したことを示します。tpreturn()は,C言語のreturn()に該当します(つまり,tpreturn()が呼び出されると,サービス関数は,コミュニケーションリソースマネジャにリターンします)。コミュニケーションリソースマネジャへ正しく制御が戻ることを保証するために,tpreturn()は,コミュニケーションリソースマネジャで割り当てられたサービス関数内から呼び出すことをお勧めします。

関数tpreturn()は,サービスの応答メッセージを送信するために使用します。tpreturn()が成功すると,tpcall(),tpgetrply(),tprecv()で受信待ちしているプログラムの受信バッファに応答が返ります。

会話型サービスでは,tpreturn()はコネクションも終了させます。つまり,サービス関数は,tpdiscon()を直接呼べません。正しい結果を保証するために,会話型サービスと通信しているプログラムは,tpdiscon()を呼ばないでください。むしろ,会話型サービスが完了する通知を待ってください(つまり,tpreturn()から送信されたTPEV_SVCSUCCかTPEV_SVCFAILのようなイベントを待つ必要があります)。

サービス関数がトランザクションモードの場合は,tpreturn()は,トランザクションが完了したときに,そのサービスをコミットするかロールバックするかを決定します。サービスは,同じトランザクションの一部として複数回呼び出されるので,トランザクションの生成者からtx_commit(),tx_rollback()が呼ばれるまで,必ずしも完全にコミット,またはロールバックされるとはかぎりません。

関数tpreturn()は,サービス関数から起動されたサービス要求のすべての応答を受信したあとで呼んでください。さもなければ,サービスの性質に従いますが,TPESVCERRやイベントであるTPEV_SVCERRが,サービス関数との会話を開始したプログラムにリターンされます。受信されていない未解決の応答は,コミュニケーションリソースマネジャで自動的に捨てられます。これらの応答のための記述子は,無効な記述子になります。

関数tpreturn()は,サービスで開始されたすべてのコネクションがクローズされてから呼んでください。さもないと,サービスの性質に従って,TPESVCERRやイベントであるTPEV_SVCERRが,サービス関数との会話を開始したプログラムにリターンされます。さらに,緊急のコネクション切断イベント(TPEV_DISCONIMM)が,すべてのサブオーディネータへのオープンコネクションに送信されます。

コネクション制御に関して,tpreturn()を呼び出したサービス関数が,このサービス関数を呼び出したコネクションの制御権を持たない場合は,二つの結果が起こることが考えられます。一つ目は,もしサービス関数が,rvalにTPFAIL,dataにNULLを設定したtpreturn()を呼ぶと,TPEV_SVCFAILイベントが会話のオリジネータへ送信されます。二つ目は,ほかの値を設定したtpreturn()を呼ぶと,TPEV_SVCERRイベントがオリジネータへ送信されます。

会話型サービスは,開始していないオープンコネクションを一つだけしか持っていないので,コミュニケーションリソースマネジャは,送信された記述子のデータ(または,イベント)を認識しています。これらの理由で記述子はtpreturn()に渡されます。

引数

『●rval

TPSUCCESS,TPFAILのどちらか一つを設定します。』

『●rcode

アプリケーションで定義するリターンコードを設定します。』

『●data

送信する応答データのバッファを指すポインタを設定します。』

『●len

送信されてきたデータのバッファの長さを設定します。』

『●flags

0を設定します(将来の予約)。』

rvalには,次のうちどれか一つの値が設定されます。

TPSUCCESS

サービスが成功して終了しました。データがある場合は,それも送信されます(リターン処理中で失敗がなければ)。呼び出し側がトランザクションモードである場合は,tpreturn()は,そのサービスが最終的にコミットされる場所に置きます。

Note:tpreturn()は,必ずしもトランザクション全体を決着する訳ではありません。また,呼び出し側が成功を示しているときでも,未解決の応答やオープンコネクションがあるときや,サービスの中でトランザクションがrollback_only状態となるような何らかの処理をしていた場合,エラーメッセージが送信されます(つまり,応答の受け取り側は,TPESVCERRか,イベントであるTPEV_SVCERRを受信します)。

Note:何らかの理由で,トランザクションがサービス関数内でrollback_only状態になる場合は,rvalにはTPFAILを設定してください。会話型サービスにTPSUCCESSが設定されていた場合は,イベントであるTPEV_SVCSUCCが通知されます。

TPFAIL

サービスがアプリケーションの立場から見て不成功に終了しました。エラーは応答を受信するプログラムに送信されます。つまり,応答を受信する呼び出しは失敗して,受け取り側はTPESVCFAILか,イベントであるTPEV_SVCFAILを受信します。呼び出し側がトランザクションモードである場合は,tpreturn()はトランザクションをrollback_only状態にします(トランザクションはすでにrollback_only状態になっているかもしれないことに注意)。リターンの処理中で失敗がなければ,呼び出し側のデータがある場合は,送信されます。呼び出し側のデータが送信されない理由の一つは,トランザクションタイムアウトが起こったときです。この場合,応答を待っているプログラムは,TPETIMEのエラーを受信します。

rvalにこれらのうちのどれか一つを設定していない場合は,デフォルトでTPFAILが仮定されます。

アプリケーションで定義するリターンコードのrcodeは,サービスの応答を受信するプログラムへ送信されます。このコードは,応答が正常に送信されているかぎり,rvalに設定した内容に関係なく送信されます(つまり,呼び出しの受信が成功か,TPESVCFAILをリターンするか,TPEV_SVCSUCCかTPEV_SVCFAILのイベントのうちの一つを受信しているかぎり)。会話型サービスでは,このコードは,tpreturn()の呼び出し時にサービス関数がコネクションの制御権を持っているときだけ送信されます。rcodeの値は変数tpurcodeとして,受け取り側で有効となります。

dataは,送信する応答のデータ部を指すポインタです。dataがNULLでない場合は,dataは事前に呼ばれたtpalloc()で得られたバッファを必ず指すようにしてください。このバッファが,呼び出し時にサービス関数に渡されたバッファと同じ場合は,この処理はコミュニケーションリソースマネジャに任せられて,サービス関数の作成者は,バッファが解放されているかどうかを意識する必要はありません。つまり,このバッファを解放しようとするユーザの試みは失敗します。しかし,tpreturn()に渡されたバッファが,サービスを呼び出したときと同じでないバッファの場合は,tpreturn()はこのバッファを解放できます。lenは,送信されるデータバッファの合計サイズを設定します。dataが長さを設定する必要がないバッファを指すポインタの場合は,lenは無視されます(0にしてください)。長さが必要なバッファ型をdataが指す場合は,lenには0を設定しないでください。

dataがNULLの場合は,lenは無視されます。この場合,応答がサービスを呼び出したプログラムから要求されている場合は,データ部がない応答が送信されます。応答が要求されていない場合は,tpreturn()は必要なときにデータを解放して,応答なしの送信をリターンします。

flagsは将来の使用のために予約されているので,0を設定しておきます。

サービスが会話型の場合,データ部が送信されない理由には,次の二つの場合があります。

  • 呼び出しが完了したときに,すでにコネクションが切断されている場合(つまり,呼び出し側がコネクションに関するTPEV_DISCONIMMを受信した),この呼び出し側は,単にサービスルーチンを終わらせて,トランザクションがある場合は,ロールバックします。この場合,呼び出し側のデータは送信されません。

  • 上記で説明したように,呼び出し側がコネクションを制御していない場合は,TPEV_SVCFAIL,またはTPEV_SVCERRが,オリジネータ(コネクションの確立元)に送信されます。オリジネータがどのイベントを受け取るかどうかに関係なく,データは送信されません。しかし,オリジネータがTPEV_SVCFAILを受信した場合は,オリジネータのリターンコードはtpurcodeで有効になります。

リターン値

サービス関数は,呼び出し側には値をリターンしないで,コミュニケーションリソースマネジャが割り当てます。そのため,void型の宣言となっています。ただし,サービス関数は,tpreturn()で終了することを期待されます。サービス関数がtpreturn()を使わないで終了した場合(つまり,C言語のreturn()を使うか,または関数が終わったら),サーバはサービス要求者にサービスエラーをリターンします。すべてのサブオーディネータへのオープンコネクションはすぐに切断されて,未解決の非同期応答は捨てられます。サーバがトランザクションモードで失敗した場合は,トランザクションはrollback_only状態になります。

tpreturn()がサービス関数の外で(例えば,サービスでないルーチンから)使われる場合は,何もしません。

エラー

tpreturn()は,サービス関数を終了させるので,引数をハンドリングしているときか,処理中のときに起こったエラーは,関数の呼び出し側に通知できません。このようなエラーは,tpcall()かtpgetrply()を経由してサービスの結果を受信するプログラムでは,TPESVCERRをtperrnoに設定する要因となります。tpsend()やtprecv()を使っているプログラムでは,イベントTPEV_SVCERRが通知されます。

関連項目

tpalloc(),tpcall(),tpconnect(),tpdiscon(),tpgetrply(),tprecv(),tpsend(),tpservice()

『OpenTP1で使う場合の注意事項』

  1. 『該当バージョンのtpreturn()は,サービス関数を終了させません。tpreturn()を呼び出したあとには,すぐにreturn()でサービス関数を終了してください。tpreturn()を呼び出したあとに何らかの処理をした場合は,動作は保証しません。』

  2. 『OSI TP通信をするXATMIのエラーは,従来のTCP/IPとエラー動作が異なる場合があります。』