先来BOA,搬自:http://www.cl.cam.ac.uk/research/dtg/attarchive/omniORB/doc/2.8/omniORB2/node6.html

The Basic Object Adaptor (BOA)

This chapter describes the BOA implementation in omniORB2. The CORBA specification defines the Basic Object Adaptor as the entity that mediates between object implementations and the ORB. Unfortunately, the BOA specification is incomplete and does not address the multi-threading issues appropriately. The end result is that different ORB vendors implement different extensions to their BOAs. Worse, the implementation of the operations defined in the specification are different in different ORBs. Recently, a new Object Adaptor specification (the Portable Object Adaptor- POA) has been adopted and will replace the BOA as the standard Object Adaptor in CORBA. The new specification recognises the compatibility problems of BOA and recommends that all BOAs should be considered propriety extensions. OmniORB2 will support POA in future releases. Until then, you have to use the BOA to attach object implementations to the ORB.

The rest of this chapter describes the interface of the BOA in detail. It is important to recognise that the interface described below is omniORB2 specific and hence the code using this interface is unlikely to be portable to other ORBs.

Unless it is stated otherwise, the term ``object'' will be used below to refer to object implementations. This should not be confused with ``object references'' which are handles held by clients.

BOA Initialisation

It takes two steps to put the BOA into service. The BOA has to be initialised using BOA_init and activated using impl_is_ready.

BOA_init is a member of the CORBA::ORB class. Its signature is:

BOA_ptr BOA_init(int & argc,
char ** argv,
const char * boa_identifier);

Typically, it is used in the startup code as follows:

CORBA::ORB_ptr orb = CORBA::ORB_init(argc,argv,"omniORB2");   // line 1
CORBA::BOA_ptr boa = orb->BOA_init(argc,argv,"omniORB2_BOA"); // line 2

The argv parameters may contain BOA options. These options will be removed from the argv list when BOA_init returns. Other parameters in argv will remain. The supported options are:

-BOAiiop_port <port number (0-65535)>
Use the port number to receive IIOP requests. This option can be specified multiple times in the command line and the BOA would be initialised to listen on all of the ports.

-BOAid <id (string)>
If this option is used the id must be ``omniORB2_BOA''.

-BOAiiop_name_port <hostname[:port number]>
Similar to -BOAiiop_port, this options tells the BOA the hostname and optionally the port number to use.

If the third argument of BOA_init is non-nil, it must be the string constant ``omniORB2_BOA''. If the argument is nil, -BOAid must be present in argv.

If there is any problem in the initialisation process, a CORBA::INITIALIZE exception would be raised.

To register an object with the BOA, the method _obj_is_ready should be called with the return value of BOA_init as the argument.

BOA_init is thread-safe. It can be called multiple times and the same BOA_ptr will be returned. However, only the argv in the first call will be scanned, the argument is ignored in subsequent calls.

BOA_init returns a pseudo object of type CORBA::BOA_ptr. Similar to CORBA::Object_ptr, the pointer can be managed using CORBA::BOA_varBOA::_duplicate and CORBA::release. The pointer can be tested using CORBA::is_nil which returns true if the pointer is equivalent to the return value of BOA::_nil.

After BOA_init is called, objects can be registered. However, incoming IIOP requests would not be despatched until impl_is_ready is called.

class BOA {
public:
impl_is_ready(CORBA::ImplementationDef_ptr p = 0,
CORBA::Boolean NonBlocking = 0);
};

One of the common pitfall in using the BOA is to forget to call impl_is_ready. Until this call returns, there is no thread listening on the port from which IIOP requests are received. The remote client may hang because of this.

When impl_is_ready is called with no argument. The calling thread would be blocked indefinitely in the function until impl_shutdown (see below) is called. The thread that is calling impl_is_ready is not used by the BOA to perform its internal functions. The BOA has its own set of threads to process incoming requests and general housekeeping. Therefore, it is not necessary to have a thread blocked in the call if it can be put into use elsewhere. For example, the main thread may callimpl_is_ready once in non-blocking mode (see below) and then enter the event loop to handle the GUI frontend.

