- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- ソース を表示
- PostgreSQL/開発/include/utils/timeout.h へ行く。
- 1 (2018-04-15 (日) 06:30:22)
- 2 (2018-04-15 (日) 06:59:07)
- 3 (2018-04-16 (月) 11:05:50)
- 4 (2018-04-17 (火) 08:33:42)
- 5 (2018-04-18 (水) 06:36:10)
概要 †
- SIGALRMによる割り込みを多重化するためのライブラリである。
- 長時間クエリのタイムアウトを監視するStatementCancelHandlerなどの、PostgreSQL本来の機能に加え、ユーザー独自のタイムアウトを設定することも可能である。
参考(utils/timeout.h) enum TimeoutId - https://git.postgresql.org/gitweb/?p=postgresql.git;a=shortlog;h=refs/heads/REL_10_STABLE
- 複数のタイマーの管理は、アクティブなタイムアウトの存在と、最も近いタイムアウト時間に合わせてタイマーを設定することで実現している。
- タイムアウト情報は、all_timeoutという配列で管理されている。登録可能なタイマー数には制限がある。PostgreSQL10.0のソースを確認すると16(0~15)となっており、8個(0~7)が予約済みであるため、実質8個(8~15)のタイマーを登録可能である。
- 有効化されたタイムアウト設定は、active_timeoutsという配列に登録される。この配列は、all_timeouts要素の参照を保持する配列である。この配列で管理されるタイムアウト設定は、最もタイムアウト時間が直近のものから昇順に整列されている。つまり、active_timeouts[0]の要素が、最も直近に発火すべきタイマーとなっている。よって、timeoutライブラリは、タイマーの設定においてactive_timeouts[0]のfin_timeを呼べばよく、タイマー設定処理がシンプルになっている。
- タイマーが発火すると、MyLatchのフラグがセットされるため、MyLatchで待ち状態となっている処理は復帰する。また、indicatorというフラグがタイムアウト情報にセットされる。このフラグを見て(
get_timeout_indicator
)、登録したタイマーが発火したか否かを判断できる。 - タイマーの発火で登録していたタイムアウト設定のハンドラーが呼ばれると、そのタイムアウト設定はactive_timeouts配列から削除される。従って、再びタイマースケジュールしたい場合は、enable_timeout_after関数などを呼びアクティブにする必要がある。
定義 †
変数,エイリアス †
マクロ †
列挙型 †
構造体/共用体 †
Struct †
番号 | データ型 | フィールド | 説明 |
---|
関数 †
関数名 †
// 引数1: extern ForeignServer *GetForeignServer(Oid serverid);
- 説明
サンプルプログラム †
/*------------------------------------------------------------------------- * * timeout_test.c * Timeout test code * * IDENTIFICATION * contrib/timeout_test/pg_retire.c * *------------------------------------------------------------------------- */ #include "postgres.h" #include "fmgr.h" #include "utils/timeout.h" PG_MODULE_MAGIC; static TimeoutId MyTimeoutId = USER_TIMEOUT; static void my_timeout_handler(void); static void my_timeout_handler(void) { ereport(DEBUG3, (errmsg("MyTimer fired!"))); } PG_FUNCTION_INFO_V1(my_register_timeout); Datum my_register_timeout(PG_FUNCTION_ARGS) { if (MyTimeoutId != USER_TIMEOUT) { ereport(WARNING, (errmsg("timeout is already set."))); PG_RETURN_INT32(-1); } MyTimeoutId = RegisterTimeout(USER_TIMEOUT, my_timeout_handler); PG_RETURN_INT32(MyTimeoutId); } PG_FUNCTION_INFO_V1(my_enable_timeout_after); Datum my_enable_timeout_after(PG_FUNCTION_ARGS) { int timeout_after = PG_GETARG_INT32(0); enable_timeout_after(MyTimeoutId, timeout_after); PG_RETURN_BOOL(true); } PG_FUNCTION_INFO_V1(my_enable_timeout_at); Datum my_enable_timeout_at(PG_FUNCTION_ARGS) { int timeout_at = PG_GETARG_INT32(0); enable_timeout_at(MyTimeoutId, timeout_at); PG_RETURN_BOOL(true); } PG_FUNCTION_INFO_V1(my_disable_timeout); Datum my_disable_timeout(PG_FUNCTION_ARGS) { disable_timeout(MyTimeoutId, true); PG_RETURN_BOOL(true); } PG_FUNCTION_INFO_V1(my_get_timeout_indicator); Datum my_get_timeout_indicator(PG_FUNCTION_ARGS) { bool indicator; indicator = get_timeout_indicator(MyTimeoutId, false); PG_RETURN_BOOL(indicator); } PG_FUNCTION_INFO_V1(my_get_timeout_start_time); Datum my_get_timeout_start_time(PG_FUNCTION_ARGS) { int64 start_time; start_time = get_timeout_start_time(MyTimeoutId); PG_RETURN_INT64(start_time); } PG_FUNCTION_INFO_V1(my_get_timeout_finish_time); Datum my_get_timeout_finish_time(PG_FUNCTION_ARGS) { int64 finish_time; finish_time = get_timeout_finish_time(MyTimeoutId); PG_RETURN_INT64(finish_time); }
参考・関連 †
- utils/misc/timeout.c - https://git.postgresql.org/gitweb/?p=postgresql.git;a=shortlog;h=refs/heads/REL_10_STABLE
関連