入り口に戻る

原文はこちら。

翻訳にあたって、オープンソースグループ・ジャパンの MIT ライセンスの訳を参考にした。

# X Synchronization Extension Protocol(日本語訳)

## X Consortium Standard

### Tim Glauert

Olivetti Research
MultiWorks

### Dave Carver

Digital Equipment Corporation
MIT/Project Athena

### Jim Gettys

Digital Equipment Corporation
Cambridge Research Laboratory

### David P. Wiggins

X Consortium, Inc.

### James Jones

NVIDIA Corporation

X Version 11, Release 7.7

Version 3.1

Copyright © 1991 Olivetti Research Limited, Cambridge England, Digital Equipment Corporation, Maynard, Massachusetts, X Consortium

Copyright © 2010 NVIDIA Corporation

Permission to use, copy, modify, and distribute this documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies. Olivetti, Digital, MIT, the X Consortium, and NVIDIA make no representations about the suitability for any purpose of the information in this document. This documentation is provided as is without express or implied warranty.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Except as contained in this notice, the name of the X Consortium shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the X Consortium.

(訳)

(本文書を使用、複製、変更、および頒布することは、目的を問わず無償で許可する。但し、上記の著作権表示を文書のすべての複製に記載するものとする。Olivetti、Digital、MIT、X Consortium、及び NVIDIA は、本文書に含まれる情報のいかなる目的への適切性についても、何ら表明を行わない。本文書は明示または暗黙の保証なしに提供される。)

(本ソフトウェアおよび関連する文書のファイル（以下「ソフトウェア」）の複製を取得した全ての人物に対し、以下の条件に従うことを前提に、ソフトウェアを無制限に扱うことを無償で許可する。これには、ソフトウェアの複製を使用、複製、改変、結合、公開、頒布、再許諾、および/または販売する権利、およびソフトウェアを提供する人物に同様の行為を許可する権利が含まれるが、これらに限定されない。)

(上記の著作権表示および本許諾表示を、ソフトウェアの全ての複製または実質的な部分に記載するものとする。)

(ソフトウェアは「現状有姿」で提供され、明示的であるか黙示的であるかを問わず、いかなる種類の保証も行われない。ここでいう保証には、商品性、特定目的への適合性、および権利の非侵害性に関する保証も含まれるが、これらに限定されるものではない。THE X CONSORTIUM は、契約、不法行為、またはその他の行為であるかを問わず、ソフトウェアまたはソフトウェアの使用もしくはその他に取り扱いに起因または関連して生じるいかなる請求、損害賠償、その他の責任について、一切の責任を負わない。)

(X Consortium の名称は、この表示に記載されている場合を除き、X Consortium の事前の書面による承認を得ずに、宣伝であろうとその他の形であろうと、ソフトウェアの販売を促進するもの、またはソフトウェアの使用その他の扱いを奨励するものに使用してはならない。)

## 第１章　同期プロトコル

X プロトコル本体は、異なるクライアントのリクエスト群の実行順序について、何も保証しない。そのため、クライアント間の同期は、クライアントの次元で、オペレーティング・システムとネットワークとに依存した手法で実施されなければならない。たとえこのような同期の手法に標準となるものが確立されているとしても、ネットワークの使用は、クライアント群の同期と、その結果として生じるリクエストの X サーバへの配送との間に、予測できない遅延を持ち込んでしまう。

X プロトコル本体はまた、リクエストが実行された時刻についても、何ら保証しない。そのため、リアルタイムでなければならないという制約を持つクライアントは全て、ホスト・コンピュータ上に自前の時間調整機能を実装しなければならない。このような時間調整機能はどのようなものであっても、オペレーティング・システムとネットワークに内在する遅延によるエラーに弱いものであり、また、クライアントとサーバとを同期し続けるための往復リクエストが必要であることから、非効率なものでもある。

この同期拡張(synchronization extension)は、クライアント間の同期が完全に X サーバの中で行われることを可能にするための機能要素(primitives)を提供する。これによって、ネットワークに起因するいかなるエラーも除くことができ、オペレーティング・システムとホストの両方を異にするクライアント同士であっても同期を取ることが可能となる。これは、音声、映像、画像のデータ・ストリームを同期し続けるマルチメディアのアプリケーションにとって重要なことである。また、この拡張では X サーバの中に内部タイマー(timer)を用意しており、クライアントのリクエストはこの内部タイマーと同期を取ることができる。これによって、単純なアニメーション・アプリケーションは如何なる往復リクエストも用いずに実装することが可能となり、クライアント、ネットワーク、及びサーバにおけるバッファリングのやり方も最適化される。

## 詳説

X サーバの中で同期を取るためにこの拡張が用いる仕組みは、特定の同期条件(synchronization condition)が調うまでクライアントから来たリクエストの処理をブロックするというものである。条件が調った場合、クライアントは(ブロックされている状態から)解放され、リクエストの処理が再開される。クライアント間の同期を取るために、複数のクライアントを同一の条件の下にブロックすることが可能である。また、アニメーション・フレーム・マーカー(animation frame marker)のような条件を使って、単一のクライアントをブロックすることもできる。

