ホーム 主筆 その他ソフト その他情報 Syuhitu.org English

Windows関連

スクリーンセーバー作成法

半透明ウインドウの性能

bootfont.bin

キャビネット形式

ウインドウスタイルをいじる

Java製ソフトをServiceに登録する

イベントログにメッセージを出力する

コントロールパネルにアイコンを追加する

スクリプトによる拡張1

スクリプトによる拡張2

ガジェットの作成

大容量メモリ

メモリ搭載量の下限に挑む

スパースファイルにする

表示されるアイコンの種類を調べてみた

メモリマップIOとエラー処理

ファイルを作る順番と速度の関係

Cryptography API: Next Generationを使う

Windows 10のアクセントカラー

iSCSIディスクにバックアップを取る

サーバプロセスを分離して実装する

サーバプロセスを分離して実装する - F#

レジストリに大量に書き込む

Solaris関連

OpenGL

Solaris設定

ディレクトリの読み込み

主筆プラグイン開発

マルチスレッドでの開発

door

音を出す

Blade100の正しい虐め方

パッケージの作成

画像入出力

BMPファイル

ICOファイル

ANIファイル

JPEGファイル

減色アルゴリズム

減色アルゴリズムの並列化

その他アルゴリズムなど

自由軸回転

Base64

文字列操作

CPU利用率の取得

正規表現ライブラリ

メタボールを作る

メタボールを作る2

正規表現とNFA・DFA

C言語の構文解析

液晶ディスプレイを解体してみた

iSCSIの理論と実装

単一フォルダにファイルを沢山作る

USB-HUBのカスケード接続

SafeIntの性能

VHDファイルのフォーマット

USBメモリに書き込み続けてみた

door_call

2006年2月11日公開

関数プロトタイプ

int door_call(
    int d,
    door_arg_t *params
);

typedef struct {
    char        *data_ptr;  /* 引数と戻り値のバッファ */
    size_t       data_size; /* data_ptrのバッファ長 */
    door_desc_t *desc_ptr;  /* 引数のディスクリプタ */
    uint_t       desc_num;  /* desc_ptrの数 */
    char        *rbuf;      /* 戻り値用のバッファ */
    size_t      rsize;      /* rbufのバッファ長 */
} door_arg_t;

typedef struct {
    door_attr_t d_attributes;   /* 属性 */
    union {
        struct {
            int d_descriptor;  /* ディスクリプタ */
            door_id_t d_id;    /* 一意なdoorID */
        } d_desc;
    } d_data;
} door_desc_t;

必要なヘッダ

<door.h>

必要なライブラリ

-ldoor

解説

door_call関数は、doorディスクリプタdが示すサーバ関数を呼び出す。また、その関数はparamsに指定された引数が与えられる。なお、paransにNULLが指定された場合には、引数も戻り値も存在しないものと見なす。

引数はdoor_arg_t構造体の、data_ptrとdesc_ptrに指定されたバッファのデータが使用される。data_sizeにはdata_ptrのバッファ長(バイト数)を指定すること。desc_numにはdesc_ptrのバッファにあるディスクリプタの個数を指定すること。

door_arg_t構造体の全てのメンバは、door_callから制御が返ってきた時には、更新されている可能性がある。また、rbufにはdoor呼び出しの戻り値が書き込まれる。

door_arg_t構造体のdata_ptrとdesc_ptrには、rbufに書き込まれた戻り値の位置が記録される(door_callから制御が返ってきた時には、data_ptrには「rbuf内のどこに"バイト列"の戻り値が記録されているか」が書き込まれ、desc_ptrには「rbuf内のどこに"ディスクリプタ"の戻り値が記録されているか」が書き込まれる)。data_sizeとdesc_numには、戻り値のデータ長とディスクリプタの個数が書き込まれる。

door_call関数は、引数の入力と出力とで同じバッファを使用することができる。そのため、data_ptrとdesc_ptrに、rbufのバッファをポイントさせていても問題ない。

