open binder

56
OpenBinder ~Android IPC 2 回目 ~ 横浜 Android プラットフォーム部 11 回勉強会 2011/7/19 @l_b__

Upload: lb

Post on 19-Jul-2015

117 views

Category:

Technology


1 download

TRANSCRIPT

OpenBinder~Android IPC の 2回目 ~

横浜 Androidプラットフォーム部第 11回勉強会

2011/7/19@l_b__

今日の内容

● OpenBinderのドキュメントを読んでみたら非常に興味深かったので内容のご紹介。

● 元ネタは OpenBinderのアーカイブ(http://www.angryredplanet.com/~hackbod/openbinder/)

 と

Introduction to OpenBinder and Interview with Dianne Hackborn(http://www.osnews.com/story/13674/Introduction_to_OpenBinder_and_Interview_with_Dianne_Hackborn)

OpenBinder って ?

●元々は Next Generation BeOSに採用される予定だった。●UNIXの CORBA 、Windowsの COMのように分散コンポーネント環境を提供するフレームワーク。

 以上第 3回の勉強会資料から。 実はここに全部答えがありました。

今日の結論

● OpenBinderは COMです。

COMって ?

● この結論でなるほどと分かる方は今日の話は面白くないかも。

● COMについてはあまり知らなかったので、その辺も色々調べてみたというのが今日の内容です。

OpenBinder って ?● The Binder could be described as a "framework

framework". It doesn't do anything itself, but is an enabling tool for implementing other rich frameworks, such as the view hierarchy, media framework, etc.

  (OpenBinder Binder Kitの説明から )

OpenBinder って ?

● OpenBinder was really designed as an operating system component framework.

( インタビューから )

● つまり、 OpenBinderは OS上に ViewフレームワークやMediaフレームワークなどを構築するためのコンポーネントフレームワークであり、

“ ”フレームワークのためのフレームワーク 。

分散コンポーネント環境

● 分散コンポーネント /分散オブジェクトとは● システムを機能分割し、適切に (ネットワーク上のマシンに )

配置

● 機能をコンポーネント化して再利用性を高める

● 標準化された呼び出し規約を使用して、離れた位置に配置された機能を簡単に利用可能にする。

● 代表的な技術に CORBA 、 JavaRMI/EJB 、 COM(COM+)等。

分散コンポーネント /オブジェクトの仕組み

● 以下、@IT 「スキルアップのための分散オブジェクト入門」から色々抜粋

● オブジェクトインターフェースを定義● リモートオブジェクトを呼び出すためのインターフェースを定

義する必要がある。

● CORBA 、 COMは IDL(Interface Definition Language)で定義。

● JavaRMIは Javaの Interfaceで定義。

分散コンポーネント /オブジェクトの仕組み

● スタブとスケルトン● インターフェース定義をコンパイルして、ローカルクライアン

ト側で使用するスタブと、リモート側のスケルトンを生成する。

スタブとスケルトンの役割

スタブの役割

● スタブはリモートオブジェクトと同じメソッド、プロパティを持ち、プロキシとして動作する。

● ローカルクライアントはスタブにアクセスすることで、あたかもリモートオブジェクトに直接アクセスするかのように操作できる。

● 実際の呼び出しは、スタブと下の ORB(Object Request Broker)ランタイムがパラメータをマーシャリング (共通データ形式変換 )してリモートにメッセージ送信する。

スケルトンの役割

● クライアントから来たメッセージをアンマーシャリングしてリモートオブジェクトに渡して呼び出し、結果をマーシャリングしてクライアントに返す。

分散システムの機能の特徴

● リモートオブジェクトを bind(登録 )

● bindされたリモートオブジェクトを lookup(検索 )

● lookupしたリモートオブジェクトを call(呼び出し )

する仕組みを持っている。

分散システムの機能の特徴

● ブラウザとWebサーバと DNSの仕組みも同じ。

 以上の機能を代表的な技術で見てみると

CORBAの場合

● 特定 OSや言語に依存しない共通プラットフォーム

● IDL(Interface Definition Language)で呼び出し先オブジェクトインターフェースを定義

● IIOP(Interner Inter-ORB Protocol)で COMやJavaRMI等とも通信可能

CORBAの場合

● IDLを作成し、 IDLコンパイラでコンパイルしてスタブとスケルトンを作成。

● スタブとスケルトンをそれぞれの言語で実装。

● オブジェクトの登録はいろいろなサービスが用意されている。 1例としてネーミングサービス。名前で登録して名前で検索できる。

JavaRMIの場合

● 特定 OSに依存しない Javaプラットフォーム● IDLは使わず、 Javaのインターフェースでリモートインターフェースを定義

JavaRMIの場合

● インターフェースを定義、これを実装するリモートオブジェクトクラスを作成する。

● リモートオブジェクトクラスから rmicコンパイラでスタブとスケルトンを生成する。

● リモートオブジェクトを RMIレジストリか JNDI (Java Naming and Directory Interface)に登録する。

JavaRMIの場合

● クライアントは RMIレジストリ /JNDIからリモートオブジェクト参照を取り出し、スタブを使ってアクセスする。

COM/COM+の場合

● Windowsプラットフォーム上で特定言語に依存しない。

● スクリプト言語ではオートメーション (IDLコンパイラによる事前の静的処理でなく、実行時に動的にインターフェースを取得してリモートオブジェクトを呼び出す )サポート。

● 複数のインターフェースをサポートするコンポーネントを構築するための IUnknown インターフェース。

COM/COM+の特徴● オブジェクト登録・呼び出しにはレジストリを使用。

● 全インターフェースは IUnknown インターフェースを継承し、 AddRef 、 Release 、 QueryInterface関数を実装する。

● AddRef 、 Releaseはオブジェクトの参照カウントを増減させるために使用される。

● QueryInterfaceはコンポーネントが実装する他のインターフェースを取得するために使用される。

COM/COM+の特徴

● COM+オブジェクトは、自分を参照しているクライアントをカウントし、参照カウント 0になったら自らを削除する。

● サーバ側は pingを使ってクライアントの生存確認を行い、メッセージが戻らない場合は参照カウントを減らす。

参照カウント

● ガベージコレクタの動作方法の一つ

● オブジェクトに対し、どれだけ参照されているかの値。

● 参照カウント 0なら参照されなくなったということで削除。

参照カウントの例

class A { public B b;}

class B { public A a;}

public class Test {

public static void main(String[] args) {

A a = new A();

B b = new B();

a.b = b;

b.a = a;

  }

}

参照カウントの例

●Aを生成  Aの参照カウント 1

●Bを生成  Bの参照カウント 1

●Aから Bを参照  Bの参照カウント 2

●Bから Aを参照  Aの参照カウント 2

Test

Object A Object B

① ②

参照カウントの問題点

● 循環参照が発生すると、到達不可能なオブジェクトも解放できなくなる。

循環参照の例

class A { public B b;}

class B { public A a;}

public class Test {

public static void main(String[] args) {

A a = new A();

B b = new B();

a.b = b;

b.a = a;

a = null;

b = null;

  }

}

循環参照の例●Aを生成  Aの参照カウント 1

●Bを生成  Bの参照カウント 1

●Aから Bを参照  Bの参照カウント 2

●Bから Aを参照  Aの参照カウント 2

●Aへの参照を削除  Aの参照カウント 1

●Bへの参照を削除  Bの参照カウント 1

A 、 Bは到達不可能だが

参照カウントは 1のまま

Test

Object A Object B

①②

⑤ ⑥

弱い参照

● 循環参照を防ぐために、弱い参照を用いることが出来る。

● 他の強参照が無くなると参照カウント 0となって削除される。

Test

Object A Object B

①②

⑤ ⑥

弱い参照の例●Aを生成  Aの参照カウント 1

●Bを生成  Bの参照カウント 1

●Aから Bを参照 弱参照のため Bの参照カウントは増えない

●Bから Aを参照 弱参照のため Aの参照カウントは増えない

●Aへの参照を削除  Aの参照カウント 0

●Bへの参照を削除  Bの参照カウント 0

A 、 Bは参照カウント 0になり、

自分を削除する。

ようやく本題

● OpenBinderを分散オブジェクト技術として見ると。● C++で記述、プラットフォームには依存しないが、実装は最終的に Linux向け。

● IDLで呼び出し先オブジェクトインターフェースを定義。

● 複数のインターフェースをサポートするコンポーネントを構築するためのIInterfaceや IBinder インターフェース。

● リモートオブジェクトを参照カウントによって監視。

● ネットワークには非対応、 Binderカーネルドライバによる IPCをコンポーネント間に使用。

ソース構成

build ビルドの出力先

build_system makeベースの buildシステム

commands Linuxのコマンドラインツール

components Binderコンポーネント

docs ドキュメント

headers OpenBinderAPIヘッダファイル

interfaces 公開 API中の IDLファイル

libraries OpenBinderライブラリ

modules Binderカーネルモジュール

samples サンプルコード

scripts Linux/Binderシェル向けスクリプト

servers Binder実行環境向けデーモン

tools システム生成用 Linuxコマンドラインツール

Binderの特徴

● フォーカスする対象が Handheld(Be InternetAppliance, Palm)なので、ネットワーク間ではなく、プロセス間の分散システムとして設計

● 50MHz ARM7から 400MHz ARM9がターゲット

● コンポーネントモデルを取り入れることでシステム構成が柔軟に

● プロセス間で処理を分散することで Robust

Binderと COMの相違点

● COMは Cベースだが、 Binderは C++ベースなのでよりオブジェクト指向な実装となっていて、またスマートポインタのような高度な機能を使用できる

● COMではスクリプトをサポートするには IDispatchを実装する必要があるが、全ての Binderオブジェクトはスクリプト実行可能

● Binderはマルチスレッド対応としてデザインされていて、SLockerや SHandlerのようなクラスが用意されている。

BinderAPI規約から抜粋

● クラス名

● Iで始まるクラスは Binder インターフェース。 IBinderを除き IInterfaceを継承。

● Bは BBinderに直接 /間接的に由来する Binderクラス。大体は Concrete Class 。

● Sはその他のクラス。 SValueなどのデータ型が多いが、 SAtomや SHandlerのようなものもある。

BinderAPI規約から抜粋

● メモリ管理

● 通常 Stack-baseと参照カウントの 2種類のクラスを使う。

● 参照カウントされるクラスは SAtom(SLightAtom 、SLimAtom)由来。 I 、 Bで始まる全てのクラスは参照カウントされる。

● 参照カウントされるクラスは必ず newで生成され、sptr<> 、 wptr<>を用いる。

BinderAPI規約から抜粋

● メモリ管理

● Stack-Baseクラスは大体データ型クラス● newでは生成せず、スタック上や SVector<>等の

コンテナ上で生成。

● 値渡しで使用する。 Copy-On-Wright Semanticsが使用される。

● SSharedBufferは以上の全ての特徴を持つ。

SupportKit

● OpenBinderは SupportKit 、 BinderKit 、 StorageKit等から成る。

● SupportKitは便利なユーティリティや通常処理のためのスイートで構成される。

● データ型、コンテナ、メモリ管理、スレッド処理、文字列処理等。

● SHandler 、 SMessageのようなイベントループの仕組みも。

BinderKit

● OpenBinderの本体。分散オブジェクトを使ったframeworkのための Framework 。

● ネットワークを使う COMや CORBAと違い、 Binder IPC Mechanismを使用したメッセージング。

● manifestファイルベースのコンポーネント登録

Binderサービス呼び出し

#include <services/Informant.h>

sptr<IBinder> informantBinder

= Context().LookupService(SString("informant"));

sptr<IInformant> informant

= interface_cast<IInformant>(informantBinder);

if (informant != NULL) {

informant->Inform( SValue::String("myMessage"),

SValue::String("myData") );

}

Binderオブジェクト作成#include <services/Informant.h>

class MyWatcher : public BnInformed, public SPackageSptr

{

public:

MyWatcher(const SContext& context)

: BnInformed(context)

{}

void OnInform( const SValue& information,

const SValue& cookie, const SValue& key)

{

bout << "Got informed: " << information << endl;

}

};

SPackageSptrは PackageManag-erのクラス。参照がある限りロードさ

れたままにする。

BnInformedは IInformant.idlからIDLコンパイラで生成されたクラス

Binderオブジェクトをサービスに#include <services/Informant.h>

sptr<IInformant> informant =

interface_cast<IInformant>(

Context().LookupService(SString("informant")));

sptr<IBinder> informed = new MyWatcher;

if (informant != NULL && informed != NULL)

{

informant->RegisterForCallback(

SValue::String("myMessage"), informed,

SValue::String("OnInform"));

}

Binderコンポーネント作成● コンポーネント化するには以下が必要。

● Manifestの作成● PackageManagerがインスタンス生成時に呼ぶ

Factory メソッドの追加● Manifest

<manifest>

   <component>

     <interface name="org.openbinder.services.IInformed" />

   </component>

</manifest>

Binderコンポーネント作成● Factory メソッド

#include <support/InstantiateComponent.h>

sptr<IBinder>

InstantiateComponent( const SString& component,

const SContext& context,

const SValue &args)

{

if (component == "")

return static_cast<BnInformed*>(new MyWatcher(context));

return NULL;

}

コンポーネント Makefile

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

BASE_PATH:= $(LOCAL_PATH)

PACKAGE_NAMESPACE:= org.openbinder.samples

PACKAGE_LEAF:= MyWatcher

SRC_FILES:= \

MyWatcher.cpp

include $(BUILD_PACKAGE)

BinderShell

● Binderコンポーネントをコマンドライン操作できる Binder Shellが用意されている。

● C++を使わなくても Binderコンポーネントにアクセス可能。

● 詳細は割愛。

Binder用語解説

● Binder

● "The Binder”は Binderアーキテクチャ全般を指す。

● "a Binder”は BinderInterfaceの実装を指す。● Binder Object

● IBinderの実装エンティティ。大抵は BBinderを継承するクラスのこと。

Binder用語解説

● Component

● PackageManagerに公開された Binderオブジェクト。 Javaライクな NamingSchemeを使用。

● Package

● 1つ以上のコンポーネント実装を含む。● コンポーネント実装、 Manifestから成る。● COMと違い、コンポーネント情報は静的に扱われ

る。

Binder用語解説

● PackageManager

● 使用可能なコンポーネントを追跡管理する。

● コンポーネントを動的に生成し、管理する。

● /packages/components以下に配置されたコンポーネントを Binderの名前空間を使ってロード、インスタンス生成できるようにする。

Binder用語解説

● Interface

● Binderオブジェクトが実装するメソッド、プロパティ、イベントなどの定義、 IDLとして記述され、 Pidgen(IDLコンパイラ )で C++のヘッダと実装に変換される。

● Bn*クラスが Pidgenで生成されるので、 BBinderではなくこちらを継承してクラスを実装する。

Binder用語解説

● Context

● 各 Binderオブジェクトは SContextで表される "context”中に生成される。

● contextはオブジェクトがアクセスできるサービス、設定等の Globalな状態を保持している。

Binder用語解説

● Service

● /serviceに公開され、事前に生成される Binderオブジェクト。大抵システム起動時に起動される。

Binder IPC メカニズム

● カーネルモジュールを使用したプロセス間通信の仕組み。

● 標準 LinuxIPCの代わりに使われ、効率的に「スレッド移送」として IPC操作を行うことが出来る。

● ioctl() を使っての read-writeとして実装されている。

まとめ

● OpenBinder ドキュメントには他ではあまり見ない Binderの設計思想が書かれている。

● Binderは分散オブジェクトプラットフォームの事であり、 IPCはあくまでオブジェクト間のメッセージングに特化した部分に過ぎない。

最後に

● Binderを理解するためには、 OpenBinder ドキュメントの● Binder Overview

● API Conventions

● SHandler Patterns

● Binder Recipes

● Binder Terminology

● Binder IPC Mechanism

あたりを読むことをお勧めします。