この拡張においては、X サーバが新たに管理する資源(resource)として、「`Counter`」(カウンタ)、「`Alarm`」(アラーム)、及び「`Fence`」(フェンス)(訳註：barrier の親戚で、スレッドを止める柵・防壁)を導入する。カウンタは、64-bit の整数値であり、クライアントのリクエストによって、あるいはサーバの内部の処理によって、増えたり減ったりするものである。クライアントは Await リクエストを送信することでブロック状態(待機状態)になることができる。この Await リクエストは、同期条件(TRIGGER という)の集合の中の１つが TRUE になるまで待機するリクエストである。アラームは、カウンタの値が特定の遷移を果たした場合にイベントを発生させるものである。フェンスは次の２つの状態のどちらかを持つ。「トリガーされている」(triggered)か「トリガーされていない」(not triggered)かである。クライアントは、フェンスの状態をこの２つの中の好きな方に変更するよう要求できる。クライアントは、AwaitFence リクエストを送信することによって、フェンスの集合の中の１つがトリガーされるまでの間、ブロック状態になることができる。フェンスは、作成時のスクリーンに結び付けられている。

クライアントは、`CreateCounter` リクエストを使って `Counter` (カウンタ) を作成することができる。カウンタは、これを引数とする２つのリクエスト `SetCounter` と `ChangeCounter` を使って変更することができる。これらは、異なるクライアントの間の同期処理を実装するのに使うことができる。

`System Counter` (システム・カウンタ)と呼ばれるカウンタも存在する。これは、クライアントがリクエストで変更するものではなく、X サーバが内部で変更するものである。システム・カウンタの変更の結果は、サーバが現在のリクエストの処理を終えるまでの間、外から知ることはできない。別の言い方をすると、システム・カウンタの更新は、リクエストが実際に実行されている時ではなく、リクエスト群の処理と処理の合間に行われているように見える。この拡張では次のようなシステム・カウンタを用意している。即ち、X プロトコル本体で定義されている「サーバ時間」とともに進むシステム・カウンタを用意しており、また、実際の世界の時間とともに進むシステム・カウンタや CRT 画面が更新(refresh)する度に変化するシステム・カウンタも(場合によっては)提供することができる。他の拡張も、独自のシステム・カウンタを提供することができる。

この拡張には `Alarm` 機構が備わっている。クライアントは、同機構を使うことによって、特定のカウンタが変更される度にイベントを受け取ることができるようになる。

クライアントは、`CreateFence` を使ってフェンスを作成することができる。フェンスは、`TriggerFence` リクエストを使ってトリガーすることができ、`ResetFence` リクエストを使って元に戻す(トリガーされてない状態にする)ことができる。`CreateFence` は引数としてドローアブルを取る。この引数は、フェンスがどのスクリーンを元にして作成されるべきなのかを示すものである。`TriggerFence` リクエストは、先行するレンダリング命令の中、指定されたフェンスのスクリーンが所有しているオブジェクト群に影響を与えるもの全てが終了した後でなければ、フェンスの状態を変更しない。フェンス・オブジェクトはスクリーンに結び付けられており、この拡張の単純なトリガー操作はスクリーンを単位として(at screen granularity)実行されるけれども、他の拡張は、任意の数のイベントに基づくもっと細かい(more fine-grained)トリガー操作を追加している可能性もあることに注意。スクリーンへの結び付けは、単にフェンス操作の粒度(scope)の上限を定めたものにすぎない。

## 型(type)

この文書は X11 プロトコルの仕様書で定められた構文上の規約を利用しており、同仕様書で定義された型(type)を使用しているので、そちらも参照してほしい。

この拡張では、以下に示す新しい型を使用する。

    INT64:                 64-bit 符号あり整数
    COUNTER:               XID
    VALUETYPE:             {Absolute,Relative};
    TESTTYPE:              {PositiveTransition,NegativeTransition,
                            PositiveComparison,NegativeComparison}
    TRIGGER:               [
                            counter:COUNTER,
                            value-type:VALUETYPE,
                            wait-value:INT64,
                            test-type:TESTTYPE
                           ]
    WAITCONDITION:         [
                            trigger:TRIGGER,
                            event-threshold:INT64
                           ]
    SYSTEMCOUNTER:         [
                            name:STRING8,
                            counter:COUNTER,
                            resolution:INT64
                           ]
    ALARM:                 XID
    ALARMSTATE:            {Active,Inactive,Destroyed}
    FENCE:                 XID

COUNTER 型は、X サーバのカウンタに対する、クライアント側のハンドルである。カウンタの値は INT64 である。

TRIGGER はカウンタに対する試験(test)であり、その結果は TRUE もしくは FALSE となる。試験の(結果の)値は、試験値(test value)、カウンタの値、及び指定された test-type の３つで決まる。