もし、doorの戻り値のサイズがrsizeに指定された値より大きくなった場合は、システムは呼び出し元のメモリ領域内に、自動的に新しいバッファを割り当て、rbufとrsizeの値を更新する。なおその場合、バッファが不要になったら、呼び出し元でmunmap(rbuf, rsize)を呼び出して、メモリ領域を開放する必要がある。

クライアントは、ディスクリプタをdoor_desc構造体に設定することで、サーバ側にディスクリプタを渡すことができる。そのときクライアントは、d_attributesにディスクリプタの属性を設定する必要がある。属性は複数個を組み合わせて指定することできる。なお現在は、DOOR_DESCRIPTOR属性を持つディスクリプタだけをサポートしている。また、DOOR_RELEASEを指定することで、ディスクリプタがサーバに渡された時に、クライアント側のディスクリプタが自動的に閉じられるようにすることも出来る。なお、door_call関数に渡したディスクリプタは、door_call関数がEFAULTとEBADF以外の理由で失敗した場合には、自動的に閉じられる。

door_desc_t構造体は次のように定義される。

typedef struct {
    door_attr_t d_attributes;   /* 属性 */
    union {
        struct {
            int d_descriptor;  /* ディスクリプタ */
            door_id_t d_id;    /* 一意なdoorID */
        } d_desc;
    } d_data;
} door_desc_t;

ディスクリプタが渡された、或いは返された時には、新規のディスクリプタがターゲットのアドレス空間で構築され、ターゲットのd_descriptorメンバは新しいディスクリプタの値に更新される。更に、システムは各doorごとシステム全体での一意な値を生成して、d_idメンバにその値を書き込み、d_attributesメンバに次に様な属性を設定する。

DOOR_LOCAL 受け取ったdoorはdoor_createによってこのプロセスで生成された物である。
DOOR_PRIVATE 受け取ったdoorは、サーバスレッドのプライベートプールを持っている。
DOOR_UNREF 受け取ったdoorは参照されなくなった時に通知されることを期待している。
DOOR_UNREF_MULTI DOOR_UNREFに似ている。この場合は、同じdoorに対して、参照されなくなった時の通知が複数回あることを期待している。
DOOR_REFUSE_DESC このdoorはディスクリプタの引数を受け付けない。
DOOR_REVOKED 受け取ったdoorはサーバによって無効化されている。

door_call関数はrestartableなシステムコールではない。door_call関数を処理しているスレッドでシグナルを受信した時には、関数は失敗し、errnoにEINTRを設定する。door処理はidempotentでないため、door_call処理中に生成される可能性のある全てのシグナルをマスクするべきである。door_callの処理中にクライアントがアボートした場合、サーバスレッドはPOSIXスレッドのcancellationメカニズムによって通知される。

door_createから返されたディスクリプタには、close-on-exec(FD_CLOEXEC) フラグが付けられている。

doorに関する情報は、door_info関数によって全てのクライアントから参照することが出来る。そのため、セキュリティ性が求められるアプリケーションでは、door_info関数によってアクセス可能なdoor情報に、セキュアな情報を記録してはいけない。特に、cookieにはセキュアな情報を記録してはいけない。

戻り値

成功した場合は0。

失敗した場合は-1が返され、errnoに値が設定される。

エラー値

E2BIG

引数が大きすぎる。

サーバスレッドのスタックが足りない。

EAGAIN

サーバはリソースが使用可能な状態ではない。

EBADF

不正なdoorディスクリプタが指定された。

EFAULT

引数のポインタが、アロケートされたメモリ領域の範囲外をポイントしている。

EINTR

クライアントでシグナルが発生した、クライアントでforkが呼び出された、サーバが処理を終了している。

EINVAL

不正な引数が渡された。

EMFILE

クライアントもしくはサーバで、ディスクリプタを開きすぎている。

ENOTSUP

doorにDOOR_REFUSE_DESCフラグが設定されており、desc_numの引数が0でない。

EOVERFLOW

呼び出し側で、戻り値のオーバーフロー領域の確保に失敗した。

このページの情報に間違いがあっても、俺は知らんぜ。

<< 「Solarisのdoorについて」に戻る


連絡先 - サイトマップ - 更新履歴
Copyright (C)  2000 - 2016 nabiki_t All Rights Reserved.