libusb  1.0.24
USBデバイスにアクセスするためのクロス・プラットフォームのユーザー・ライブラリ
警告

スレッド・セーフ

libusbは完全にスレッド・セーフになるように設計されていますが、他のAPIと同様に、意図的であろうとなかろうと、ユーザーが自分自身で妨害するのを防ぐことはできません。

以下の一般的なガイドラインに従ってください:

  • リソースを解放する関数(libusb_close()libusb_free_config_descriptor()など)の呼び出しは、同じリソースで同時に呼び出さないでください。 これは、割り当てられたポインタに複数の free() を呼び出すのと同じです。
  • 個々の libusb_transfer は、単一のスレッドで準備する必要があります。 つまり、 libusb_transfer のフィールドに2つのスレッドが同時に入力することはできません。 これは、複数のスレッドから同じ宛先バッファーを使用して sprintf() を呼び出すことに例えることができます。 入力パラメーターがすべて同じでない限り、結果は希望どおりにならない可能性があります。しかし、そもそも、この状況を完全に回避するのがいちばん良い方法です。
  • libusb_transfer 構造体とそれに関連するデータ・バッファの両方に、転送が送信されてから完了コールバックが呼び出されるまでの間はアクセスしないでください。これら構造体やデータ・バッファの "所有権" も、転送がアクティブな間はlibusbに転送されていると考えることができます。
  • さまざまな "セッター"(setter) 関数(libusb_set_log_cb()libusb_set_pollfd_notifiers() など)をそのリソースで同時に呼び出すことはできません。そうすることで未定義の動作が発生することはありませんが、アプリケーションで予期しない結果が生じる可能性があります。

複数のスレッドと非同期入出力のルールについては、マルチ・スレッド・アプリケーションと非同期入出力 で詳しく説明しています。

フォーク(fork)に関する考慮

libusbは、fork() 呼び出しが全体で機能するように設計されていません。 プラットフォームによっては、子プロセスが利用できないリソースが親プロセスにある場合があります(Linuxの活線挿抜監視スレッドなど)。 さらに、親プロセスと子プロセスはlibusbの内部ファイル・デスクリプターを共有するため、子プロセスから何らかの方法でlibusbを使用すると、親プロセスの libusb_context が不整合な状態になる可能性があります。

Linuxでは、libusbのファイル・デスクリプターはCLOEXECとしてマークされます。これは、子プロセスが状態をクリーン・アップする必要があることや、これらのファイル・デスクリプターにアクセスすることを心配せずに、 fork() および exec() を安全に実行できることを意味します。 他のプラットフォームはそれほど寛容ではないかもしれないので、各自ご注意下さい!

デバイス・リセット

libusb_reset_device() 関数を使用すると、デバイスをリセットできます。 プログラムがそのような関数を呼び出さなければならない場合、リセットによってデバイスの状態が変化することをちゃんと認識しておく必要があります(たとえば、レジスタ値がリセットされる可能性があります)。

問題は、他のプログラムが、そのプログラムが動作しているデバイスをいつでもリセットする可能性があることです。 libusbは、これが発生したときに通知するメカニズムを提供していないため、他の誰かがデバイスをリセットした場合、そのデバイスの状態が変更された理由は自分のプログラムでは明確ではありません。

つまり、これはユーザー空間でのドライバーの書き込みの制限です。基盤となるカーネルのUSBスタックから分離すると、オペレーティング・システムがそのような通知をプログラムに配信することが困難になります。LinuxカーネルのUSBスタックでは、このようなリセット通知をカーネル内のUSBドライバーに配信できますが、ユーザー空間に存在するセカンド・クラスのドライバーにこのような通知を配信する方法は明確にはありません。

ブロッキングのみの機能

以下にリストされている機能は、同期のブロック機能を介してのみ使用できます。 非同期/非ブロッキングの代替手段はなく、これらを実装する明確な方法もありません。

構成(configuration)の選択と処理