トリガーの試験値は、同トリガーの初期化の際に value-type フィールドと wait-value フィールドを用いて計算される。value-type フィールドの値が VALUETYPE 型の定数として挙げられたもの(の１つ)でない場合、トリガーを初期化するリクエストには `Value` エラーが返ることになる。value-type フィールドの値が `Absolute` の場合、試験値は wait-value フィールドの値そのものとなる。value-type フィールドの値が `Relative` の場合、試験値は wait-value フィールドの値をカウンタの値に加えることで得られる。結果として得られた試験値が INT64 (で表しうる値)の範囲から外れていた場合、トリガーを初期化するリクエストには `Value` エラーが返ることになる。counter の値が `None` であり且つ value-type が `Relative` である場合、トリガーを初期化するリクエストには `Match` エラーが返ることになる。counter の値が `None` ではなく且つ有効なカウンタを指していなかった場合、`Counter` エラーが発生する。

test-type の値が `PositiveTransition` である場合、トリガーは最初は FALSE であり、カウンタの値が「試験値より小さい値」から「試験値より大きいか等しい値」へと変化した時、同トリガーは TRUE となる。test-type の値が `NegativeTransition` である場合、トリガーは最初は FALSE であり、カウンタの値が「試験値より大きい値」から「試験値より小さいか等しい値」へと変化した時、同トリガーは TRUE となる。test-type の値が `PositiveComparison` である場合、トリガーは、カウンタの値が試験値よりも大きいかもしくは等しければ TRUE であり、さもなければ FALSE である。test-type の値が `NegativeComparison` である場合、トリガーは、カウンタの値が試験値よりも小さいかもしくは等しければ TRUE であり、さもなければ FALSE である。test-type の値が TESTTYPE 型の定数として挙げられたもの(の１つ)でない場合、トリガーを初期化するリクエストには Value エラーが返ることになる。トリガーは、counter の値として `None` を持ち、且つ有効な test-type を持っていれば、常に TRUE である。

WAITCONDITION 型は、TRIGGER 型に event-threshold (イベントの閾値)を紐付けただけのものである。イベントの閾値を使用するのは `Await` リクエストであり、トリガーが TRUE になった後、クライアントに対するイベントを生成するか否かを判断する際に使用する。event-threshold に適切な値を設定することによって、トリガーが TRUE になった後に `Await` リクエストの処理が終わった場合にそれを知ることができるようになる。これは通常、サーバのリクエスト処理速度がクライアントの期待より遅いことを表す。

SYSTEMCOUNTER 型は、クライアントに対して `System`Counter (システム・カウンタ)に関する情報を提供するものである。name フィールドは、クライアントに割り当てられたカウンタの名前を文字列で表現したものである。counter フィールドは、クライアント側のハンドルである。このハンドルは、引数としてカウンタを必要とするリクエストで使用する。resolution フィールドは、システム・カウンタのおおよその刻み幅(step-size、認識単位)を表す。同フィールドは、クライアントに対するヒントであり、この拡張ではこの刻み幅以下の大きさでしか違わない試験値を持つ２つのウェイト・コンディションを見分けることができない可能性があることを示す。たとえば、マイクロ秒の時計は 64 マイクロ秒を単位として(in steps of 64 microseconds)進むであろうから、この時計に基くカウンタは分解能(resolution)の値として 64 を持つことになろう。

存在することが保証されているシステム・カウンタはただ１つであり、名前は SERVERTIME である。このカウンタは、適当な(arbitrary)時点からの時間をミリ秒単位で数えているものである。このカウンタの下位 32 ビットは、サーバがイベントやリクエストの中で用いる Time (訳註：プロトコルではタイムスタンプ)の値を追跡する。SYNC 拡張の別の実装では、他のシステム・カウンタも導入される可能性がある。X Consortium は、システム・カウンタの名前が名前空間内で衝突しないように、名前の登録簿を管理する。

ALARM 型は、アラームという資源に対するクライアント側のハンドルを表す。

FENCE 型は、サーバが持つフェンスに対するクライアント側のハンドルを表す。フェンスの値は BOOL で表される２つの値のいづれか１つであり、それ以外の値は取り得ない。値が TRUE の場合、フェンスは「トリガーされた」状態にある。値が FALSE の場合、フェンスは「トリガーされていない」状態にある。

## エラー

Counter | このエラーは、リクエストの COUNTER 型引数の値が定義済みの COUNTER を指していなかった場合に発生する。
Alarm | このエラーは、リクエストの ALARM 型引数の値が定義済みの ALARM を指していなかった場合に発生する。
Fence | このエラーは、リクエストの FENCE 型引数の値が定義済みの FENCE を指していなかった場合に発生する。

## リクエスト

Initialize |
    version-major,version-minor: CARD8
    =>
    version-major,version-minor: CARD8
