Factory client & server

Example 40. factory.idl


module Examples {

  module Factory {

    interface AbstractService {
      void doit (in string mesg);
      void destroy ();
    };

    interface Producer {
      AbstractService produce (in string id);
    };
  };
};
$ orbit-idl-2 --skeleton-impl factory.idl geenrates all the files we will use in this example.
File Usage for Client Usage for Server
factory.h readonly readonly
factory-common.c readonly readonly
factory-stubs.c readonly -
factory-skels.c - readonly
factory-skelimpl.c - template for user code
Files remaining to write are listed in following table, starting with factory-client.c in following chapter.
factory-client.c write the client code
factory-server.c write the generic code for servant creation


Factory client

Example 41. factory-client.c

/* factory-client.c hacked by Frank Rehberger
 * <F.Rehberger@xtradyne.de>.  */

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <orbit/orbit.h>

#include "examples-toolkit.h" /* etk_ functions */ 
#include "factory.h"


static CORBA_ORB  global_orb = CORBA_OBJECT_NIL; /* global orb */
 
/* Is called in case of process signals. it invokes CORBA_ORB_shutdown()
 * function, which will terminate the processes main loop.
 */
static
void
client_shutdown (int sig)
{
        CORBA_Environment  local_ev[1];
        CORBA_exception_init(local_ev);
 
        if (global_orb != CORBA_OBJECT_NIL)
        {
                CORBA_ORB_shutdown (global_orb, FALSE, local_ev);
                etk_abort_if_exception (local_ev, "caught exception");
        }
}
 
        
/* Inits ORB @orb using @argv arguments for configuration. For each
 * ORBit options consumed from vector @argv the counter of @argc_ptr
 * will be decremented. Signal handler is set to call
 * echo_client_shutdown function in case of SIGINT and SIGTERM
 * signals.  If error occures @ev points to exception object on
 * return.
 */
static
void
client_init (int               *argc_ptr,
       char              *argv[],
             CORBA_ORB         *orb,
             CORBA_Environment *ev)
{
        /* init signal handling */
 
        signal(SIGINT,  client_shutdown);
        signal(SIGTERM, client_shutdown);
         
        /* create Object Request Broker (ORB) */
         
        (*orb) = CORBA_ORB_init(argc_ptr, argv, "orbit-local-orb", ev);
        if (etk_raised_exception(ev)) return;
}

/* Releases @servant object and finally destroys @orb. If error
 * occures @ev points to exception object on return.
 */
static
void
client_cleanup (CORBA_ORB                 orb,
                CORBA_Object              servant,
                CORBA_Environment        *ev)
{
        /* releasing managed object */
        CORBA_Object_release(servant, ev);
        if (etk_raised_exception(ev))
    return;
 
        /* tear down the ORB */
        if (orb != CORBA_OBJECT_NIL)
        {
                /* going to destroy orb.. */
                CORBA_ORB_destroy(orb, ev);
                if (etk_raised_exception(ev)) 
      return;
        }
}

/**
 *
 */
static
void
client_run (Examples_Factory_Producer     factory,
      CORBA_Environment            *ev)
{
  #define MAX_ID_LEN 100

  CORBA_char  service_id [MAX_ID_LEN+1] = "";
  gint i = 0;
  gint j = 0;

  for (i = 0; i<20; ++i)
  {
    snprintf (service_id, MAX_ID_LEN, "id-%d", i);

    g_printf ("abstract-service: create,");
    Examples_Factory_AbstractService service 
      = Examples_Factory_Producer_produce (factory, 
                   service_id, 
                   ev);
    if (etk_raised_exception (ev)) 
      return;
    
    for (j = 0; j < 5; ++j)
    {
      g_printf (" apply,");

      CORBA_char *mesg = "hallo welt";
      Examples_Factory_AbstractService_doit (service, 
                     mesg, 
                     ev);
      if (etk_raised_exception (ev)) 
        return;
    }

    g_printf (" destroy\n");

    Examples_Factory_AbstractService_destroy (service, ev);
    if (etk_raised_exception (ev)) 
      return;

    CORBA_Object_release ((CORBA_Object) service, ev);
    if (etk_raised_exception (ev)) 
      return;

  }
  #undef MAX_IDL_LEN
}

/*
 * main 
 */
