Sample DCE/Motif/Threads program
/*
** From: ruddock@mwblan.bellcore.com (David Ruddock)
** The program accepts CDS names as arguments, creates a label/value
** window for each CDS name, creates a thread to "monitor" each
** cds entry and reports on the number of RPCs received by the server
** being monitored in the respective X/11 window.
**
** There is little/no error checking done since the point of the
** program is to demonstrate threads and X/11 working together.
** So, the whole thing crashes and burns at the first hint of trouble.
**
** There are many other things that can be done for server monitoring
** and reporting. But I wanted to keep the example simple.
** Dave
**
*/
/*
** Sample make rules (for Solaris 5.5.1):
** INCLUDES= -I/usr/dt/share/include -I/usr/openwin/share/include
** LIBS=-ldce -lpthread -lm
** CFLAGS=-D_TIMESPEC_T_ -D_REENTRANT -g $(INCLUDES)
** mtperf: mtperf.c
** cc $(CFLAGS) -o mtperf mtperf.c $(LIBS) -lXm -lXt -lX11 -lgen
*/
/************************* mtperf.c ***************************/
/* X include files */
#include <Xm/LabelG.h>
#include <Xm/RowColumn.h>
#include <Xm/Text.h>
/* DCE include files */
#include <stdio.h>
#include <dce/rpc.h>
#include <dce/pthread.h>
/* application defines, prototypes, etc */
struct server_info {
int RPCs_In;
int RPCs_Out;
int Pkts_In;
int Pkts_Out;
int GUI_fd;
Widget this_widget;
char *CDSname;
} Info[10];
void DoMonitor( struct server_info * );
void ShowCB( Widget, XtPointer, XmPushButtonCallbackStruct *);
/* main processing */
int pipe_channel[2];
main(int argc, char **argv )
{
Widget toplevel, rowcol;
XtAppContext application;
int ctr;
pthread_t thread_id[10];
pipe(pipe_channel);
toplevel = XtVaAppInitialize( &application, "Simple DCE X based monitor",
(XrmOptionDescList) NULL, 0, &argc, argv,
NULL, NULL, NULL);
rowcol = XtVaCreateWidget("rowcol",
xmRowColumnWidgetClass, toplevel,
XmNpacking, XmPACK_COLUMN,
XmNnumColumns, argc -1,
XmNorientation, XmHORIZONTAL,
XmNentryAlignment, XmALIGNMENT_END,
XmNisAligned, True,
NULL);
for ( ctr = 1; ctr <= argc - 1; ctr ++ ) {
XtVaCreateManagedWidget( argv[ctr],
xmLabelGadgetClass, rowcol,
NULL);
Info[ctr - 1].this_widget =
XtVaCreateManagedWidget( argv[ctr],
xmTextWidgetClass, rowcol,
NULL);
Info[ctr - 1].GUI_fd = pipe_channel[1]; /* write end */
Info[ctr - 1].CDSname = argv[ctr];
if( pthread_create( &thread_id[ctr], pthread_attr_default,
(pthread_startroutine_t) DoMonitor,
&Info[ctr - 1]) != 0 ) {
perror("Oh darn!");
exit( 1 );
}
}
XtManageChild(rowcol);
XtRealizeWidget(toplevel);
XtAppAddInput(application, pipe_channel[0], XtInputReadMask, ShowCB, NULL);
XtAppMainLoop( application );
}
void
DoMonitor( struct server_info *info )
{
handle_t bh; /* Servers binding handle */
rpc_stats_vector_t *stats; /* Server performance stats */
error_status_t status; /* house keeping stuff */
uuid_t obj_uuid; /* Servers object UUID */
rpc_ns_handle_t obj_inq_context,
import_context;
rpc_ns_entry_object_inq_begin(
rpc_c_ns_syntax_default,
(unsigned_char_p_t) info->CDSname,
&obj_inq_context,
&status);
rpc_ns_entry_object_inq_next(
obj_inq_context,
&obj_uuid,
&status);
rpc_ns_entry_object_inq_done(&obj_inq_context, &status);
rpc_ns_binding_import_begin(
rpc_c_ns_syntax_default,
(unsigned_char_p_t) info->CDSname,
NULL,
&obj_uuid,
&import_context,
&status);
/* Import only the first binding */
rpc_ns_binding_import_next(import_context, &bh, &status);
rpc_mgmt_is_server_listening(bh, &status);
while( status == rpc_s_ok ) {
rpc_mgmt_inq_stats(bh, &stats, &status);
info->RPCs_In = stats->stats[rpc_c_stats_calls_in];
info->RPCs_Out = stats->stats[rpc_c_stats_calls_out];
info->Pkts_In = stats->stats[rpc_c_stats_pkts_in];
info->Pkts_Out = stats->stats[rpc_c_stats_pkts_out];
rpc_mgmt_stats_vector_free( &stats, &status);
if ( write(info->GUI_fd, &info, sizeof(struct server_info *)) != 4 ) {
fprintf(stderr,"Write failed!\n");
}
sleep(60);
}
pthread_exit(0);
}
void
ShowCB( Widget w, XtPointer client_data, XmPushButtonCallbackStruct * cbs)
{
struct server_info *ptr;
int length;
char text[200];
length = read(pipe_channel[0], &ptr, sizeof(struct server_info *));
if( length != sizeof(struct server_info *) ) {
fprintf(stderr,"Read failed!\n");
exit(-1);
}
else {
sprintf( text,"%d RPCs received", ptr->RPCs_In);
XmTextSetString(ptr->this_widget, text);
}
return;
}