/*-------------------------------------------------------------------------------------------------------
Purpose: Embryonic process - functionality is assigned dynamically using PSRP
and PSRP components of the PUPS environment
Authors: M.A. O'Neill
Digital Vision
Didcot
Oxfordshire
OX11 8QY
Dated: 8th May 1999
Version: 1.00
E-mail: mao@sable.ox.ac.uk
-------------------------------------------------------------------------------------------------------*/
#include <me.h>
#include <utils.h>
#include <netlib.h>
#include <psrp.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <hipl_hdr.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <shmheap.h>
#include <shmalloc.h>
#include <vstamp.h>
/* Version number -- do not edit! */
#define VTAG 314
_IMPORT appl_vtag = VTAG;
/*--------------------------------------------------------------------------------------------------------
Function called when checkpoint file reloaded but before user code re-entered ...
--------------------------------------------------------------------------------------------------------*/
void restartfunc()
{ if(appl_verbose == TRUE)
{ fprintf(stderr,"\n\nrestart function\n\n\n\n");
fflush(stderr);
}
}
/*--------------------------------------------------------------------------------------------------------
Function called when checkpoint file saved ...
--------------------------------------------------------------------------------------------------------*/
void ckptfunc()
{ fprintf(stderr,"\n\ncheckpoint function\n\n\n\n");
fflush(stderr);
}
/*--------------------------------------------------------------------------------------------------------
Exit function for testfps() [interrupt when processing transactions to/from remote slave] ...
--------------------------------------------------------------------------------------------------------*/
_PRIVATE int testfps_exitf(int chid)
{ int fdes,
index;
index = get_ftab_index_by_id(chid);
(void)fcclose(ftab[index].stream);
return(0);
}
/*--------------------------------------------------------------------------------------------------------
Display process status (to attached PSRP client process) ...
--------------------------------------------------------------------------------------------------------*/
_PRIVATE int psrp_process_status(int argc, char *argv[])
{
fprintf(psrp_out,"status\n");
fflush(psrp_out);
return(PSRP_OK);
}
/*--------------------------------------------------------------------------------------------------------
Create a slaved interation client (SIC) and talk to it ...
--------------------------------------------------------------------------------------------------------*/
_PRIVATE int testsic(int argc, char *argv[])
{ int ret;
char reply[256];
psrp_channel_type *sic = (psrp_channel_type *)NULL;
if(argc != 2)
{ fprintf(psrp_out,"Usage: testsic <sic server>\n");
fflush(psrp_out);
return(PSRP_OK);
}
fprintf(psrp_out,"\ncreating (peer-to-peer) SIC to client %s\n\n",argv[2]);
fflush(psrp_out);
if((sic = psrp_create_slaved_interaction_client(psrp_out,(char *)NULL,"pslave","sic")) == (psrp_channel_type *)NULL)
{ fprintf(psrp_out,"SIC creation failed\n");
fflush(psrp_out);
return(PSRP_OK);
}
/* Send command to slaved PSRP client */
(void)psrp_write_sic(sic,"version\n");
/* Read reply */
do { if((ret = psrp_read_sic(sic,reply)) == PSRP_MORE)
{ (void)fputs(reply,psrp_out);
(void)fflush(psrp_out);
}
} while(ret == PSRP_MORE);
/* Send command to slaved PSRP client */
(void)psrp_write_sic(sic,"chelp\n");
/* Read reply */
do { if((ret = psrp_read_sic(sic,reply)) == PSRP_MORE)
{ (void)fputs(reply,psrp_out);
(void)fflush(psrp_out);
}
} while(ret == PSRP_MORE);
(void) psrp_destroy_slaved_interaction_client(psrp_out,sic);
return(PSRP_OK);
}
/*------------------------------------------------------------------------------------------------------
Get application information for slot manager ...
------------------------------------------------------------------------------------------------------*/
/* Slot information function */
_PRIVATE void embryo_slot(int level)
{ fprintf(stderr,"int dynamic app (PSRP) embryo 1.10: [ANSI C, PUPS MTD D]\n");
if(level > 1)
{ fprintf(stderr,"(c) 1996 Digital Vision, Didcot\n");
fprintf(stderr,"Author: M.A. O'Neill\n");
fprintf(stderr,"Unassigned PSRP dynamic process (PUPS format)\n\n");
}
else
fprintf(stderr,"\n");
fflush(stderr);
}
/* Application usage function */
_PRIVATE void embryo_usage()
{ fprintf(stderr,"[-state] ");
fprintf(stderr,"\n\nSignals\n\n");
fprintf(stderr,"SIGINIT SIGCHAN SIGPSRP: Process status [PSRP] request (protocol %2.2f)\n",PSRP_PROTOCOL_VERSION);
fprintf(stderr,"SICLIENT: tell client server is about to segment\n");
#ifdef THREAD_SUPPORT
fprintf(stderr,"SIGTHREAD: tell client its service thread (on PSRP server) has been terminated\n");
#endif
#ifdef CKPT
if(checkpointing == TRUE)
fprintf(stderr,"SIGCHECK SIGVACATE: CKPT job control\n");
#endif
fprintf(stderr,"SIGALIVE: check for existence of client on signal dispatch host\n");
fflush(stderr);
}
#ifdef SLOT
#include <slotman.h>
_EXTERN void (* SLOT)() = embryo_slot;
_EXTERN void (* USE )() = embryo_usage;
#endif
/*-------------------------------------------------------------------------------------------------------
Public variables and function pointers used by this application ...
-------------------------------------------------------------------------------------------------------*/
_PRIVATE _BYTE test_databag[1024];
/*-------------------------------------------------------------------------------------------------------
Functions which are private to this application ...
-------------------------------------------------------------------------------------------------------*/
/* Test function */
_PROTOTYPE _PRIVATE int static_test_function_object(int argc, char *argv[]);
/* ASCII text generation function */
_PROTOTYPE _PRIVATE int ascii(int argc, char *argv[]);
/*-------------------------------------------------------------------------------------------------------
Variables which are private to this module ...
-------------------------------------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------------------------------------------
Main - decode command tail then interpolate using parameters supplied by user ...
-------------------------------------------------------------------------------------------------------------*/
_PUBLIC int main(int argc, char *argv[])
{ int cnt = 0,
tdes = 0,
hdes = (-1);
unsigned long size;
char *h_ptr_1 = (char *)NULL,
*h_ptr_2 = (char *)NULL;
char buf[256];
FILE *tstream = (FILE *)NULL;
psrp_channel_type *embryo_sic = (psrp_channel_type *)NULL;
_BYTE *tbuf = (_BYTE *)NULL;
double *fbuf = (double *)NULL;
/* Do not allow PSRP clients to connect until we are initialised */
psrp_ignore_requests();
/*-------------------------------------------------------------------------------------------------------------
Get standard items form the command tail ...
-------------------------------------------------------------------------------------------------------------*/
std_init(TRUE,
&argc,
"1.00",
"M.A. O'Neill",
"(PSRP) embryo",
"1999",
argv);
#ifdef CKPT_SUPPORT
/* Register a ckpt function */
register_pups_ckpt_f("ckptfunc",&ckptfunc,(char *)NULL);
/* Register a restart function */
register_pups_restart_f("retstartfunc",&restartfunc,(char *)NULL);
#endif /* CKPT_SUPPORT */
register_pups_exit_f(stderr,"retstartfunc",&restartfunc,(char *)NULL);
/* Get the application to tell us what it is */
if((ptr = locate(&init,"state",&argc,args)) != NOT_FOUND)
{ fprintf(stderr," I am a PSRP embryo process, I am waiting to be\n");
fprintf(stderr," told what to do ...\n\n");
fflush(stderr);
pups_exit(1);
}
/* Complain about any unparsed arguments */
t_arg_errs(argc,argd,args);
/*-------------------------------------------------------------------------------------------------------------
Initialise PSRP function dispatch handler - note that the embryo is fully dynamic and prepared
to import both dynamic functions and data objects ...
-------------------------------------------------------------------------------------------------------------*/
psrp_init(PSRP_DYNAMIC_FUNCTION | PSRP_STATIC_DATABAG | PSRP_HOMEOSTATIC_STREAMS,NULL);
/* Attach static functions which can be accessed from PSRP client */
(void)psrp_attach_static_function(stderr,"status",(void *)&psrp_process_status);
(void)psrp_attach_static_function(stderr,"testsic",(void *)&testsic);
(void)psrp_attach_static_function(stderr,"testfps",&static_test_function_object);
/* We must define static bindinfgs BEFORE loading the default */
/* dispatch table. In the case of static bindings, the only */
/* effect of loading a saved dispatch table is to (possibly) */
/* add object aliases */
(void)psrp_load_default_dispatch_table(stderr);
/* Tell PSRP clients we are ready to service their requests */
psrp_accept_requests();
#ifdef SUPPORT_SHARED_HEAPS
/* Lets attach a shared heap */
if((hdes = msm_heap_attach("heap1",
O_RDWR | O_CREAT,
PROT_READ | PROT_WRITE,
MAP_SHARED,
LIVE)) == (-1))
pups_exit(-1);
/* And another */
/*if(msm_heap_attach("heap2",
O_RDWR | O_CREAT,
PROT_READ | PROT_WRITE,
MAP_SHARED,
LIVE) == (-1))
pups_exit(-1);
*/
/* And another */
/*if(msm_heap_attach("heap3",
O_RDWR | O_CREAT,
PROT_READ | PROT_WRITE,
MAP_SHARED,
LIVE) == (-1))
pups_exit(-1);
*/
/* Allocate some objects on the first shared heap */
if(shmalloc(hdes,260000,"object1") == (void *)NULL)
{ fprintf(stderr,"test: failed to allocated shared heap object (%s)\n","object1");
fflush(stderr);
/* If this object already exists - which is the reason that the */
/* attempt to allocate it failed, lets take a look at the shared */
/* memory associated with it */
h_ptr_1 = msm_lockobjectname(hdes,F_LOCK,"object1",WRITE);
fprintf(stderr,"INITIAL VALUE: %s\n",h_ptr_1,h_ptr_1);
msm_lockobjectname(hdes,F_ULOCK,"object1",READ);
}
if(shmalloc(hdes,55000,"object2") == (void *)NULL)
{ fprintf(stderr,"test: failed to allocated shared heap object (%s)\n","object2");
fflush(stderr);
}
/* Remove the object "object2" from the shared heap "heap1" */
h_ptr_1 = msm_lockobjectname(hdes,F_LOCK,"object2",READWRITE);
(void)shfree(hdes,h_ptr_1);
/* And add another shared object */
if(shmalloc(hdes,355000,"object3") == (void *)NULL)
{ fprintf(stderr,"test: failed to allocated shared heap object (%s)\n","object3");
fflush(stderr);
}
/* Display the current objects and clients */
(void)map_show(hdes,stderr);
(void)client_show(hdes,stderr);
#endif /* SUPPORT_SHARED_HEAPS */
/*-------------------------------------------------------------------------------------------------------------
This is the event loop of the embryo -- it may well interact with windowed applications such as
Xmt Widgets or X applications such as TK or file managers ...
-------------------------------------------------------------------------------------------------------------*/
fprintf(stderr,"\n %s (%d@%s) is waiting to be allocated an application\n\n",
appl_name,getpid(),appl_host);
fflush(stderr);
while(1)
{ char strdum[256];
unsigned long ldum;
int i,
idum;
#ifdef SUPPORT_SHARED_HEAPS
/* Update shared heap object "object1" on heap "heap1" */
/* Lock "object1" and return a (local) pointer to it */
h_ptr_1 = msm_lockobjectname(hdes,F_LOCK,"object1",READWRITE);
/* Update "object1" */
(void)sscanf(h_ptr_1,"%s %s %s %s %s %d",
strdum,strdum,strdum,strdum,strdum,&cnt);
(void)sprintf(h_ptr_1,"[0x%x] %s [%d@%s] cnt is %d!",
(unsigned long)h_ptr_1,appl_name,appl_pid,appl_host,++cnt);
fprintf(stderr,"%s\n",h_ptr_1);
fflush(stderr);
(void)usleep(100);
/* Unlock "object1" so other clients can access it */
(void)msm_lockobjectname(hdes,F_ULOCK,"object1",READWRITE);
#else
(void)usleep(100);
#endif /* SUPPORT_SHARED_HEAPS */
}
/* Exit from PUPS/PSRP application cleaning up any mess it may have created */
pups_exit(0);
}
/*-------------------------------------------------------------------------------------------------------------
Simple test function to exercise vairous psrp functions ...
-------------------------------------------------------------------------------------------------------------*/
_PRIVATE int static_test_function_object(int argc, char *argv[])
{ int i,
init,
ptr,
ret_code;
char command[256],
item[256];
FILE *pipestream = (FILE *)NULL;
#ifdef PSRP_AUTHENTICATE
if(strin(argv[1],"^") == TRUE && pups_check_pass_set() == FALSE)
{ fprintf(psrp_out,"testfps: authentication failure\n");
fflush(psrp_out);
return(PSRP_OK);
}
#endif
if(argc < 2)
{ fprintf(psrp_out,"usage: testfps <pipestream>\n");
fflush(psrp_out);
return(PSRP_OK);
}
(void)strcpy(command,"");
for(i=1; i<argc; ++i)
{ (void)strcat(command,argv[i]);
(void)strcat(command," ");
}
if((pipestream = xfopen(command,"r",TRUE)) == (FILE *)NULL)
{ fprintf(psrp_out,"testfps: failed to open pipestream \"%s\"\n",command);
fflush(psrp_out);
return(PSRP_OK);
}
(void)psrp_set_client_exitf(c_client,"testfps_client",&testfps_exitf);
(void)set_ftab_id(fileno(pipestream),c_client);
/* Loop to extract data from pipestream */
do { xfgets(item,256,pipestream);
if(feof(pipestream) == 0)
{ fprintf(psrp_out,"%s\n",item);
fflush(psrp_out);
}
} while(feof(pipestream) == 0);
(void)xfclose(pipestream);
return(PSRP_OK);
}
/*--------------------------------------------------------------------------------------------------------------
Test function to send stream of ASDII text to PSRP client process ...
--------------------------------------------------------------------------------------------------------------*/
_PRIVATE int ascii(int argc, char *argv[])
{ int cnt = 0;
sigset_t set,
old_set;
while(1)
{ fprintf(stderr,"in ASCII (%d)\n",cnt);
fflush(stderr);
/*
fprintf(psrp_out,psrp_client_pid,psrp_chbrk_handler,"ASCII text (%d)\n",cnt);
*/
fprintf(psrp_out,"ASCII text (%d)\n",cnt);
fflush(psrp_out);
sleep(1);
sigprocmask(SIG_UNBLOCK,&old_set,NULL);
++cnt;
(void)usleep(100);
}
}