このリクエストは、SYNC 拡張の他の如何なるリクエストよりも先に実行されなければならない。クライアントがこの規則を破った場合、同クライアントの発した SYNC 拡張リクエスト全ての結果が未定義となる。このリクエストは、クライアントが使用したいと考える SYNC 拡張の版番号を引数に取る。そして、同クライアントの SYNC 拡張が実際に実装している版の番号を返す。SYNC 拡張は、クライントが指定した版番号に応じて、異なる版番号を返す可能性がある。このリクエストは、各クライアント・コネクションに対して１回だけ実行するものとする。 SYNC プロトコルの２つの版 v1 と v2 (番号は異なる)がある時、次の条件を満たす場合に限って「v1 は v2 と互換性がある」という。即ち、「v1.version_major = v2.version_major」(上位の版番号が同じ)であり、且つ「v1.version_minor <= v2.version_minor」(v1 の下位の版番号が v2 の下位の版番号以下)である場合である。「互換性がある」とは、２つの版において、全ての機能が同一の型式で実装されていることを言う。 本文書に記述する SYNC プロトコルは、上位の版番号が 3、下位の版番号が 1 である。
ListSystemCounters |
    =>
    system-counters: LISTofSYSTEMCOUNTER
    Errors: Alloc
このリクエストは、リクエストの実行時点で利用可能なシステム・カウンタの全てが入ったリスト(配列)を返す。ここには、他の拡張が管理しているシステム・カウンタも含まれる。このリクエストから返ったリストは、他の拡張がカウンタを作成したり破棄したりするのに従って、変更を被る可能性がある。
CreateCounter |
    id: COUNTER
    initial-value: INT64
    Errors: IDChoice,Alloc
このリクエストは、カウンタを１つ作成し、同カウンタに対して特定の ID を割り当てる。カウンタの値は、指定された initial-value で初期化される。このリクエストの時点では、クライアントはこのカウンタに対する待受けを行わない。
DestroyCounter |
    counter: COUNTER
    Errors: Counter,Access
このリクエストは、指定されたカウンタを破棄し、counter フィールドに同カウンタを設定していた全ての TRIGGER につき、その counter フィールドに `None` を設定する。指定されたカウンタを待ち受けていたクライアントは全て解放される。そして、event-threshold の値に関わらず、待受けクライアントのそれぞれに対して destroyed フィールドが TRUE の `CounterNotify` イベントが送られる。このリクエストで指定されたカウンタを参照していた全てのアラームは `Inactive` 状態となり、state フィールドが `Inactive` の `AlarmNotify` イベントが発生する。カウンタは、同カウンタを作成したクライアントへの(X の)接続が途切れた場合、close-down モードが Destroy であれば(訳註：X プロトコル参照)、自動的に破棄される。counter の指すカウンタがシステム・カウンタであった場合、`Access` エラーが発生する。counter が有効なカウンタを指していなかった場合、`Counter` エラーが発生する。
QueryCounter |
    counter: COUNTER
    =>
    value: INT64
    Errors: Counter
このリクエストは、counter で指定されたカウンタの現在の値を返す。counter が有効なカウンタを指していなかった場合、`Counter` エラーが発生する。
Await |
    wait-list: LISTofWAITCONDITION
    Errors: Counter,Alloc,Value
このリクエストが呼び出された場合、wait-list の中のトリガー群は、TRIGGER の定義のところで述べたように、wait-value フィールドと value-type フィールドを用いて初期化される。クライアントのための更なるリクエストの処理は、１つもしくはそれ以上の数のトリガーが TRUE になるまでの間、ブロック(block)される。このブロックの処理は、初期化の結果として即座に起こることもあるし、時間が経ってから、後続のリクエスト `SetCounter`、`ChangeCounter`、`DestroyCounter` の結果として起こることもある。 wait-list が空だった場合、Value エラーが発生する。 クライアントのブロックが解除された場合、`CounterNotify` イベントを発生させるべきか否かを判断するため、各トリガーを検査する。カウンタの値から試験値(test value)を引くことで、カウンタと試験値の差を計算する。test-type が `PositiveTransition` もしくは `PositiveComparison` である場合、計算された差が event-threshold の値以上であれば `CounterNotify` イベントが発生する。test-type が `NegativeTransition` もしくは `NegativeComparison` である場合、計算された差が event-threshold の値以下であれば `CounterNotify` イベントが発生する。計算された差が INT64 で表される範囲から外れている場合、イベントは発生しない。 この閾値検査は wait-list のリストの中の各トリガーに対して行われ、検査で当て嵌まったトリガー全てに対して `CounterNotify` イベントが発生する。`CounterNotify` イベントのための検査は、このリクエストが初めて実行された時にトリガーの中のいづれかが既に TRUE であった場合にも実施される。リクエストで複数のトリガーを指定した場合、値が FALSE であるトリガーに対しても `CounterNotify` イベントが発生する可能性がある。トリガーの中のいづれかに対応するカウンタが破棄された場合、destroyed フラグが TRUE の `CounterNotify` イベントが常に発生する。
ChangeCounter |
    counter: COUNTER
    amount: INT64
    Errors: Counter,Access,Value
このリクエストは、counter で指定されたカウンタの現在の値に amount の数値を加えることで、同カウンタを変更する。 このカウンタの変更によって、クライアントの待ち受けるトリガーの条件が満たされた場合、同クライアントはブロックを解除され、１つ以上の `CounterNotify` イベントが発生する(イベントの発生は絶対ではない)。同カウンタの変更がアラームのトリガーの条件を満たした場合、`AlarmNotify` イベントが発生し、同アラームは更新される。counter で指定されたカウンタがシステム・カウンタであった場合、`Access` エラーが発生する。counter が有効なカウンタを指していなかった場合、`Counter` エラーが発生する。カウンタ変更時の計算結果の値が INT64 の値の範囲から外れていた場合、`Value` エラーが発生し、指定されたカウンタは変更されない。 この変更によってトリガーの条件が満たされたクライアントの全てがブロックを解除されること、それゆえにこのリクエストは相互排除(mutual exclusion)の実装には使えないことに注意。
SetCounter |
    counter: COUNTER
    value: INT64
    Errors: Counter,Access
