BadCall client & server

Example 27. badcall.idl


module Examples {

  interface BadCall {
    struct Foo { 
      double fval; 
    };

    exception NoParam     { };
    exception SingleParam { string mesg; };
    exception DoubleParam { string mesg; long val; };

    Foo trigger (in long val, out Foo bar) 
      raises (NoParam, SingleParam, DoubleParam);
  };
};
$ orbit-idl-2 --skeleton-impl badcall.idl geenrates all the files we will use in this example.
File Usage for Client Usage for Server
badcall.h readonly readonly
badcall-common.c readonly readonly
badcall-stubs.c readonly -
badcall-skels.c - readonly
badcall-skelimpl.c - template for user code
Files remaining to write are listed in following table, starting with badcall-client.c in following chapter.
badcall-client.c write the client code
badcall-server.c write the generic code for servant creation


BadCall client

Example 28. badcall-client.c

/* badcall-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 <orbit/orbit.h>

#include "badcall.h"

#include "examples-toolkit.h" /* ie. etk_abort_if_exception() */

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_trigger_exception (Examples_BadCall          servant,
        CORBA_long                arg,
        CORBA_Environment        *ev)
{
  CORBA_long            in_arg  = arg;  
  Examples_BadCall_Foo *out_arg = NULL;

  Examples_BadCall_Foo  ret_val;
  
   ret_val = Examples_BadCall_trigger (servant, 
              in_arg, 
              out_arg,
              ev);  
  
  switch(etk_exception_type(ev)) {
  case CORBA_NO_EXCEPTION:/* successful outcome*/
    
    /* now use data the server delivered to client
     * over the return-value, or those out- and
     * inout-parameters */
    
    break;
    
  case CORBA_USER_EXCEPTION:/* a user-defined exception */
    if (etk_raised_exception_is_a (ev, 
                 ex_Examples_BadCall_NoParam)) 
    {
      /* NoParam exception  does not own members */ 
      Examples_BadCall_NoParam *bc 
        = (Examples_BadCall_NoParam*)CORBA_exception_value(ev);
      g_warning ("raised exception: %s\n",  
           CORBA_exception_id(ev));
    } 
    else if (etk_raised_exception_is_a (ev,
                ex_Examples_BadCall_SingleParam)) 
    {
      Examples_BadCall_SingleParam *bc 
        = (Examples_BadCall_SingleParam*)
        CORBA_exception_value(ev);
      
      g_warning ("raised exception: %s\n"
           " mesg: %s\n",  
           CORBA_exception_id(ev),
           bc->mesg);

    } else if (etk_raised_exception_is_a 
         (ev, ex_Examples_BadCall_DoubleParam)) 
    {
      Examples_BadCall_DoubleParam *bc 
        = (Examples_BadCall_DoubleParam*)
        CORBA_exception_value(ev);
      
      g_warning ("raised exception: %s\n"
           " mesg: %s\n"
           " val: %d\n",  
           CORBA_exception_id(ev),
           bc->mesg,
           bc->val);
    }
    else 
    {       
      /* should never get here ... */
      g_print ("unexpected CORBA_USER_EXCEPTION -%s\n",
         CORBA_exception_id(ev));
    }
    break;
    
  case CORBA_SYSTEM_EXCEPTION:
  default: /* standard exception */
    /*
     * CORBA_exception_id() can be used to determine which
     * particular standard exception was raised; the minor
     * member of the struct associated with the exception
     * (as yielded by CORBA_exception_value()) may provide
     * additional system-specific information about the
     * exception
     */
    g_print ("BadCall::trigger raised system exception: %s\n",  
       CORBA_exception_id(ev));
    
    break;
  }
  
  /* free any storage associated with exception */
  CORBA_exception_free(ev);
  
  CORBA_free (out_arg); /* free Foo data */
  
}

/**
 *
 */
static
void
client_run (Examples_BadCall          servant,
      CORBA_Environment        *ev)
{
  CORBA_long N=1000;
  CORBA_long i=0;

  /* increment sequence length, beginning with 0 up to 2048 */
  for (i=0; i<N; ++i)
  {
     client_trigger_exception (servant, i, ev); 
  }
}


/*
 * main 
 */
int
main(int argc, char* argv[])
{
  CORBA_char filename[] = "badcall.ref";

        Examples_BadCall  servant = 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);

   servant = etk_import_object_from_file (global_orb,
                 filename,
                 ev); 
        etk_abort_if_exception(ev, "importing IOR failed");

   client_run (servant, ev); 
        etk_abort_if_exception(ev, "client stopped");
 
   client_cleanup (global_orb, servant, ev); 
        etk_abort_if_exception(ev, "cleanup failed");
 
        exit (0);
}

BadCall server

Example 29. badcall-server.c

/*
 * echo-server program. Hacked from Echo test suite by by Frank
 * Rehberger <F.Rehberger@xtradyne.de>
 */

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

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