int
main(int argc, char* argv[])
{
        CORBA_char filename[] = "factory.ref";
         
        Examples_Factory_Producer producer = CORBA_OBJECT_NIL;
 
        CORBA_Environment ev[1];
        CORBA_exception_init(ev);
 
        client_init (&argc, argv, &global_orb, ev);
        etk_abort_if_exception(ev, "init failed");
 
        g_print ("Reading service reference from file \"%s\"\n", filename);
 
        producer 
          = (Examples_Factory_Producer) 
    etk_import_object_from_file (global_orb,
               filename,
               ev);
        etk_abort_if_exception(ev, "import service failed");
 
        client_run (producer, ev);
        etk_abort_if_exception(ev, "service not reachable");
  
        client_cleanup (global_orb, producer, ev);
        etk_abort_if_exception(ev, "cleanup failed");
  
        exit (0);
}

Factory server

Example 42. factory-server.c

/*
 * factory-server program. Hacked by Frank
 * Rehberger <F.Rehberger@xtradyne.de>
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <orbit/orbit.h>
#include <ORBitservices/CosNaming.h>

#include "factory.h"
#include "factory-skelimpl.c" 

#include "examples-toolkit.h" /* etk_ functions */ 

static CORBA_ORB          global_orb = CORBA_OBJECT_NIL; /* global orb */
static PortableServer_POA root_poa   = CORBA_OBJECT_NIL; /* root POA
  
/* Is called in case of process signals. it invokes CORBA_ORB_shutdown()
 * function, which will terminate the processes main loop.
 */
static
void
server_shutdown (int sig)
{
  CORBA_Environment  local_ev[1];
  CORBA_exception_init(local_ev);

        if (global_orb != CORBA_OBJECT_NIL)
        {
                CORBA_ORB_shutdown (global_orb, FALSE, local_ev);
                etk_abort_if_exception (local_ev, "caught exception");
        }
}

/* Inits ORB @orb using @argv arguments for configuration. For each
 * ORBit options consumed from vector @argv the counter of @argc_ptr
 * will be decremented. Signal handler is set to call
 * echo_server_shutdown function in case of SIGINT and SIGTERM
 * signals.  If error occures @ev points to exception object on
 * return.
 */static 
void 
server_init (int                 *argc_ptr, 
       char                *argv[],
       CORBA_ORB           *orb,
       PortableServer_POA  *poa,
       CORBA_Environment   *ev)
{
  PortableServer_POAManager  poa_manager = CORBA_OBJECT_NIL; 

  CORBA_Environment  local_ev[1];
  CORBA_exception_init(local_ev);

  /* init signal handling */
  signal(SIGINT,  server_shutdown);
  signal(SIGTERM, server_shutdown);
  
  /* create Object Request Broker (ORB) */
  
        (*orb) = CORBA_ORB_init(argc_ptr, argv, "orbit-local-orb", ev);
  if (etk_raised_exception(ev)) 
    goto failed_orb;

        (*poa) = (PortableServer_POA) 
    CORBA_ORB_resolve_initial_references(*orb, "RootPOA", ev);
  if (etk_raised_exception(ev)) 
    goto failed_poa;

        poa_manager = PortableServer_POA__get_the_POAManager(*poa, ev);
  if (etk_raised_exception(ev)) 
    goto failed_poamanager;

 PortableServer_POAManager_activate(poa_manager, ev);
  if (etk_raised_exception(ev)) 
    goto failed_activation;

        CORBA_Object_release ((CORBA_Object) poa_manager, ev);
  return;

 failed_activation:
 failed_poamanager:
        CORBA_Object_release ((CORBA_Object) poa_manager, local_ev);
 failed_poa:
  CORBA_ORB_destroy(*orb, local_ev);    
 failed_orb:
  return;
}

/* Entering main loop @orb handles incoming request and delegates to
 * servants. If error occures @ev points to exception object on
 * return.
 */
static void 
server_run (CORBA_ORB          orb,
      CORBA_Environment *ev)
{
        /* enter main loop until SIGINT or SIGTERM */
  
        CORBA_ORB_run(orb, ev);
  if (etk_raised_exception(ev)) return;

        /* user pressed SIGINT or SIGTERM and in signal handler
   * CORBA_ORB_shutdown(.) has been called */
}

/* Releases @servant object and finally destroys @orb. If error
 * occures @ev points to exception object on return.
 */