このリクエストは、counter で指定されたカウンタに value の値を設定する。結果は、カウンタの値が value になるように ChangeCounter リクエストを実行するのと同じである。counter がシステム・カウンタを指していた場合、Access エラーが発生する。counter が有効なカウンタを指していなかった場合、Counter エラーが発生する。
CreateAlarm |
    id: ALARM
    values-mask: CARD32
    values-list: LISTofVALUE
    Errors: IDChoice,Counter,Match,Value,Alloc
このリクエストは、アラームを作成し、同アラームに識別子 id を割り当てる。values-mask と values-list は、属性群(attributes)の値がどのように初期化されるべきかを具体的に指定する(訳註：LISTofVALUE の VALUE は、本文書の ver3.1 では符号化の章にて「VALUES」として定義されている)。 アラームの属性群とそのデフォルトの値は以下の通り。
属性(Attribute) | 型(Type) | デフォルトの値
--- | --- | ---
trigger | TRIGGER | counter | None
|  | value-type | Absolute
|  | value | 0
|  | test-type | PositiveComparison
delta | INT64 | 1 |
events | BOOL | TRUE |
trigger は TRIGGER の定義のところで述べたやり方で初期化され、必要であればエラーが発生する。 counter が `None` である場合はアラームの状態は `Inactive` に設定されるが、そうでない場合は Active となる。 トリガーが TRUE になった場合、それがこのリクエストの結果であるのか、それとも別のリクエスト `SetCounter`、`ChangeCounter`、`DestroyCounter`、`ChangeAlarm` の結果であるのかを問わず、常に`AlarmNotify` イベントが発生し、アラームは更新される。アラームの更新は次のように行う。即ち、delta の値をトリガーの value に加算して同トリガーを再び初期化する、という動作を同トリガーが FALSE になるまで繰り返す方法によって行う(訳註：「value」は TRIGGER 型の「wait-value」に相当)。この更新の結果として value の値が INT64 の値の範囲から外れそうになった場合、あるいは counter の値が `None` である場合、あるいは delta が 0 で test-type が `PositiveComparison` もしくは `NegativeComparison` である場合、value の値は変更されず、アラームの状態は `Inactive` となり、その後にイベントが発生する。`Inactive` 状態のアラームは、`ChangeAlarm` リクエストもしくは `DestroyAlarm` リクエストが実行されるまでの間、これ以上イベントを生成しない。 test-type が`PositiveComparison` もしくは `PositiveTransition` であり且つ delta がゼロより小さい場合、あるいは test-type が `NegativeComparison` もしくは `NegativeTransition` であり且つ delta がゼロより大きい場合、`Match` エラーが発生する。 events の値によって、リクエストを実行したクライアントに `AlarmNotify` イベントを配送するか否かが決まる。アラームはクライアントごとに別々にイベント・フラグ(events)を保持するので、他のクライアントが同アラームからのイベントを受け取るようにすることも可能である。 `AlarmNotify` イベントは必ず、`CreateAlarm` リクエストの実行の後のどこかの時点で発生する。トリガーが TRUE なら即座に発生する。そうでない場合は、後になってトリガーが TRUE になった時もしくはアラームが破棄された時に発生する。
ChangeAlarm |
    id: ALARM
    values-mask: CARD32
    values-list: LISTofVALUE
    Errors: Alarm,Counter,Value,Match
このリクエストはアラーム内の変数(parameters)を変更する。`CreateAlarm` リクエストで指定した変数は全てこのリクエストを使って変更できる。トリガーは再び初期化され、`CreateAlarm` リクエストのところで述べた通り、必要であれば `AlarmNotify` イベントが発生する。 events フラグの変更は、このリクエストを発したクライントへのイベント配送に影響を与えるが、他のクライアントへのイベント配送には影響を与えない。クライアントは、events フラグの変更を通じて、他のクライアントが作成したアラームからのイベントの配信を選択(select)したり選択解除したりすることができる。 各属性を確認し変更する際の順番は、サーバ次第である。エラーが発生した場合、属性群の一部だけが変更された可能性がある。
DestroyAlarm |
    alarm: ALARM
    Errors: Alarm
このリクエストによってアラームを破棄する。アラームを作成したクライアントとの接続が切れた時、close-down モードが `Destroy` であれば、アラームは自動的に破棄される。アラームが破棄された場合、state フィールドの値が `Destroyed` である `AlarmNotify` イベントが発生する。
QueryAlarm |
    alarm: ALARM
    =>
    trigger: TRIGGER
    delta: INT64
    events: ALARMEVENTMASK
    state: ALARMSTATE
    Errors: Alarm
