Example
Component IDL
Code Block |
---|
language | cpp |
---|
title | Async.idl |
---|
linenumbers | true |
---|
collapse | true |
---|
|
#ifndef _ASYNC_IDL_
#define _ASYNC_IDL_
#pragma prefix "acs"
#include <acscommon.idl>
#include <acscomponent.idl>
module examples
{
interface MyCallback: ACS::OffShoot {
void update(in string text);
};
interface Async : ACS::ACSComponent {
oneway void delayAsync(in ACS::uLong delay, in MyCallback cb);
};
interface Async : ACS::ACSComponent {
void delay(in ACS::uLong delay);
};
};
#endif |
Component Implementation
C++
Code Block |
---|
language | cpp |
---|
title | AsyncImpl.h |
---|
linenumbers | true |
---|
collapse | true |
---|
|
#ifndef _ASYNC_IMPL_H
#define _ASYNC_IMPL_H
#include <acscomponentImpl.h>
#include <AsyncS.h>
class AsyncImpl : public virtual acscomponent::ACSComponentImpl, public virtual POA_examples::Async
{
public:
AsyncImpl(const ACE_CString& name, maci::ContainerServices* containerServices);
virtual ~AsyncImpl();
void delayAsync(ACS::uLong delay, acs::examples::MyCallback_ptr cb);
};
#endif
|
Code Block |
---|
language | cpp |
---|
title | AsyncImpl.cpp |
---|
linenumbers | true |
---|
collapse | true |
---|
|
#include <AsyncImpl.h>
#include <ACSErrTypeOK.h>
AsyncImpl::AsyncImpl(const ACE_CString& name, maci::ContainerServices* containerServices) : acscomponent::ACSComponentImpl(name, containerServices) {
}
AsyncImpl::~AsyncImpl() {
}
void AsyncImpl::delayAsync(ACS::uLong delay, acs::examples::MyCallback_ptr cb) {
cb->update("WORKING");
sleep(delay);
cb->update("DONE");
}
/* --------------- [ MACI DLL support functions ] -----------------*/
#include <maciACSComponentDefines.h>
MACI_DLL_SUPPORT_FUNCTIONS(AsyncImpl)
/* ----------------------------------------------------------------*/ |
Configuration
Code Block |
---|
language | xml |
---|
title | Components.xml |
---|
linenumbers | true |
---|
collapse | true |
---|
|
<e Name="ASYNC_CPP"
Code="AsyncImpl"
Type="IDL:acs/examples/Async:1.0"
Container="bilboContainer"
ImplLang="cpp"
KeepAliveTime="0"
/>
<e Name="ASYNC_CLIENT_CPP"
Code="AsyncClientImpl"
Type="IDL:acs/examples/AsyncClient:1.0"
Container="bilboContainer"
ImplLang="cpp"
KeepAliveTime="0"
/> |
Client Implementation
Callback Definition
C++
Code Block |
---|
language | cpp |
---|
title | MyCBImpl.h |
---|
linenumbers | true |
---|
collapse | true |
---|
|
#ifndef _MY_CB_IMPL_H
#define _MY_CB_IMPL_H
#include <AsyncC.h>
class MyCBImpl : public virtual POA_examples::MyCallback {
public:
MyCBImpl() {
status=std::string("INIT");
}
virtual ~CBuLongImpl() {}
void update(const char* value) {
status = std::string(value);
}
public:
std::string status;
};
#endif |
Standalone Client
C++
Code Block |
---|
language | cpp |
---|
title | AsyncClient.cpp |
---|
linenumbers | true |
---|
collapse | true |
---|
|
#include <maciSimpleClient.h>
#include <AsyncC.h>
#include <ACSErrTypeCommon.h>
#include <acsutilTimeStamp.h>
#include <MyCBImpl.h>
using namespace maci;
int main(int argc, char *argv[]) {
SimpleClient client;
examples::Async_var comp;
if (client.init(argc,argv) == 0) {
return -1;
} else {
client.login();
}
try {
comp = client.getComponent<examples::Async>("ASYNC_CPP", 0, true);
} catch(maciErrType::CannotGetComponentExImpl& _ex) {
_ex.log();
return -1;
}
MyCBImpl cb;
examples::MyCallback_var cbObj = cb._this();
ACS_SHORT_LOG((LM_INFO, "%s", cb.status));
comp->delayAsync(8, cbObj.in());
ACS_SHORT_LOG((LM_INFO, "%s", cb.status));
sleep(5);
ACS_SHORT_LOG((LM_INFO, "%s", cb.status));
sleep(5);
ACS_SHORT_LOG((LM_INFO, "%s", cb.status));
try {
client.releaseComponent("ASYNC_CPP");
} catch(maciErrType::CannotReleaseComponentExImpl &_ex) {
_ex.log();
return -1;
}
client.logout();
ACE_OS::sleep(3);
return 0;
} |
Component Client
C++
Code Block |
---|
language | cpp |
---|
title | AsyncClientImpl.h |
---|
linenumbers | true |
---|
collapse | true |
---|
|
#ifndef _ASYNC_CLIENT_IMPL_H
#define _ASYNC_CLIENT_IMPL_H
#include <acscomponentImpl.h>
#include <AsyncS.h>
class AsyncClientImpl : public virtual acscomponent::ACSComponentImpl, public virtual POA_examples::AsyncClient
{
public:
AsyncClientImpl(const ACE_CString& name, maci::ContainerServices* containerServices);
virtual ~AsyncClientImpl();
void delay(ACS::uLong delay);
};
#endif
|
Code Block |
---|
language | cpp |
---|
title | AsyncClientImpl.cpp |
---|
linenumbers | true |
---|
collapse | true |
---|
|
#include <AsyncClientImpl.h>
#include <ACSErrTypeOK.h>
AsyncClientImpl::AsyncClientImpl(const ACE_CString& name, maci::ContainerServices* containerServices) : acscomponent::ACSComponentImpl(name, containerServices) {
}
AsyncClientImpl::~AsyncClientImpl() {
}
void AsyncClientImpl::delay(ACS::uLong delay) {
examples::Async_var comp = getContainerServices().getComponent<examples::Async>("ASYNC_CPP", 0, true);
MyCBImpl cb;
ACS::OffShoot_var offshoot = getContainerServices().activateOffShoot(&cb);
examples::MyCallback_var cbObj = examples::MyCallback::_narrow(offshoot);
ACS_SHORT_LOG((LM_INFO, "%s", cb.status));
comp->delayAsync(delay, cbObj.in());
ACS_SHORT_LOG((LM_INFO, "%s", cb.status));
sleep(delay/2+1);
ACS_SHORT_LOG((LM_INFO, "%s", cb.status));
sleep(delay/2+1);
ACS_SHORT_LOG((LM_INFO, "%s", cb.status));
getContainerServices().releaseComponent("ASYNC_CPP");
getContainerServices().deactivateOffShoot(&cb)
}
/* --------------- [ MACI DLL support functions ] -----------------*/
#include <maciACSComponentDefines.h>
MACI_DLL_SUPPORT_FUNCTIONS(AsyncClientImpl)
/* ----------------------------------------------------------------*/ |
Notes
C++
OffShoot Standalone Client
When working with standalone clients, we need to handle the servant lifecycle of the offshoots/callbacks. There are two approaches:
...
Code Block |
---|
language | cpp |
---|
linenumbers | true |
---|
collapse | true |
---|
|
MyCBImpl* cb = new MyCBImpl();
examples::MyCallback_var cbObj = cb->_this();
...
// Stop ORB
...
// Delete the heap OffShoot servant instance
delete cb; |
OffShoot Component Client
When working with standalone clients in a component, we need to handle the servant lifecycle of the offshoots/callbacks. There are three approaches:
...
- The CORBA details are encapsulated in an ACS framework method
- A special POA is used instead of the default one, providing special policies recommended for transient CORBA objects
- PortableServer::SYSTEM_ID
- PortableServer::TRANSIENT
- PortableServer::USE_ACTIVE_OBJECT_MAP_ONLY
- PortableServer::RETAIN
It is possible to use this approach both for stack and heap variables with the same restrictions:
Stack OffShoot
For the OffShoot servant instance on the stack, you need to make sure to deactivate the OffShoot servant before cb variable goes out of scope. Here you will get compilation issues if you try to deactivate it after going out of scope.
Code Block |
---|
language | cpp |
---|
linenumbers | true |
---|
collapse | true |
---|
|
MyCBImpl cb;
ACS::OffShoot_var offshoot = getContainerServices().activateOffShoot(&cb);
examples::MyCallback_var cbObj = examples::MyCallback::_narrow(offshoot.in());
...
//Deactivate the Offshoot servant
getContainerServices().deactivateOffShoot(&cb); |
Heap OffShoot
For the OffShoot servant instance on the heap, you need to make sure to deactivate the OffShoot servant before destroying the cb variable. Doing it in the reverse order has undefined behavior, usually ending in segmentation fault.
Code Block |
---|
language | cpp |
---|
linenumbers | true |
---|
collapse | true |
---|
|
MyCBImpl* cb = new MyCBImpl();
ACS::OffShoot_var offshoot = getContainerServices().activateOffShoot(cb);
examples::MyCallback_var cbObj = examples::MyCallback::_narrow(offshoot.in());
...
//Deactivate the Offshoot servant
getContainerServices().deactivateOffShoot(cb);
// Make sure to delete the OffShoot servant instance after deactivating the CORBA object
delete cb; |