static void 
server_cleanup (CORBA_ORB           orb,
    PortableServer_POA  poa,
    CORBA_Object        ref,
    CORBA_Environment  *ev)
{
  PortableServer_ObjectId   *objid       = NULL;

  objid = PortableServer_POA_reference_to_id (poa, ref, ev);
  if (etk_raised_exception(ev)) return;
    
  /* Servant: deactivatoin - will invoke  __fini destructor */
  PortableServer_POA_deactivate_object (poa, objid, ev);
  if (etk_raised_exception(ev)) return;

  PortableServer_POA_destroy (poa, TRUE, FALSE, ev);
  if (etk_raised_exception(ev)) return;

  CORBA_free (objid);

        CORBA_Object_release ((CORBA_Object) poa, ev);
  if (etk_raised_exception(ev)) return;
  
        CORBA_Object_release (ref, ev);
  if (etk_raised_exception(ev)) return;

        /* ORB: tear down the ORB */
        if (orb != CORBA_OBJECT_NIL)
        {
                /* going to destroy orb.. */
                CORBA_ORB_destroy(orb, ev);
    if (etk_raised_exception(ev)) return;
        }
}

/* Creates servant and registers in context of ORB @orb. The ORB will
 * delegate incoming requests to specific servant object.  @return
 * object reference. If error occures @ev points to exception object
 * on return.
 */
static CORBA_Object
server_activate_service (CORBA_ORB           orb,
       PortableServer_POA  poa,
       CORBA_Environment  *ev)
{
  Examples_Factory_Producer ref = CORBA_OBJECT_NIL; 

  ref = impl_Examples_Factory_Producer__create (poa, ev);
  if (etk_raised_exception(ev)) 
    return CORBA_OBJECT_NIL;
  
  return ref;
}

/* 
 * main 
 */

int
main (int argc, char *argv[])
{
  CORBA_Object servant = CORBA_OBJECT_NIL;
  
  CORBA_char filename[] = "factory.ref";

  CORBA_Environment  ev[1];
  CORBA_exception_init(ev);
  
  server_init (&argc, argv, &global_orb, &root_poa, ev);
  etk_abort_if_exception(ev, "failed ORB init");

  servant = server_activate_service (global_orb, root_poa, ev);
  etk_abort_if_exception(ev, "failed activating service");

  g_print ("Writing service reference to: %s\n\n", filename);

  etk_export_object_to_file (global_orb, 
           servant, 
           filename, 
           ev);
  etk_abort_if_exception(ev, "failed exporting IOR");
  
  server_run (global_orb, ev);
  etk_abort_if_exception(ev, "failed entering main loop");

  server_cleanup (global_orb, root_poa, servant, ev);
  etk_abort_if_exception(ev, "failed cleanup");

  exit (0);
}

Example 43. factory-skelimpl.c

/*
 * This is a template file generated by command 
 * orbit-idl-2 --skeleton-impl name-resolve.idl 
 * User must edit this file, inserting servant 
 * specific code between markers. 
 */

#include "factory.h"

/*** App-specific servant structures ***/

typedef struct
{
  POA_Examples_Factory_AbstractService servant;
  PortableServer_POA poa;

  /* ------ add private attributes here ------  */
  CORBA_char *id;
  CORBA_long counter;
  /* ------ ---------- end ------------ ------  */
} impl_POA_Examples_Factory_AbstractService;

typedef struct
{
  POA_Examples_Factory_Producer servant;
  PortableServer_POA poa;

  /* ------ add private attributes here ------ */
  /* ------ ---------- end ------------ ------ */
} impl_POA_Examples_Factory_Producer;

/*** Implementation stub prototypes ***/

static void
  impl_Examples_Factory_AbstractService__fini
  (impl_POA_Examples_Factory_AbstractService * servant,
   CORBA_Environment * ev);
static void
  impl_Examples_Factory_AbstractService_doit
  (impl_POA_Examples_Factory_AbstractService * servant,
   const CORBA_char * mesg, CORBA_Environment * ev);

static void
  impl_Examples_Factory_AbstractService_destroy
  (impl_POA_Examples_Factory_AbstractService * servant,
   CORBA_Environment * ev);

static void
  impl_Examples_Factory_Producer__fini
  (impl_POA_Examples_Factory_Producer * servant, CORBA_Environment * ev);
static Examples_Factory_AbstractService
  impl_Examples_Factory_Producer_produce
  (impl_POA_Examples_Factory_Producer * servant, const CORBA_char * id,
   CORBA_Environment * ev);

/*** epv structures ***/