If non-blocking behaviour is needed, the NonBlocking argument should be set to 1. For instance, if you creates a callback object, you might call impl_is_ready in non-blocking mode to tell the BOA to start receiving IIOP requests before sending the callback object to the remote object. The first argument ImplementationDef_ptr is ignored by the BOA. Just set the argument to nil.

impl_is_ready is thread safe and can be called multiple times. Multiple threads can be blocked in impl_is_ready.

Object Registration

Once the BOA is initialised, objects can be registered. The purpose of object registration is to let the BOA know of the existence of the object and to dispatch requests for the object as upcalls into the object.

To register an object, the _obj_is_ready function should be called. _obj_is_ready is a member function of the implementation skeleton class. The function should be called only once for each object. The call should be made only after the object is fully initialised.

The member function obj_is_ready of the BOA may also be used to register an object. However, this function has been superseded by _obj_is_ready and should not be used in new application code.

Object Disposal

Once an object is registered, it is under the management of the BOA. To remove the object from the BOA and to delete it (when it is safe to do so), the _disposefunction should be called. _dispose is a member function of the implementation skeleton class. The function should be called only once for each object.

Notice the asymmetry in object instantiation and destruction. To instantiate an object, the application code has to call the new operator. To remove the object, the application should never call the delete operator on the object directly.

At the time the _dispose call is made, there may be other threads invoking on the object, the BOA ensures that all these calls are completed before removing the object from its internal tables and calling the delete operator.

Internally, the BOA keeps a reference count on each object. Initially, the reference count is 0. After a call to _obj_is_ready, the reference count is 1. The BOA increases the reference count by 1 before an upcall into the object is made. The count is decreased by 1 when the upcall returns. _dispose decreases the reference count by 1, if the reference count is 0, the delete operator is called. If the count is non-zero, the object is marked as disposed. The object will be deleted when the reference count eventually goes to zero.

The reference count is also increased by 1 for each object reference held in the same address space. Hence, the delete operator will not be called when there are outstanding object references in the same address space. To ensure that an object is deleted, all its object references in the same address space should be released using CORBA::release.

Unlike colocated object references, references held by clients in other address spaces would not prevent the deletion of objects. If these clients invoke on the object after it is disposed, the system exception INV_OBJREF would be raised. The difference in semantics is an undesirable side-effect of the current BOA implementation. In future, colocated references will have the same semantics as remote references, i.e. their presence will not delay the deletion of the objects.

Instead of _dispose, it may be useful to have a method to deactivate the object but not deleting it. This feature is not supported in the current BOA implementation.

BOA Shutdown

The BOA can be withdrawn from service using member functions impl_shutdown and destroy.

class BOA {
public:
void impl_shutdown();
void destroy();
};

impl_shutdown and destroy are the inverse of impl_is_ready and BOA_init respectively.

impl_shutdown deactivates the BOA. When the call returns, all the internal threads and network connections will be shutdown. Any thread blocking in impl_is_ready would be unblocked. After the call, no request from other address spaces will be processed. In other words, the BOA will be in the same state as it was in before impl_is_readywas called. For example, a remote client may hang if it tries to connect to the server after impl_shutdown was called because no thread is listening on the IIOP port.

impl_shutdown does not wait for incoming requests to complete before it closes the network connections. The remote clients will see the network connections shutdown and the replies may not reach them even if the upcalls have been completed. Therefore, if the application is to define an operation in an IDL interface to shutdown the BOA, the operation should be defined as an oneway operation.

impl_shutdown is thread-safe and can be called multiple times. The call is silently ignored if the BOA has already been shutdown. After impl_shutdown is called, the BOA can be reactivated by another call to impl_is_ready.

It should be noted that impl_shutdown does not affect outgoing network connections. That is, clients in the same address space will still be able to make calls to objects in other address spaces.

While remote requests are not delivered after impl_shutdown is called, the current implementation does not stop colocated clients from calling the objects. In future, colocated clients will exhibit the same behaviour as remote clients.

