#include "../../../../framework/ccacore/Port.h"
#include "../../../../framework/ccacore/CCATServicesProxy.h"
#include "ConcatComponent.h"
#include "ConcatComponentHome.h"
#include "../../../../framework/idl/myString/MyString_idl.h"
#include "../../../../framework/ccacore/RegisterType.h"
#include "../../../../framework/ccacore/FRAMEWORK_REGISTRATION_ID.h"
#include "../../../system/event-channel/EventChannelComponent.h"
#include "../../../system/event-channel/EventChannelComponentHome.h"
#include "../../../../framework/idl/eventPort/ProvidesEventPortSkel.h"
#include "../../../../framework/idl/eventChannel/ProvidesFilteringEventChannelSkel.h" 

HPCxx_Mutex myLock;

ConcatComponent *concatComponent = NULL;
CCATServicesSkel *concatCore = NULL;

// Flag used to make sure that the core is initialized 
// before the function  returnComponentID tries to access it.
// We cannot use sync variables here, as hpcxx_initAgent
// may not have gone  through (i.e. Nexus may not have been
// initialized) when this function will get called.
static bool coreDone = false;

// This global method is invoked by the creation
// service (gram) to get a handle to the component.
// It is okay to busy wait (and hence waste cpu cycles)
// as the component should not be allowed to attempt to 
// do anything useful before coreDone gets set to true
CCATServicesProxy returnComponentID(){
  while (!coreDone) ;
  ((CCATServicesProxy *)(concatCore->getComponentID()))->setName("CONCAT_COMPONENT_ID");
  return *(dynamic_cast(concatCore->getComponentID()));

int main(int argc, char **argv) {
  hpcxx_initAgent(argc, argv);

  // returnComponentID(...) is specific to 
  // a user component. As a result it needs to
  // be registered here
  hpcxx_register(returnComponentID, RETURN_COMPONENT_ID);

  // register all the remote methods
  // that will be remotely invoked
  // once the component is initialized
  // Needs to be done only once per 
  // instantiation, hence it is a static
  // method call

  // Avoid race condtions
  // Let only one thread be able to 
  // setServices(...) on the component

  // Event channel creation and setup

  // Create a standard event channel component to be added to each application
  // component. This will take care of all the required initialization,
  // including ports and component registration.
  EventChannelComponent *channel = EventChannelComponentHome::instantiate();

  // create a core for the event channel. This must be different from the core
  // for the application component, although they must share the pseudo
  // components. The core creation will make calls on the
  // FrameworkServicesfactory and create the pseudo components, but will not
  // connect them to the event channel ports. When you instantiate a core with
  // an event channel as a parameter, it will complete this "framework
  // bootstrapping" process by making connections between the event channel and
  // the pseudo components.
  CCATServicesSkel *eventCore = new CCATServicesSkel();
  channel->setServices (eventCore);
  CCATServicesProxy* eventCompID = (CCATServicesProxy *)eventCore->getComponentID();

  // Instantiate a CCAT specific implementation of the services object.
  // This will get the pseudo components from the 
  concatCore = new CCATServicesSkel(eventCompID);

  // Instantiate a concat component. Will also do whatever initialization
  // necessary for this component to run properly, which includes port and
  // component registration. Hide the component specific initializations
  // with the instantiate() method
  concatComponent = ConcatComponentHome::instantiate();

  // This call is required as part of Component Interface. The component now has
  // a handle to the framework.

  // export the event channel component's "register" provides port as the
  // application component's "register" provides port.
  ConnectionService *connectionService = 
    (ConnectionService *) (concatCore->getPort("ConnectionService"));
  CCATServicesProxy* concatCompID = 
    (CCATServicesProxy *) concatCore->getComponentID();  
  connectionService->exportAs(concatCompID, eventCompID, "register", "register");  


  // It is now okay to return the componentID
  // to the creationService
  coreDone = true;
  cout << "ConcatServer:Up and waiting for requests\n" << endl;

  // sleep till you get a kill signal
  HPCxx_Sync i;
  int waitForKillSignal = i;

  // This sleep() call is useful if the
  // above kill statement is used. Just ensures
  // that the component dies before HPCxx 
  // starts its cleanup

Back to CCA Compliant HPC++ based CCAT Components
Last modified: Tue Jan 25 15:18:29 EST 2000