static PortableServer_ServantBase__epv
  impl_Examples_Factory_AbstractService_base_epv = {
  NULL,       /* _private data */
  (gpointer) & impl_Examples_Factory_AbstractService__fini, /* finalize routine */
  NULL,       /* default_POA routine */
};
static POA_Examples_Factory_AbstractService__epv
  impl_Examples_Factory_AbstractService_epv = {
  NULL,       /* _private */
  (gpointer) & impl_Examples_Factory_AbstractService_doit,

  (gpointer) & impl_Examples_Factory_AbstractService_destroy,

};
static PortableServer_ServantBase__epv
  impl_Examples_Factory_Producer_base_epv = {
  NULL,       /* _private data */
  (gpointer) & impl_Examples_Factory_Producer__fini,  /* finalize routine */
  NULL,       /* default_POA routine */
};
static POA_Examples_Factory_Producer__epv impl_Examples_Factory_Producer_epv = {
  NULL,       /* _private */
  (gpointer) & impl_Examples_Factory_Producer_produce,

};

/*** vepv structures ***/

static POA_Examples_Factory_AbstractService__vepv
  impl_Examples_Factory_AbstractService_vepv = {
  &impl_Examples_Factory_AbstractService_base_epv,
  &impl_Examples_Factory_AbstractService_epv,
};
static POA_Examples_Factory_Producer__vepv
  impl_Examples_Factory_Producer_vepv = {
  &impl_Examples_Factory_Producer_base_epv,
  &impl_Examples_Factory_Producer_epv,
};

/*** Stub implementations ***/

static Examples_Factory_AbstractService
impl_Examples_Factory_AbstractService__create (PortableServer_POA poa,
                 const CORBA_char * id,
                 CORBA_Environment * ev)
{
  Examples_Factory_AbstractService retval;
  impl_POA_Examples_Factory_AbstractService *newservant;
  PortableServer_ObjectId *objid;

  newservant = g_new0 (impl_POA_Examples_Factory_AbstractService, 1);
  newservant->servant.vepv = &impl_Examples_Factory_AbstractService_vepv;
  newservant->poa =
    (PortableServer_POA) CORBA_Object_duplicate ((CORBA_Object) poa, ev);
  POA_Examples_Factory_AbstractService__init ((PortableServer_Servant)
                newservant, ev);
  /*
   * Before servant is going to be activated all private attributes must 
   * be initialized.  
   */

  /* ------ init private attributes here ------ */
  newservant->id = CORBA_string_dup (id);
  newservant->counter = 0;
  /* ------ ---------- end ------------- ------ */

  objid = PortableServer_POA_activate_object (poa, newservant, ev);
  CORBA_free (objid);
  retval = PortableServer_POA_servant_to_reference (poa, newservant, ev);

  return retval;
}

/**
 * impl_Exampels_Factory_AbstractService__fini
 * 
 * Destructor called after servant has been deactivated finally.
 * In case any operation invocation, method invoation is being delayed.
 * Note, in former versions of ORBit2 this function would have been 
 * named impl_Exampels_Factory_AbstractService__destroy.
**/
static void
  impl_Examples_Factory_AbstractService__fini
  (impl_POA_Examples_Factory_AbstractService * servant,
   CORBA_Environment * ev)
{
  CORBA_Object_release ((CORBA_Object) servant->poa, ev);

  /*
   * No further remote method calls are delegated to servant and you
   * may free your private attributes. 
   */
  /* ------ free private attributes here ------  */
  CORBA_free (servant->id);
  /* ------ ---------- end ------------- ------  */

  POA_Examples_Factory_AbstractService__fini ((PortableServer_Servant)
                servant, ev);

  g_free (servant);
}

static void
  impl_Examples_Factory_AbstractService_doit
  (impl_POA_Examples_Factory_AbstractService * servant,
   const CORBA_char * mesg, CORBA_Environment * ev)
{
  /* ------ insert method code here ------ */
  g_print ("service-id=\"%s\", nth-call=\"%d\", \n", 
     servant->id, 
     servant->counter);
  ++(servant->counter);
  /* ------ ---------- end ------------ ------  */
}


static void
deactivate_servant (PortableServer_POA poa,
        PortableServer_Servant servant, CORBA_Environment * ev)
{
  PortableServer_ObjectId *id
    = PortableServer_POA_servant_to_id (poa, servant, ev);

  if (etk_raised_exception (ev))
    return;

  PortableServer_POA_deactivate_object (poa, id, ev);

  /* free id in any case  */
  g_free (id);
}