destroy permanently removed the BOA. This function will call impl_shutdown implicitly if it has not been called. When this call returns, the IIOP port(s) held by the BOA will be freed. Remote clients will see their requests refused by the operating system when they try to open a connection to the IIOP port(s).

After destroy is called, the BOA should not be used. If there is any objects still registered with the BOA, the objects should not be invoked afterwards. The objects are not disposed. Invoking on the objects after destroy would result in undefined behaviour. Initialisation of another BOA using BOA_init is not supported. The behaviour of BOA_init after this call is undefined.

Unsupported functions

The following member functions are not implemented. Calling these functions do not have any effect.

  • Object_ptr create(...)
  • ReferenceData* get_id(Object_ptr)
  • Principal_ptr get_principal(Object_ptr,Environment_ptr)
  • void change_implementation(Object_ptr, ImplementationDef_ptr)
  • void deactivate_impl(ImplementationDef_ptr)
  • void deactivate_obj(Object_ptr)

Loading Objects On Demand

Since 2.5.0, there is limited support for loading objects on demand. An application can register a handler for loading objects dynamically. The handler should have the signature omniORB::loader::mapKeyToObject_t:

  namespace omniORB {
...
class loader {
public:
typedef CORBA::Object_ptr (*mapKeyToObject_t) (const objectKey& key);
static void set(mapKeyToObject_t NewKeyToObject);
};
};

When the ORB cannot locate the target object in this address space, it calls the handler with the object key of the target. The handler is expected to instantiate the object, either in this address space or in another address space, and returns the object reference to the newly instantiated object. The ORB will then reply with a LOCATION_FORWARD message to instruct the client to retry using the object reference returned by the handler. When the handler returns, the ORB assumes ownership of the returned value. It will call CORBA::release() on the returned value when it has finished with it.

The handler may be called concurrently by multi-threads. Hence it must be thread-safe.

If the handler cannot load the target object, it should return CORBA::Object::_nil(). The object will be treated as non-existing.

The application registers the handler with the ORB at runtime using omniORB::loader::set(). This function is not thread-safe. Calling this function again will replace the old handler with the new one.

再来POA,搬自:http://www.dre.vanderbilt.edu/~schmidt/DOC_ROOT/TAO/docs/poa_migration.html

Migrating CORBA Applications from BOA to POA

Starting with the CORBA 2.2, the Basic Object Adapter (BOA) has been deprecated in favor of the Portable Object Adapter (POA). This document explains the changes required to migrate CORBA applications based on the BOA to use TAO's POA implementation, which is the only Object Adapter supported by TAO. For more information on the benefits of the POA please see the Object Interconnection columns written by Doug Schmidt and Steve Vinoski.

Contents

Client-side Changes

    • Very little has changed. Thus, many applications require no changes.

Server-side Changes

    • POA_init is replaced with resolve_initial_references("RootPOA") followed by a _narrow operation.
    • The implementation no longer inherits from the client-side stub. Instead, they inherit from PortableServer::ServantBase. The implications of this are (a) if you want a object reference for that, you must use the _this method.
    • Object ID's are assigned by the POA unless you activate the servant with a specific ID. IDL_Cubit has examples on how to do this.
    • Unlike the BOA, the POA explicitly addresses the temporal nature of servants and declares that a POA can service either transient or persistent servants (not both). The root POA's (mandated, unchangeable) policy is "transient". The implications of this are that in order for a client to be able to manufacture an object reference on its own and use that to access an object, the servant for that object must be registered with a POA whose policy is "persistent". Thus, you must create a child POA with that policy and register the servant with that POA. NOTE: when the POA declares something as "persistent", it is only stating that the key is valid between different runs of the server; it makes no claims that state or anything else is persistent.
      • Servants are not automatically activated, hence you must register them by calling some of the activate_object* methods on a POA or calling _this on the servant; with the latest you have no control on the ObjectId (which sometimes is good), and the POA must support the right policies (the RootPOA does).
      • Servant constructors use to take a const char* parameter to set they object id, this is not needed now, in fact in many cases they use to pass this argument to the skeleton class: this will fail now.
      This list is not intended to be exhaustive, but should give you a good starting point. If you find things along the way that change your applications and I didn't note them, please send them to me. Perhaps we can work together on the ultimate migration document.