このリクエストは、アラーム内の現在の変数を取り出す。
SetPriority |
    client-resource: XID
    priority: INT32
    Errors: Match
このリクエストは、client-resource を作成したクライアントのスケジューリング優先度(scheduling priority)を変更する。client-resource が `None` である場合、リクエストを実行したクライアントの優先度を変更する。client-resource が `None` ではなく、且つ同引数がサーバ内に存在するリソースを指していなかった場合、`Match` エラーが発生する。２つの優先度の値 A と B があるとして、A が B より大きい場合に限って、A の方が優先度が高いと言える。 クライアントの接続が初めて作成された時点では、クライアントの優先度は 0 に設定される。 クライアントの優先度が異なる場合の効果処理については SYNC 拡張の実装次第であり、場合によっては何の効果も無いということもありうる。しかしながら、高い優先度を持つクライアントのリクエストが低い優先度を持つクライアントのリクエストよりも先に実行される、というのが基本である。 大抵のアニメーション・アプリケーションでは、アニメーションを実行するクライアントがリアルタイムでないクライアントよりも優先されるのが望ましい。こうすることで、実行サーバ上のアニメーションがより滑らかになる。サーバは、最も優先度の高いクライアントのリクエストを処理するにあたって他の全てのクライアントを排除する類の、非常に厳格な優先度管理(very strict priorities)を自由に実装することができる。そのため、サーバをまるごと独占する可能性があるクライアント(例えばアニメーションであって、速度制限無しにできる限り速く継続的な出力を行うもの)は、高い優先度ではなく低い優先度を与えて実行することが重要である。
GetPriority |
    client-resource: XID
    =>
    priority: INT32
    Errors: Match
このリクエストは、client-resource を作成したクライアントのスケジューリング優先度を返す。client-resource が `None` であれば、このリクエストを呼び出したクライアントの優先度が返る。client-resource が `None` ではなく、且つ同引数がサーバ内に存在するリソースを指していなかった場合、`Match` エラーが返る。
CreateFence |
    drawable: DRAWABLE
    id: FENCE
    initially-triggered: BOOL
    Errors: IDChoice,Alloc
このリクエストは、drawable で指定されたドローアブルに結び付けられたスクリーンに対するフェンスを作成し、それに対して識別子 id を割り当てる。initially-triggered が TRUE である場合、フェンスの初期状態は「トリガーされた」状態になる。 このフェンスを待ち受けるクライアントは(このリクエストの時点では)存在しない。
TriggerFence |
    fence: FENCE
    Errors: Fence
このリクエストは、先行リクエスト(fence で指定されたフェンスのスクリーンが所有しているリソースに影響を与えるもの)のレンダリング全てが完了した後、同フェンスをトリガーされた状態にする。ここでいう先行リクエストには、他のクライアントのディスパッチ済みの(dispatched)リクエスト群も含まれる。当該フェンスが既にトリガーされた状態となっている場合、このリクエストは目に見える効果は齎さない。fence が有効なフェンスを指していなかった場合、`Fence` エラーが発生する。 fence で指定されたフェンスの状態は、このリクエストで直接変更されるとは限らないことに注意。状態変更は、要求されているレンダリングが完了した後に実施されるよう、待ち行列に入れられる(be queued)ことを保証されるにすぎない。クライアントは、後続のリクエスト(例えば、即座に先のフェンスに操作を施すリクエスト)において当該フェンスがトリガーされた状態になっているものと仮定しないよう、気をつけるべきである。後続のリクエストにおいてフェンスがトリガーされた状態でなければならない場合、まず `AwaitFence` を発行するべきである。
ResetFence |
    fence: FENCE
    Errors: Fence,Match
このリクエストは、即座に、fence で指定されたフェンスを「トリガーされていない」状態にする。フェンスが「トリガーされた」状態でなかった場合、`Match` エラーが発生する。fence が有効なフェンスを指していなかった場合、`Fence` エラーが発生する。 `TriggerFence` の「遅れて発生する効果」に関する先述の注意を確認してほしい。特に注意すべきなのは、`TriggerFence` リクエストの直後に `ResetFence` リクエストを実行すると、おそらく `Match` エラーが発生することになるということである。２つのリクエストの間に `AwaitFence` リクエストを発行するべきである。
DestroyFence |
    fence: FENCE
    Errors: Fence
このリクエストは、fence で指定されたフェンスを破棄するものである。このフェンスを待ち受けるクライアントは全て解放される。フェンスを作成したクライアントとの接続が切れた場合、close-down モード(訳註：X プロトコル参照)が `DestroyAll` であれば、同フェンスは自動的に破棄される。fence が有効なフェンスを指していなかった場合、`Fence` エラーが発生する。
QueryFence |
    fence: FENCE
    =>
    triggered: BOOL
    Errors: Fence
このリクエストは、fence で指定されたフェンスが「トリガーされた」状態であれば TRUE を、「トリガーされていない」状態であれば FALSE を返す。fence が有効なフェンスを指していなかった場合、`Fence` エラーが発生する。
AwaitFence |
    fence-list: LISTofFENCE
    Errors: Fence,Alloc
