uv_handle_t — 基底ハンドル

uv_handle_tは、libuvのすべてのハンドル型の基底型です。

構造体は、libuvのどのハンドルも、uv_handle_tにキャストできるように配置されています。ここで定義するすべてのAPI関数は、どのハンドル型でも使えます。

libuvのハンドルは移動できません。関数に渡したハンドル構造体へのポインターは、要求した操作が続く間、有効でなければなりません。スタック上に確保したハンドルを使うときは注意してください。

データ型

type uv_handle_t

libuvの基底ハンドル型です。

enum uv_handle_type

libuvハンドルの種類です。

typedef enum {
  UV_UNKNOWN_HANDLE = 0,
  UV_ASYNC,
  UV_CHECK,
  UV_FS_EVENT,
  UV_FS_POLL,
  UV_HANDLE,
  UV_IDLE,
  UV_NAMED_PIPE,
  UV_POLL,
  UV_PREPARE,
  UV_PROCESS,
  UV_STREAM,
  UV_TCP,
  UV_TIMER,
  UV_TTY,
  UV_UDP,
  UV_SIGNAL,
  UV_FILE,
  UV_HANDLE_TYPE_MAX
} uv_handle_type;
type uv_any_handle

すべてのハンドル型の共用体です。

typedef void (*uv_alloc_cb)(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf)

次の関数、uv_read_start()と、uv_udp_recv_start()へ渡すコールバックの型定義です。ユーザーはメモリーを確保し、渡された、uv_buf_t構造体を埋める必要があります。バッファのbaseにNULLを代入したり、長さを0にしたりすると、UV_ENOBUFSエラーが、uv_udp_recv_cbまたは、uv_read_cbのコールバックで発生します。

各バッファは1回だけ使われ、ユーザーは、uv_udp_recv_cbまたは、uv_read_cbのコールバックで解放する責任があります。

推奨サイズ(現在、多くの場合は65536)が渡されますが、目安にすぎず、読み取り待ちのデータの量とは一切関係ありません。ユーザーは、自分で決めた量のメモリーを確保できます。

たとえば、フリーリスト、メモリープール、スラブ方式のアロケーターなど、独自の割り当て方式を使うアプリケーションでは、すでに持っているメモリーブロックに合う別のサイズを使えます。

例:

static void my_alloc_cb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
  buf->base = malloc(suggested_size);
  buf->len = suggested_size;
}
typedef void (*uv_close_cb)(uv_handle_t *handle)

次の関数、uv_close()へ渡すコールバックの型定義です。

公開メンバー

uv_loop_t *uv_handle_t.loop

ハンドルが動作する、uv_loop_tへのポインターです。読み取り専用です。

uv_handle_type uv_handle_t.type

基になるハンドルの型を示す、uv_handle_typeです。読み取り専用です。

void *uv_handle_t.data

ユーザーが定義する任意のデータのための領域です。libuvはこのフィールドを使いません。

API

UV_HANDLE_TYPE_MAP(iter_macro)

各ハンドル型について、iter_macroを呼び出す列に展開されるマクロです。iter_macroは、2つの引数で呼び出されます。1つ目は、uv_handle_typeの要素名から、UV_の接頭辞を除いた名前です。2つ目は、対応する構造体の型名から、uv_の接頭辞と、_tの接尾辞を除いた名前です。

int uv_is_active(const uv_handle_t *handle)

ハンドルがアクティブなら0以外、非アクティブなら0を返します。「アクティブ」の意味は、ハンドルの型によって異なります。

  • uv_async_tハンドルは常にアクティブです。uv_close()で閉じる場合を除き、非アクティブにできません。

  • uv_pipe_t、uv_tcp_t、uv_udp_tなど、基本的にI/Oを扱うハンドルは、読み取り、書き込み、接続、新しい接続の受け付けなど、I/Oに関係する処理を行っているときにアクティブです。

  • uv_check_t、uv_idle_t、uv_timer_tなどのハンドルは、uv_check_start()、uv_idle_start()などの呼び出しで開始したときにアクティブになります。

目安として、uv_foo_t型のハンドルに、uv_foo_start()関数がある場合は、その関数を呼び出した時点からアクティブです。同様に、uv_foo_stop()は、ハンドルを再び非アクティブにします。

int uv_is_closing(const uv_handle_t *handle)

ハンドルが閉じる処理中または閉じた状態なら0以外、それ以外なら0を返します。

注記

この関数は、ハンドルの初期化からcloseコールバックが呼び出されるまでの間だけ使ってください。

void uv_close(uv_handle_t *handle, uv_close_cb close_cb)

ハンドルを閉じるよう要求します。close_cbは、この呼び出しの後で非同期に呼び出されます。メモリーを解放する前に、各ハンドルに対して必ずこの関数を呼び出してください。さらに、メモリーを解放できるのは、close_cbの中、またはその関数が戻った後だけです。

