ORBの実行
Simple Wiki Based Contents Management System
ソフトウェア関連 >> ライブラリ >> RtORBについて >> RtORBの動作について >> ORBの実行

ORBの実行

 CORBA_ORB_run関数を実行して、CORBAのイベントループを起動させる。

【CORBA_ORB_run関数】

この関数では、POA_main_loop( The_RootPOA ); を呼んでいるのみである。

【POA_main_loop関数】

この関数では、server_loop(10000.0, PortableServer_execute_request, rootPOA); を呼んでいるのみである。

【server_loop関数】

この関数は、RtORBのもっとも低レベルの通信レイアである。この関数の処理の流れは、下記の通り。
  1. init_socket_servers(); GIOPで使用するfd_set 構造体を初期化する。
  2. selectシステムコールで使用するtime_out構造体に引数で与えられたmsecの時間をセット
  3. 以下の処理をループする
    1. select_socket_servers(time_out); time_outの時間、またはGIOPリクエストの到達まで待ち、リクエストに対する処理を実行。
    2. (*idle)(arg); 第2引数の関数ポインタがNULLでなければ、第2引数の関数を第3引数のポインタを引数にして関数を実行。すなわち、PortableServer_execute_request(The_RootPOA) が実行される。

【init_socket_servers関数】

この関数は、GIOPで使用するfd_set構造体を初期化する。この関数の処理の流れは、下記の通り。
  1. get_Servers_from_SockProfile(sockServers, &nSock, 0); sockport_profileのtypeがSOCK_SERVERまたはSOCK_SERVICEのものを抽出
  2. FD_ZERO(&main_socket_bits); selectシステムコールで使用するfd_set構造体を初期化
  3. sockport_profileのtypeがSOCK_SERVERのものをfd_set構造体にセット

【get_Servers_from_SockProfile関数】(要 修正)

この関数は、sockport_profileのtypeがSOCK_SERVERまたはSOCK_SERVICEのものを抽出する。
SockProfileは、予め大域変数として定義されたsockport_profile構造体である。また、FD_SETSIZEは、OSごとに定義されている最大のfd_setの数である。

【select_socket_servers関数】

この関数は、select_socket_ports関数を呼び出しているのみである。
select_socket_ports( &main_socket_bits, time_out);

【select_socket_ports関数】

この関数は、selectシステムコールで、外部からのGIOPリクエストを待ち、接続要求の場合には、GIOP用のsocketを生成し、そうでなければ、予めSockProfileに設定されているcommand_procを実行する。command_procがNULLまたは、実行時にエラーが発生すれば、その接続を閉じる。この関数の処理の流れは、下記のとおり。
  1. selectシステムコールで使うfd_set socksをFD_ZERO関数で初期化
  2. 引数で与えられたselectシステムコールで入力待ちになるfd_set sockbitsを、先ほど初期化したsocksにコピーする。
  3. 引数で与えられたtime_out構造体をコピー
  4. selectシステムコールで、GIOPイベントの到着を待つ。
  5. selectシステムコールで、イベントが来たsocket記述子すべてに対して以下の処理を行う。
  6. active_portに0をセットし、イベントが来たsocket記述子を取得。
  7. SockProfile配列から、active_portに対応するcommand_procの関数ポインタを取得しておく。これは、RtORBでは、SOCK_SERVERでは、POAの活性化時に、PortableServer_enqueue_request関数がセットされているはずである。SockProfile配列から、active_portに対応するtypeを取得し、それに応じて、次の処理を行う。
  8. typeがSOCK_SERVERの時:
    1. これは、新規の接続要求である。そのためaccept_connection関数でGIOP通信用のsocketを生成する。この時active_portに対応するconnection_procがセットされていれば、active_portとargを引数として関数を実行。acceptが成功すれば、新規に生成されたsocket記述子に対応するSockProfileに対して、copy_sockport_profile関数でコールバック関数等をコピーし、typeをSOCK_SERVICEにする。さらに、そのsocket記述子をFD_SET関数でsockbitsにセットする。
    2. FD_CLRで、socksからactive_portを除去し、イベント待ちのsocket記述子の数を1つ減じる。
  9. typeがSOCK_CLIENTまたは、SOCK_SERVICEの時:
    1. active_portに対応するcommand_procの関数をGIOP_ConnectionHandler h={CONNECTION_TYPE_SOCKET,active_port} を引数として実行する。この時、処理が失敗すれば、コネクションが切れているので、active_portに対応するdisconnect_procがセットされていれば、それを実行し、active_portをクローズし、sockbitsからactive_portをクリアするとともに、typeをSOCK_CLOSEDにする。
    2. FD_CLRで、socksからactive_portを除去し、イベント待ちのsocket記述子の数を1つ減じる。
  10. それ以外の時:
    1. エラーメッセージを表示し、イベント待ちのsocket記述子の数を1つ減じる。