このリクエストが実行された場合、このクライアントの後続のリクエストの処理は、fence-list にあるフェンスの１つ以上がトリガーされた状態になるまでの間、ブロックされる。フェンスのいづれかが既にトリガーされた状態であれば、リクエストの処理は即座に再開する。fence-list の要素のいづれかが有効なフェンスを指していなかった場合、`Fence` エラーが発生する。

## イベント

CounterNotify |
    counter: COUNTER
    wait-value: INT64
    counter-value: INT64
    time: TIME
    count: CARD16
    destroyed: BOOL
`CounterNotify` イベントは、`Await` リクエストの処理が完了した後、クライアントがブロックを解除された時に発生する可能性がある。wait-value は待ち受けている値であり、counter-value はこのイベントが生成された時点におけるカウンタの実際の値である。destroyed フラグは、このイベントがカウンタの破棄の結果として生じたものである場合は TRUE であり、そうでなければ FALSE である。time は、イベントが発生した時点におけるサーバ時間である。 クライアントのブロックが解除された場合、Await リクエストに対する全ての `CounterNotify` イベントが連続で(切れ目なく)発生する。count が 0 であれば、同リクエストに関しては、これ以上後続のイベントは存在しない。count が n であれば、少なくとも n 個のイベントが続く。
AlarmNotify |
    alarm: ALARM
    counter-value: INT64
    alarm-value: INT64
    state: ALARMSTATE
    time: TIME
`AlarmNotify` イベントは、アラームがトリガーされた時に発生する。alarm-value は、アラームがトリガーされた時点における、同アラームのトリガーの試験値である。counter-value は、アラームをトリガーしたカウンタの値である。time は、このイベントが発生した時点におけるサーバ時間である。state は、アラームの新しい状態である。state が `Inactive` である場合、`ChangeAlarm` リクエストが実行されるか、アラームが破棄されるか、あるいはアラームのカウンタが破棄されるかするまでの間、このアラームによってはこれ以上のイベントは生成されない。

## 第２章　符号化

この章では、X11 プロトコルの符号化に関する文書(X Window System Protocol 附録 B の「プロトコルの符号化」)で確立した構文上の規約を用いており、また同文書で定義した型を使用しているので、同文書も参照してほしい。

この拡張の名称は「SYNC」である。

## 新しい型(type)の符号化

SYNC 拡張では、以下の新しい型を使用する。

    ALARM: CARD32

    ALARMSTATE:
           0         Active
           1         Inactive
           2         Destroyed

    COUNTER: CARD32

    INT64: 符号あり 64-bit 整数

    SYSTEMCOUNTER:
           4         COUNTER                 カウンタ
           8         INT64                   分解能
           2         n                       名前の長さ(バイト単位)
           n         STRING8                 名前
           p                                 pad,p=pad(n+2)

    TESTTYPE:
           0         PositiveTransition
           1         NegativeTransition
           2         PositiveComparison
           3         NegativeComparison

    TRIGGER:
           4         COUNTER                 counter
           4         VALUETYPE               wait-type
           8         INT64                   wait-value
           4         TESTTYPE                test-type  VALUETYPE:
           0         Absolute
           1         Relative

    WAITCONDITION:
           20        TRIGGER                 trigger
           8         INT64                   イベントの閾値(しきいち)

    FENCE: CARD32

INT64 は８バイトで符号化される。上位４バイトが先で、下位４バイトがそれに続く。４バイトの塊それぞれの中でのバイトの順序は、接続設定の時に決めた順序を使用する。

## エラーの符号化

    Counter
            1    0            Error (X11 におけるエラーを表すコード)
            1    Base + 0     code (SYNC 拡張におけるエラーの種類を表すコード)
            2    CARD16       sequence number (通し番号)
            4    CARD32       bad counter
            2    CARD16       minor opcode
            1    CARD8        major opcode
            21                unused
    Alarm
            1    0            Error
            1    Base + 1     code
            2    CARD16       sequence number
            4    CARD32       bad alarm
            2    CARD16       minor opcode
            1    CARD8        major opcode
            21                unused
    Fence
            1    0            Error
            1    Base + 2     code
            2    CARD16       sequence number
            4    CARD32       bad fence
            2    CARD16       minor opcode
            1    CARD8        major opcode
            21                unused