ファイルディスクリプターを包むハンドルは即座に閉じられますが、close_cbは、次のイベントループの反復まで延期されます。そのコールバックで、ハンドルに関連するリソースを解放できます。

uv_connect_tやuv_write_tなどの進行中のリクエストはキャンセルされ、status=UV_ECANCELEDとして非同期にコールバックが呼び出されます。

close_cbは、後処理やメモリーの解放が不要な場合、NULLにできます。

void uv_ref(uv_handle_t *handle)

指定したハンドルを参照します。参照操作は冪等です。すでに参照されているハンドルでこの関数を再び呼び出しても、何も変わりません。

詳しくは、参照カウントを参照してください。

void uv_unref(uv_handle_t *handle)

指定したハンドルの参照を外します。参照操作は冪等です。参照されていないハンドルでこの関数を再び呼び出しても、何も変わりません。

詳しくは、参照カウントを参照してください。

int uv_has_ref(const uv_handle_t *handle)

ハンドルが参照されていれば0以外、それ以外なら0を返します。

詳しくは、参照カウントを参照してください。

size_t uv_handle_size(uv_handle_type type)

指定したハンドル型のサイズを返します。構造体の配置を知りたくないFFIバインディングの作成者に役立ちます。

その他のAPI関数

以下のAPI関数は、uv_handle_tを引数に取りますが、一部のハンドル型でだけ動作します。

int uv_send_buffer_size(uv_handle_t *handle, int *value)

OSがソケットに使う送信バッファのサイズを取得または設定します。

値が、*value == 0なら、*valueへ現在の送信バッファのサイズを設定します。値が、*value > 0なら、*valueを使って新しい送信バッファのサイズを設定します。

成功時は0、エラー時は負の値を返します。

この関数は、UnixではTCP・pipe・UDPのハンドル、WindowsではTCP・UDPのハンドルで動作します。

注記

Linuxでは、指定した値の2倍のサイズを設定し、元の指定値の2倍のサイズを返します。

int uv_recv_buffer_size(uv_handle_t *handle, int *value)

OSがソケットに使う受信バッファのサイズを取得または設定します。

値が、*value == 0なら、*valueへ現在の受信バッファのサイズを設定します。値が、*value > 0なら、*valueを使って新しい受信バッファのサイズを設定します。

成功時は0、エラー時は負の値を返します。

この関数は、UnixではTCP・pipe・UDPのハンドル、WindowsではTCP・UDPのハンドルで動作します。

注記

Linuxでは、指定した値の2倍のサイズを設定し、元の指定値の2倍のサイズを返します。

int uv_fileno(const uv_handle_t *handle, uv_os_fd_t *fd)

プラットフォームに依存する、対応するファイルディスクリプターを取得します。

TCP・pipe・TTY・UDP・pollのハンドルをサポートします。他のハンドル型を渡すと、UV_EINVALで失敗します。

ハンドルにまだファイルディスクリプターが関連付けられていない場合や、ハンドル自体が閉じられている場合は、UV_EBADFを返します。

警告

この関数を使うときは十分注意してください。libuvはファイルディスクリプターを自身が制御していると仮定するため、変更を加えると正常に動作しなくなる可能性があります。

uv_loop_t *uv_handle_get_loop(const uv_handle_t *handle)

戻り値は、handle->loopです。

バージョン1.19.0で追加。

void *uv_handle_get_data(const uv_handle_t *handle)

戻り値は、handle->dataです。

バージョン1.19.0で追加。

void uv_handle_set_data(uv_handle_t *handle, void *data)

次のフィールド、handle->dataを、dataに設定します。

バージョン1.19.0で追加。

uv_handle_type uv_handle_get_type(const uv_handle_t *handle)

戻り値は、handle->typeです。

バージョン1.19.0で追加。

const char *uv_handle_type_name(uv_handle_type type)

指定したハンドル型に対応する構造体の名前を返します。たとえば、「pipe」という、uv_pipe_tに対応する名前が、UV_NAMED_PIPEに対して返されます。

該当するハンドル型がなければ、NULLを返します。

バージョン1.19.0で追加。

参照カウント

libuvのイベントループを既定のモードで実行すると、アクティブで、かつ参照されているハンドルがなくなるまで実行します。ユーザーは、アクティブなハンドルの参照を外すことで、ループを早く終了させられます。たとえば、uv_unref()を、uv_timer_start()の呼び出し後に呼び出します。

ハンドルは、参照されている状態か、参照されていない状態のどちらかです。この参照管理ではカウンターを使わないため、どちらの操作も冪等です。

すべてのハンドルは、既定ではアクティブなときに参照されます。アクティブという状態の詳細は、uv_is_active()を参照してください。アクティブという状態の意味を詳しく説明しています。