Reference counting Servants

The new POA/servant reference counting rules of the CORBA 2.3 spec are somewhat tricky. Here are two main reasons why:

    • If a servant is deleted without deactivating from the POA, the application will crash because the POA will try to access the still registered (but now non-existent) servant when the POA is destroyed.

      The solution to this is to make sure that the servant is deleted after the POA is deleted or make sure that the servant is deactivated from the POA before the servant is deleted.

  • You cannot delete a servant which is the target of the current upcall/request. A good example of this is the typical destroy() method, usually written like this:

    class TAO_Export TAO_Thread_Policy : public POA_PortableServer::ThreadPolicy
    {
    void destroy (CORBA_Environment &ACE_TRY_ENV);
    }; void
    TAO_Thread_Policy::destroy (CORBA::Environment &ACE_TRY_ENV)
    {
    PortableServer::POA_var poa = this->_default_POA (ACE_TRY_ENV);
    ACE_CHECK; PortableServer::ObjectId_var id = poa->servant_to_id (this,
    ACE_TRY_ENV);
    ACE_CHECK; poa->deactivate_object (id.in (),
    ACE_TRY_ENV);
    ACE_CHECK; // Commit suicide: must have been dynamically allocated.
    delete this;
    }

    The correct implementation is:

    class TAO_Export TAO_Thread_Policy : public virtual PortableServer::RefCountServantBase,
    public virtual POA_PortableServer::ThreadPolicy
    {
    void destroy (CORBA_Environment &ACE_TRY_ENV);
    }; void
    TAO_Thread_Policy::destroy (CORBA::Environment &ACE_TRY_ENV)
    {
    //
    // Remove self from POA. Because of reference counting, the POA
    // will automatically delete the servant when all pending requests
    // on this servant are complete.
    // PortableServer::POA_var poa = this->_default_POA (ACE_TRY_ENV);
    ACE_CHECK; PortableServer::ObjectId_var id = poa->servant_to_id (this,
    ACE_TRY_ENV);
    ACE_CHECK; poa->deactivate_object (id.in (),
    ACE_TRY_ENV);
    ACE_CHECK;
    }

    One additional step required is to make the POA responsible for the servant after it has been registered with the POA:

      // Register with the POA.
    PortableServer::ThreadPolicy_var result = new_thread_policy->_this (ACE_TRY_ENV); // Give ownership of this servant to the POA.
    new_thread_policy->_remove_ref (ACE_TRY_ENV);

    If you use the above approach of multiple inheritance, you must add the following to your header file:

    // This is to remove "inherits via dominance" warnings from MSVC.
    // MSVC is being a little too paranoid.
    #if defined (_MSC_VER)
    # pragma warning (disable : 4250)
    #endif /* _MSC_VER */

    To see the above example in detail, checkout TAO/examples/POA/Reference_Counted_Servant and/or Root_POA.cpp and Root_POA.h.