#include "examples-toolkit.h" /* ie. etk_abort_if_exception() */

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_BadCall ref = CORBA_OBJECT_NIL; 

  ref = impl_Examples_BadCall__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[] = "badcall.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 30. badcall-skelimpl.c

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

#include "badcall.h"

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

typedef struct
{
   POA_Examples_BadCall servant;
   PortableServer_POA poa;

   /* ------ add private attributes here ------ */
   CORBA_long counter;
   /* ------ ---------- end ------------ ------ */
} impl_POA_Examples_BadCall;

/*** Implementation stub prototypes ***/

static void impl_Examples_BadCall__fini(impl_POA_Examples_BadCall *
          servant, CORBA_Environment * ev);

static Examples_BadCall_Foo
impl_Examples_BadCall_trigger(impl_POA_Examples_BadCall * servant,
            const CORBA_long val,
            Examples_BadCall_Foo * bar,
            CORBA_Environment * ev);

/*** epv structures ***/

static PortableServer_ServantBase__epv impl_Examples_BadCall_base_epv = {
   NULL,      /* _private data */
   (gpointer) & impl_Examples_BadCall__fini,  /* finalize routine */
   NULL,      /* default_POA routine */
};
static POA_Examples_BadCall__epv impl_Examples_BadCall_epv = {
   NULL,      /* _private */

   (gpointer) & impl_Examples_BadCall_trigger,

};

/*** vepv structures ***/

static POA_Examples_BadCall__vepv impl_Examples_BadCall_vepv = {
   &impl_Examples_BadCall_base_epv,
   &impl_Examples_BadCall_epv,
};

/*** Stub implementations ***/

static Examples_BadCall
impl_Examples_BadCall__create(PortableServer_POA poa, CORBA_Environment * ev)
{
   Examples_BadCall retval;
   impl_POA_Examples_BadCall *newservant;
   PortableServer_ObjectId *objid;

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

   /* ------ init private attributes here ------ */ 
   newservant->counter=0;  /* init */
   /* ------ ---------- end ------------- ------ */

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

   return retval;
}

static void
impl_Examples_BadCall__fini (impl_POA_Examples_BadCall * 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 ------ */ 
   servant->counter=0;  /* reset */
   /* ------ ---------- end ------------- ------ */

   POA_Examples_BadCall__fini((PortableServer_Servant) servant, ev);
   
   g_free (servant);
}

static Examples_BadCall_Foo
impl_Examples_BadCall_trigger(impl_POA_Examples_BadCall * servant,
            const CORBA_long val,
            Examples_BadCall_Foo * bar,
            CORBA_Environment * ev)
{
   Examples_BadCall_Foo ret_val = {0.0};


   /* ------   insert method code here   ------ */
   switch ((servant->counter++) % 2)
   {
   case 0:
   {
     /* this piece of code demonstrates how to raise exception
      * without any further parameter */

     Examples_BadCall_Foo dummy_foo = {0.0};

     /* after user has assinged exception attributes, user may
      * not touch the data anymore, ownership is handed over to
      * CORBA environment  */
           CORBA_exception_set (ev, 
        CORBA_USER_EXCEPTION,
                                ex_Examples_BadCall_NoParam,
                                NULL); /* exception has no members */
           
     /* on exception you need not to care about out-argument
      * @bar, but due to programming language C it is necessary
      * to return valid value */ 
           return dummy_foo;
           break;
   }
   case 1:
   {
     /* this piece of code demonstrates how to raise exception
      * that has a string as parameter */

     Examples_BadCall_Foo dummy_foo = {0.0};

     Examples_BadCall_SingleParam* ex_parameters
       = Examples_BadCall_SingleParam__alloc();

     ex_parameters->mesg 
       = CORBA_string_dup ("raised in \"" __FILE__ "\"");

     /* after user has assinged exception attributes, user may
      * not touch the data anymore, ownership is handed over to
      * CORBA environment  */
           CORBA_exception_set (ev, 
        CORBA_USER_EXCEPTION,
                                ex_Examples_BadCall_SingleParam,
                                ex_parameters); /* exception has members */
         
     /* on exception you need not to care about out-argument
      * @bar, but due to programming language C it is necessary
      * to return valid value */ 
           return dummy_foo;
           break;
   }
   /* this code will never raise exception DoubleParam */

   default:
           g_assert_not_reached ();
   }
   /* ------ ---------- end ------------ ------ */

   return ret_val;
}

Compiling client & server

Example 31. Makefile

PREFIX ?= /usr
CC = gcc
TARGETS=badcall-client badcall-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 -lORBit-2 -llinc -lgmodule-2.0 \
             -ldl -lgobject-2.0 -lgthread-2.0 -lpthread -lglib-2.0 -lm        \
             -lORBitCosNaming-2

IDLOUT=badcall-common.c badcall-stubs.c badcall-skels.c badcall.h

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

badcall-server.o: badcall-server.c badcall-skelimpl.c

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

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

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

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

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