@node utils, viewlib, thread, Top
@comment  node-name,  next,  previous,  up
@chapter utils

@menu
* get_mem_size.c::              
* http_system.c::               
* msequence.c::                 
* stabilizer.c::                
@end menu

@node get_mem_size.c, http_system.c, utils, utils
@comment  node-name,  next,  previous,  up
@section ./utils/get_mem_size.c


@defun get_mem_size
@cartouche
@example
unsigned int
get_mem_size( )
@end example
@end cartouche

@heading 説明
このシステムコールを発行したアプリケーションで利用可能なメモリの総量を返します。使われているメモリも、使われていないメモリも含めての値です。

@heading リターンデータ
システムコールを発行したアプリケーションで利用可能なメモリの総量を返す。

@heading 詳細
UNIX ではこれに相当するシステムコールが見当たらないので、つんであるメモリ量と、setlimit で設定されているヒープメモリ量を比較し、どちらか小さいほうを返すようにしました。
Windows/Mac ではそれぞれに相当する関数を使って実装してください。

@end defun


@node http_system.c, msequence.c, get_mem_size.c, utils
@comment  node-name,  next,  previous,  up
@section ./http_system.c


@defun http_system
@cartouche
@example
void
http_system(
    char * @var{host_name},
    int @var{port},
    char * @var{change_page}
)
@end example
@end cartouche

@heading 説明
@example
@var{host_name} :
@var{port} :
@var{change_page} :
@end example

@heading 履歴

@table @samp 
@item 02/4/12
UNIX において、現在起動しているnetscape へページを表示する方法がわかりましたので、その処理を加えました。今までのようにnetscape がたくさん立ち上がって困る問題がなくなりました。Windows/Mac ではたぶん今までの実装のままで対応できると思います。
この変更に伴い、get.c などで、ブラウザーの種類で分岐するコードはなくなりました。
@item 02/11/19
http_system にはブラウザを示す引数がありましたが、それは取りました。理由はどのブラウザが立ち上がるかはシステムが知っているからです。
http_client はcosmos がWWWブラウザを立ち上げるときにどのブラウザを使うかを指定する変数です。しかし、どのブラウザが立ち上がるかはシステムが知っているため、取り除きました。これに伴い、http_systemの最初の変数を削除し、

@example
http_system(host name,port,change page);
@end example

というように変更しました。
@end table
@end defun

@node msequence.c, stabilizer.c, http_system.c, utils
@comment  node-name,  next,  previous,  up
@section ./msequence.c


@defun init_msequence
@cartouche
@example
void
init_msequence();
@end example
@end cartouche

@heading 説明
ルーチンの初期化

@end defun


@defun ms_do
@cartouche
@example
int
ms_do(int (*func)(), void * @var{arg}, char @var{str[]})
@end example
@end cartouche

@heading 説明
func、arg をキューにつなぎ、この関数の実行が終わるのをまつ。終わったら、func の戻り値を返す。

@heading リターンデータ

@heading 詳細
たとえば、

@example
V_DIKSPLAY*
v_func(int @var{a} int @var{b})
@{
    V_DISPLAY * @var{c};
    ..... 実行.....
    return c
@}
@end example

というようなX 処理関数みたいなのがあって、これをmsequence 対応にするためには、

@example
typedef struct arg @{
    int @var{a};
    int @var{b};
    V_DISPLAY * @var{c};
@}:
    /*　BODY */
int
_v_func(struct arg * ag)
@{
    ..... 実行.....
    ag->c = c;
    return 0;
@}
    /* GRUE */
V_DISPLAY *
v_func(int @var{a},int @var{b})
@{
    struct arg ag;
    ag.a = a;
    ag.b = b;
    ms_do(_v_func,&ag,"v_func");
    return ag.c;
@}
@end example

というように書き直します。
これだと、v_loop の実行が問題となりますが、v_loop の中身のfor 文によるループをGRUE のなかで行い、イベントをとってくる部分のみをmsequence にまかせる。

@end defun


@defun ms_loop
@cartouche
@example
void
ms_loop();
@end example
@end cartouche

@heading 説明
ルーチンの初期化

@heading 詳細
main 関数のあるスレッドの最後の部分でms_loop を呼ぶ。この中で、ms do によって発行される関数を順番にキューからはずし、以下の形で実行する。

@example
(*func)(arg);
@end example

この実行が終わると待っているms_do をwakeup する。
@end defun



@node stabilizer.c,  , msequence.c, utils
@comment  node-name,  next,  previous,  up
@section ./stabilizer.c


@defun exit_stabilizer
@cartouche
@example
void
exit_stabilizer(char ch)
@end example
@end cartouche

@heading 説明

@example
@var{ch} :
@end example


@heading リターンデータ

@heading 詳細
stabilizer 参照

@end defun



@defun stabilizer
@cartouche
@example
int
stabilizer()
@end example
@end cartouche

@heading 詳細
これはクライアント側には関係ない関数ですが、一応記しておきます。この関数は、サーバーが落ちたときに、落ちたのを認識して再起動させる関数です。main の最初で、stabilizer() を呼んでおくと、親プロセスはまったく同じ子プロセスを生成しておいて寝てしまいます。親プロセスと子プロセスの間には、一つのパイプを結んでおき(へその緒) それらが切られると親プロセスは新しい子プロセスを生成します。
このとき子プロセスから、明示的にexit_stablizer(’e’) を呼び出すと、親プロセスも終了してしまいます。
渡した引数は’e’ 以外は新しい子プロセスに渡されます。

@end defun