libusbがデバイス・ハンドルをアプリケーションに提示すると、対応するデバイスが未構成の状態になる可能性があります。複数の構成を持つデバイスの場合、現在選択されている構成がアプリケーションで使用したい構成ではない可能性もあります。

明らかな解決策は、デバイスの初期化ルーチンの早い段階で libusb_set_configuration() への呼び出しを追加することですが、以下の注意事項があります:

  1. デバイスがすでに目的の構成である場合、同じ構成値を使用して libusb_set_configuration() を呼び出すと、軽量デバイス(lightweight device)がリセットされます。これは望ましい動作ではない場合があります。
  2. 目的の構成がすでにアクティブになっている場合、libusbは軽量デバイスのリセットを実行することさえできない場合があります。たとえば、指紋リーダー付きのUSBキーボードを考えてみましょう。libusbを介して指紋リーダー・インターフェイスを駆動することに興味がありますが、カーネルのUSB-HIDドライバーはほとんどの場合キーボード・インターフェイスを要求します。カーネルがインターフェイスを要求しているため、軽量デバイス(lightweight device)のリセットを実行することさえできず、 libusb_set_configuration() は失敗します。 (幸いなことに、問題のデバイスはの1つの構成だけを持ちます。)
  3. 他のプログラムまたはドライバーがインターフェイスを要求している場合、libusbは構成を設定できません。 特に、これは、 libusb_set_configuration() が成功する前に、カーネル・ドライバーをすべてのインターフェイスから切り離す必要があることを意味します。

上記の問題のいくつかに対する1つの解決策は、現在アクティブな構成を調べることです。必要な構成がすでにアクティブになっている場合は、構成を選択する必要はありません:

cfg = -1;
if (cfg != desired)
libusb_set_configuration(dev, desired);

これはおそらくほとんどのシナリオに適していますが、本質的に際どいものです。なぜなら、 libusb_get_configuration()呼び出し後に、別のアプリケーションまたはドライバーが選択した構成を変更する場合があるからです。

libusb_set_configuration() が成功した場合でも、あなたのアプリケーションが libusb_set_configuration() を呼び出した後、他のアプリケーションまたはドライバーが構成を変更する可能性があることを考慮してください。

デバイスを特定の構成にロックする方法の一つは以下のとおりです:

  1. 目的の構成を設定します(または上記のロジックを使用して、既に目的の構成になっていることを確認します)
  2. あなたが使用したいインターフェイスを要求する
  3. 現在アクティブな構成が、あなたが使用したい構成であることを確認してください。

上記の方法が機能するのは、インターフェイスが要求されると、アプリケーションまたはドライバーは別の構成を選択できないためです。

転送の早期完了

注意: この節は現在Linuxを主眼に記述されています。これらの考慮事項のいずれがDarwinまたは他のプラットフォームに適用されるかどうかはわかりません。

転送が早期に完了すると(つまり、転送バッファーで許可されるよりも少ないデータが1つのパケットで送受信される場合)、libusbは転送をすぐに終了するように設計されており、他の転送がユーザーによってキューに入れられていない限り、それ以上データを転送または受信しません。

旧来のプラットフォームでは、libusbはすべての状況でこれを実行できるわけではありません。不完全なパケットが発生した後、"余剰" データが転送される場合があります。 libusbの最近のバージョンでは、この情報が保持され(転送のデータ長が更新されます)、デバイスからホストへの転送では、余分なデータがバッファーに追加されました。それでも、これは短いパケットの終わりに関する情報を失うため、良い解決策ではありません。ユーザーは、余ったデータが次の論理転送で到着することを望んでいた可能性があります。

長さゼロのパケット

  • libusbでは長さゼロの転送を送信すれば、長さがゼロのパケットをエンドポイントに送信できます。
  • The LIBUSB_TRANSFER_ADD_ZERO_PACKET フラグは現在、Linuxのみでサポートされます。
libusb_set_configuration
int libusb_set_configuration(libusb_device_handle *dev_handle, int configuration)
定義: core.c:1619
libusb_get_configuration
int libusb_get_configuration(libusb_device_handle *dev_handle, int *config)
定義: core.c:1533