[搬运]CORBA中BOA和POA的含义的更多相关文章

  1. linux top命令中各cpu占用率含义

    linux top命令中各cpu占用率含义 [尊重原创文章摘自:http://www.iteye.com/topic/1137848]0.3% us 用户空间占用CPU百分比 1.0% sy 内核空间 ...

  2. 关于phpcms中模块_tag.class.php中的pc_tag()方法的含义

    关于phpcms中模块_tag.class.php中的pc_tag()方法的含义:        在phpcms系统中自己写后台模块,要在前台模板中显示出来须要在\phpcms\modules\自定义 ...

  3. UML类图中箭头和线条的含义和用法

    UML类图中箭头和线条的含义和用法 在学习UML过程中,你经常会遇到UML类图关系,这里就向大家介绍一下UML箭头.线条代表的意义,相信通过本文的介绍你对UML中箭头.线条的意义有更明确的认识. AD ...

  4. (转)linux top命令中各cpu占用率含义及案例分析

    原文:https://blog.csdn.net/ydyang1126/article/details/72820349 linux top命令中各cpu占用率含义 0 性能监控介绍 1 确定应用类型 ...

  5. shell if判断中常用的a-z表达式含义

    shell if判断中常用的a-z表达式含义 可通过在在linux中man test命令查看下列参数的详细用法   [ -a FILE ] 如果 FILE 存在则为真. [ -b FILE ] 如果 ...

  6. shell脚本中特定符合变量的含义

    shell脚本中特定符合变量的含义: $#   传递到脚本的参数个数 $*    以一个单字符串显示所有向脚本传递的参数.与位置变量不同,此选项参数可超过9个 $$    脚本运行的当前进程PID号 ...

  7. Linux Shell中的特殊符号和含义简明总结(包含了绝大部份)

    case语句适用于需要进行多重分支的应用情况. case分支语句的格式如下: case $变量名 in 模式1) 命令序列1 ;; 模式2) 命令序列2        ;; *) 默认执行的命令序列  ...

  8. 在Qt示例项目的C ++ / QML源中的//! [0]的含义是什么?

    在Qt示例项目的C ++ / QML源中的//! [0]的含义是什么? 例如:  //! [0] GLWidget :: GLWidget(Helper * helper,QWidget * pare ...

  9. 转:js中javascript:void(0) 真正含义

    from:http://www.jb51.net/article/71532.htm 在Javascript中void是一个操作符,该操作符指定要计算一个表达式但是不返回值. 我想使用过ajax的都常 ...

随机推荐

  1. requests.exceptions.SSLError: hostname '127.0.0.1' doesn't match None

    http://stackoverflow.com/questions/33429453/python-requests-ssl-hostname-doesnt-match-error http://w ...

  2. solr 高亮显示

    官网:https://lucene.apache.org/solr/guide/6_6/highlighting.html#Highlighting-TheUnifiedHighlighter 前言 ...

  3. 【Docker】利用数据卷容器来备份、恢复、迁移数据卷

    利用数据卷容器来备份.恢复.迁移数据卷 可以利用数据卷对其中的数据进行进行备份.恢复和迁移. 备份 首先使用 --volumes-from 标记来创建一个加载 dbdata 容器卷的容器,并从主机挂载 ...

  4. IE测试CSS兼容性测试

    我们知道IE6~8是现在浏览器的主流.但是由IE6开始,我们已经知道IE并不是完全执行W3C标准.我们在编程的时候往往遇到只兼容某一种浏览器. 我们以前经常使用IE Test进行IE的兼容性测试.但是 ...

  5. 给Swing的GUI组件设置前景色和背景色

    JButton btn=new JButton("TEST"); btn.setForeground(Color.white);// 设置前景色(文字颜色)btn.setBackg ...

  6. 微信公众号支付调用chooseWXPay提示“errmsg choosewxpay fail”

    微信公众号支付一直提示“errmsg choosewxpay fail”,也没有提示具体错误信息,签名没有问题(签名验证地址:https://pay.weixin.qq.com/wiki/doc/ap ...

  7. Discuz常见小问题2-如何在新建的页面上只显示一部分板块

    切换到论坛-版块管理,记住要只显示的板块的gid(比如我的是36)   为某个主导航设置一个单独的php页面(名字自己取)   如果这个页面内容跟首页forum.php完全一样,只是第三行增加了一句话 ...

  8. 重载&lt;&lt;和&gt;&gt;

    在C++编程中实现数据的输入/输出能够用cin>>ch/cout<<ch; 可是使用cin>>ch或cout<<ch并不能实现一些特殊的数据的输入或者输 ...

  9. webSQL 实现即时通讯

    websql存储方式一共有以下几个方法 openDatabase:这个方法使用现有的数据库或新建数据库来创建数据库对象. transaction:这个方法允许我们执行事务处理; executeSql: ...

  10. Openerp开发进销存系统完毕总结

      转自:http://blog.csdn.net/heartrude/article/details/9142463 安装Openoffice 在openoffice中安装openerp repor ...