## リクエストの符号化

    Initialize
            1    CARD8        major opcode (SYNC 拡張リクエストを表す X11 のコード)
            1    0            minor opcode (SYNC 拡張におけるリクエストの種類を表すコード)
            2    2            request length (リクエストの長さ)
            1    CARD8        major version
            1    CARD8        minor version
            2                 unused
    =>
            1    1            Reply
            1                 unused
            2    CARD16       sequence number
            4    0            reply length
            1    CARD8        major version
            1    CARD8        minor version
            2                 unused
            20                unused

    ListSystemCounters
            1    CARD8                  major opcode
            1    1                      minor opcode
            2    1                      request length
    =>
            1    1                      Reply
            1                           unused
            2    CARD16                 sequence number
            4    0                      reply length
            4    INT32                  list length
            20                          unused
            4n   list of SYSTEMCOUNTER  system counters

    CreateCounter
            1    CARD8                  major opcode
            1    2                      minor opcode
            2    4                      request length
            4    COUNTER                id
            8    INT64                  initial value (初期値)

    DestroyCounter
            1    CARD8                  major opcode
            1    6                      minor opcode[1]
            2    2                      request length
            4    COUNTER                counter
    =>
            1    1                      Reply
            1                           unused
            2    CARD16                 sequence number
            4    0                      reply length
            8    INT64                  counter value
            16                          unused

    Await
            1    CARD8                  major opcode
            1    7                      minor opcode[2]
            2    1 + 7*n                request length
            28n  LISTofWAITCONDITION    wait conditions

    ChangeCounter
            1    CARD8                  major opcode
            1    4                      minor opcode[3]
            2    4                      request length
            4    COUNTER                counter
            8    INT64                  amount

    SetCounter
            1    CARD8                  major opcode
            1    3                      minor opcode[4]
            2    4                      request length
            4    COUNTER                counter
            8    INT64                  value

    CreateAlarm
            1    CARD8                  major opcode
            1    8                      minor opcode
            2    3+n                    request length
            4    ALARM                  id
            4    BITMASK                values mask

                 #x00000001             counter
                 #x00000002             value-type
                 #x00000004             value
                 #x00000008             test-type
                 #x00000010             delta
                 #x00000020             events

            4n   LISTofVALUE            values

    VALUES
            4    COUNTER                counter
            4    VALUETYPE              value-type
            8    INT64                  value
            4    TESTTYPE               test-type
            8    INT64                  delta
            4    BOOL                   events

    ChangeAlarm
            1    CARD8                  major opcode
            1    9                      minor opcode
            2    3+n                    request length
            4    ALARM                  id
            4    BITMASK                values mask
                 CreateAlarm と同じ符号を使用
            4n   LISTofVALUE            values
                 CreateAlarm と同じ符号を使用

    DestroyAlarm
            1    CARD8        major opcode
            1    11           minor opcode[5]
            2    2            request length
            4    ALARM        alarm

    QueryAlarm
            1    CARD8        major opcode
            1    10           minor opcode[6]
            2    2            request length
            4    ALARM        alarm
    =>
            1    1            Reply
            1                 unused
            2    CARD16       sequence number
            4    2            reply length
            20   TRIGGER      trigger
            8    INT64        delta
            1    BOOL         events
            1    ALARMSTATE   state
            2                 unused

    SetPriority
            1    CARD8        major opcode
            1    12           minor opcode
            2    3            request length
            4    CARD32       id
            4    INT32        priority

    GetPriority
            1    CARD8        major opcode
            1    13           minor opcode
            2    1            request length
            4    CARD32       id
    =>
            1    1            Reply
            1                 unused
            2    CARD16       sequence number
            4    0            reply length
            4    INT32        priority
            20                unused

    CreateFence
            1    CARD8        major opcode
            1    14           minor opcode
            2    4            request length
            4    DRAWABLE     drawable
            4    FENCE        id
            1    BOOL         initially triggered
            3                 unused

    TriggerFence
            1    CARD8        major opcode
            1    15           minor opcode
            2    2            request length
            4    FENCE        id

    ResetFence
            1    CARD8        major opcode
            1    16           minor opcode
            2    2            request length
            4    FENCE        id

    DestroyFence
            1    CARD8        major opcode
            1    17           minor opcode
            2    2            request length
            4    FENCE        id

    QueryFence
            1    CARD8        major opcode
            1    18           minor opcode
            2    2            request length
            4    FENCE        id
    =>
            1    1            Reply
            1                 unused
            2    CARD16       sequence number
            4    0            reply length
            1    BOOL         triggered
            23                unused

    AwaitFence
            1    CARD8        major opcode
            1    19           minor opcode
            2    1 + n        request length
            4*n  LISTofFENCE  wait conditions

## イベントの符号化

    CounterNotify
            1    Base + 0     code (X11 における SYNC 拡張イベントのコードの開始位置 + 0)
            1    0            kind (SYNC 拡張におけるイベントの種類を表す番号)
            2    CARD16       sequence number
            4    COUNTER      counter
            8    INT64        wait value
            8    INT64        counter value
            4    TIME         timestamp(タイムスタンプ)
            2    CARD16       count
            1    BOOL         destroyed
            1                 unused

    AlarmNotify
            1    Base + 1     code
            1    1            kind
            2    CARD16       sequence number
            4    ALARM        alarm
            8    INT64        counter value
            8    INT64        alarm value
            4    TIME         timestamp
            1    ALARMSTATE   state
            3                 unused

[1] 本文書の以前の版では、従たる命令コード(minor opcode)が間違っていた。

[2] 本文書の以前の版では、従たる命令コードが間違っていた。

[3] 本文書の以前の版では、従たる命令コードが間違っていた。

[4] 本文書の以前の版では、従たる命令コードが間違っていた。

[5] 本文書の以前の版では、従たる命令コードが間違っていた。

[6] 本文書の以前の版では、従たる命令コードが間違っていた。

入り口に戻る