【PortableServer_execute_request関数】

この関数は、GIOPメセージを処理する。CORBAのリモートメソッドコールのメインの関数である。引数であたえられたポインタは、POAであるはず。また、GIOPのリクエストは、一時的に、poa->requests にストックされ、そのリクエストキューに対して
 GIOP_execute_request(poa, poa->requests);
を実行する。

【GIOP_execute_request関数】

この関数は、GIOPメセージをすべて処理する。この処理が、CORBAのメインの処理となる。この関数の処理の流れは、下記のとおり。
  1. 引数であたえられたPtrList *lstの各要素に対して以下の処理をする。
    1. request = (GIOP_Request_Item)current_request->item; 要素の中身を取る。
    2. header = (GIOP_MessageHeader *)request->buf; 要素の中のGIOPメッセージをGIOPヘッダーheadにキャスト
    3. buf = request->buf; 要素の中のGIOPメッセージをbufにセット
    4. h = request->connh; コネクションハンドラをセット
    5. version = header->minor; GIOPバージョンをセット
    6. header->flags & 0x01 をチェックしてbyte_orderをセットし、必要であれば、メッセージサイズを変換。
    7. header->message_typeに応じて下記の処理をする
      1. header->message_typeがGIOP_Requestの時:
        1. スレッドをサポートしている場合には、該当リクエストのコピーを作って RunThread(&thr, GIOP_Request_perform_thread, (void *)arg, 1); で新規スレッドに処理を渡す。
        2. スレッドをサポートしていない場合には、GIOP_Request_perform(h, (octet *)buf, poa, header, body, &env);を実行
      2. header->message_typeがGIOP_Replyの時:GIOP_Reply_perform(h, (octet *)buf, poa, header, body, &env);を実行
      3. header->message_typeがGIOP_CancelRequestの時:GIOP_CancelRequest_perform(h, (octet *)buf, poa, header, body, &env);を実行
      4. header->message_typeがGIOP_LocateRequestの時:GIOP_LocationRequest_perform(h, (octet *)buf, poa, header, body, &env);を実行
      5. header->message_typeがGIOP_LocateReplyの時:GIOP_LocationRequest_perform(h, (octet *)buf, poa, header, body, &env);を実行
      6. header->message_typeがGIOP_CloseConnectionの時:何もしない
      7. header->message_typeがGIOP_MessageErrorの時: "Message Error occured\n"のメッセージを表示
      8. header->message_typeがGIOP_Fragmentの時:"FragmentMessage have not implemented.....\n"のメッセージを表示
      9. その他: "Invalid message type ([header->message_type])\n"メッセージを表示
    8. current_request->released = 1; 処理が終わったのでreleaseに1をセット
    9. current_request = current_request->next; 次の要素に移動。
  2. すべてのリクエストに対する処理が終了したら、PtrList_remove_released_items関数で、処理が終わったリクエストを削除。