Example 5-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);
};
};| 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 |
Example 5-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-mt-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);
}
Example 5-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-mt-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 5-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;
}
Example 5-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