static void
  impl_Examples_Factory_AbstractService_destroy
  (impl_POA_Examples_Factory_AbstractService * servant,
   CORBA_Environment * ev)
{
  /* ------ insert method code here ------ */
  deactivate_servant (servant->poa, servant, ev);
  /* ------ ---------- end ------------ ------ */
}

static Examples_Factory_Producer
impl_Examples_Factory_Producer__create (PortableServer_POA poa,
          CORBA_Environment * ev)
{
  Examples_Factory_Producer retval;
  impl_POA_Examples_Factory_Producer *newservant;
  PortableServer_ObjectId *objid;

  newservant = g_new0 (impl_POA_Examples_Factory_Producer, 1);
  newservant->servant.vepv = &impl_Examples_Factory_Producer_vepv;
  newservant->poa =
    (PortableServer_POA) CORBA_Object_duplicate ((CORBA_Object) poa, ev);
  POA_Examples_Factory_Producer__init ((PortableServer_Servant)
               newservant, ev);
  /*
   * Before servant is going to be activated all private attributes must 
   * be initialized.  
   */

  /* ------ init private attributes here ------ */ 
  /* ------ ---------- end ------------- ------ */

  objid = PortableServer_POA_activate_object (poa, newservant, ev);
  CORBA_free (objid);
  retval = PortableServer_POA_servant_to_reference (poa, newservant, ev);

  return retval;
}

/**
 * impl_Examples_Factory_Producer__fini
 * 
 * Destructor called after servant has been deactivated finally.
 * In case any operation invocation, method invoation is being delayed.
 * Note, in former versions of ORBit2 this function would have been 
 * named impl_Exampels_Factory_Producer__destroy
**/
static void
  impl_Examples_Factory_Producer__fini
  (impl_POA_Examples_Factory_Producer * servant, CORBA_Environment * ev)
{
  CORBA_Object_release ((CORBA_Object) servant->poa, ev);

  /*
   * No further remote method calls are delegated to servant and you
   * may free your private attributes. 
   */ 
  /* ------ free private attributes here ------  */
  /* ------ ---------- end ------------- ------ */

  POA_Examples_Factory_Producer__fini ((PortableServer_Servant) servant, ev);

  g_free (servant);
}

static Examples_Factory_AbstractService
  impl_Examples_Factory_Producer_produce
  (impl_POA_Examples_Factory_Producer * servant, const CORBA_char * id,
   CORBA_Environment * ev)
{
  Examples_Factory_AbstractService retval;

  /* ------ insert method code here ------ */
  retval =
    impl_Examples_Factory_AbstractService__create (servant->poa, id, ev);
  if (etk_raised_exception (ev))
    {
      retval = CORBA_OBJECT_NIL;
    }
  /* ------ ---------- end ------------ ------  */

  return retval;
}

Compiling client & server

Example 44. Makefile

PREFIX ?= /usr
CC = gcc
TARGETS=factory-client factory-server
ORBIT_IDL=$(PREFIX)/bin/orbit-idl-2
CFLAGS=-g -DORBIT2=1 -D_REENTRANT -I$(PREFIX)/include/orbit-2.0 \
         -I$(PREFIX)/include/linc-1.0 -I$(PREFIX)/include/glib-2.0 \
         -I$(PREFIX)/lib/glib-2.0/include 
LDFLAGS= -Wl,--export-dynamic  -L$(PREFIX)/lib -lORBitCosNaming-2 -lORBit-2 -llinc -lgmodule-2.0 \
             -ldl -lgobject-2.0 -lgthread-2.0 -lpthread -lglib-2.0 -lm
IDLOUT=factory-common.c factory-stubs.c factory-skels.c factory.h

all: $(IDLOUT) factory-client factory-server

factory-server.o: factory-server.c factory-skelimpl.c

factory-client : factory-client.o factory-stubs.o factory-common.o examples-toolkit.o
factory-server : factory-server.o factory-skels.o factory-common.o examples-toolkit.o

$(IDLOUT): factory.idl
  $(ORBIT_IDL) factory.idl

%-skelimpl.c: %.idl
  $(ORBIT_IDL) --skeleton-impl $^

clean:
  rm -rf *.o *~ $(IDLOUT) *.ior *.ref

distclean: clean
  rm -rf factory-client factory-server