home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
NMPIPE.ZIP
/
CLIENT.C
next >
Wrap
Text File
|
1992-03-07
|
9KB
|
186 lines
#include "nmpipe.h"
/* */
/* */
/* Sample Named Pipe Application: */
/* */
/* Server supports MULTIPLE instances of the same pipe */
/* so that multiple clients can call in at any time. */
/* */
/* The Server uses the Named Pipe System Semiphore to */
/* manage input stream records. */
/* */
/* The Server writes the each incoming client, the data collection */
/* interval upon client callin. */
/* After that, the client will calibrate itself, and then begin */
/* sending records to the server. As the server can change the */
/* collection interval dynamically, the server will examine */
/* the Interval field of the input record, and if the returned */
/* Interval does NOT match the current server setup, the */
/* Server will write, in duplex, the current collection interval */
/* to the client for the next cycle. */
/* */
/* Therefore this is a DUPLEX pipe, and the client MUST have a */
/* read thread outstanding at all times. */
/* */
HSEM SemHandle;
HFILE FileHandle;
HPIPE PipeHandle;
BOOL running=TRUE;
BOOL Calibrating=TRUE;
VOID ReadThread(PVOID);
VOID IdleThread(PVOID);
main(int argc, char *argv[], char *envp[])
{
char RealPipeName[132]; /* work variables */
ULONG Action,BytesWritten,BytesRead;
APIRET rc;
// struct wksta_info_10 *p;
BOOL FirstSample=TRUE; /* set first sample flag */
//NetWkstaGetInfo(Here,10,(PBYTE)NULL,0,&BufSize); // get size of info
//p=(struct wksta_info_10 *)malloc(BufSize); // allocate buffer
//NetWkstaGetInfo(Here,10,(PBYTE)p,BufSize,&BufSize); // get info
//strcpy(inforec.computername,p->wki10_computername); // copy computer name
//free((char *)p); // free the buffer
/* as this is the client end of this application */
/* the pipe COULD be remote, as such the server */
/* is passed as an argument if it is remote */
/* we have to build the name correctly if we are */
/* remote. The name is \\SERVER\PIPE\NAME.EXT */
sprintf(RealPipeName,"%s%s%s",
argc==2?"\\\\":"",
argc==2?strupr(argv[1]):"",
PipeName);
printf("Pipe is %s\n", RealPipeName); /* print derived pipe name */
for(PipeHandle=(HPIPE)NULL; !PipeHandle; ) /* forever loop until pipe open */
{
/* open the pipe now */
rc=DosOpen(RealPipeName,&PipeHandle,&Action,0L,FILE_NORMAL,
OPEN_ACTION_OPEN_IF_EXISTS,OPEN_ACCESS_READWRITE|OPEN_SHARE_DENYNONE,0L);
if(rc==ERROR_PATH_NOT_FOUND) /* if server not started */
DosSleep(WaitForPipe); /* wait a bit */
else if(rc==ERROR_PIPE_BUSY) /* if no free instance */
rc=DosWaitNPipe(RealPipeName,SEM_INDEFINITE_WAIT); /* wait for one */
} /* end for */
/* pipe is open, get the current Interval fromthe server */
rc=DosRead(PipeHandle,(PBYTE)&inforec.Interval,Client_ReadSize,&BytesRead);
_beginthread(ReadThread,NULL,StackSize,NULL); /* start thread */
/* set this thread to time critical, max. */
/* 1. so calibarte/idle thread inherits the same prty */
/* 2. When we wake up after the Interval, we DON'T want */
/* the then idle thread to get any cpu time, that way */
/* its counters can't get damaged */
DosSetPrty(PRTYS_THREAD,PRTYC_TIMECRITICAL,+31,0);
DosSleep(0L); /* give up our timeslice so we get a clean one */
_beginthread(IdleThread,NULL,StackSize,NULL); /* start it */
DosSleep(CalibrateTime); /* sleep thru calibrate cycle */
DosEnterCritSec(); /* don't let idle thread start yet */
Calibrating=FALSE; /* turn off the calibrate cycle */
DosExitCritSec(); /* ok, done with calibrate */
DosQuerySysInfo(QSV_MS_COUNT,QSV_MS_COUNT,&inforec.last_msecs,sizeof(inforec.last_msecs));
while (running) /* while we are processing */
{
/* sleep for the requested interval */
/* the idle thread is counting now */
DosSleep(inforec.Interval); /* when it can */
DosQuerySysInfo(QSV_MS_COUNT,QSV_MS_COUNT,&inforec.current_msecs,sizeof(inforec.current_msecs));
/* calculate idle count since last time */
inforec.current = inforec.counter - inforec.last;
inforec.last = inforec.counter; /* set last tick seen */
/* milliseconds elased */
inforec.delta_msec = inforec.current_msecs - inforec.last_msecs;
/* save last time for next cycle */
inforec.last_msecs = inforec.current_msecs;
if (running) /* still running ? */
{
if(!FirstSample) /* ignore the first sample data */
{
/* send this info to the server */
rc=DosWrite(PipeHandle,(PBYTE)&inforec,Client_WriteSize,&BytesWritten);
if(rc==ERROR_BROKEN_PIPE) /* woops, server ended already */
running=FALSE; /* we are done */
}
FirstSample=FALSE; /* set not first sample */
} /* endif */
} /* endwhile */
DosEnterCritSec(); /* no thread switching */
DosClose(PipeHandle); /* close the pipe */
PipeHandle=(HPIPE)NULL; /* clear the handle */
DosExitCritSec(); /* thread switching back on */
}
VOID ReadThread(PVOID f)
{
ULONG rc,BytesRead; /* work variables */
while( PipeHandle ) /* loop while pipe open */
{
/* read changed Interval time */
rc=DosRead(PipeHandle,(PBYTE)&inforec.Interval,Client_ReadSize,&BytesRead);
if(rc==ERROR_BROKEN_PIPE) /* woops, server went away on us */
running=FALSE; /* lets stop this loop */
}
DosExit(EXIT_THREAD,0); /* end this thread now */
}
void IdleThread(PVOID f)
{
ULONG CStart_ms;
/* when this thread gets control it is Time Critical, Max, and */
/* is expected to calibrate the MAX count possible on this CPU */
/* this value will be used later to calculate the actual CPU */
/* busy values, collected from the second half of this thread */
DosSleep(0L); /* give up our timeslice so we get a clean one */
DosQuerySysInfo(QSV_MS_COUNT,QSV_MS_COUNT,&CStart_ms,sizeof(CStart_ms));
while(Calibrating) /* loop while still calibrating */
inforec.base++; /* count again */
DosQuerySysInfo(QSV_MS_COUNT,QSV_MS_COUNT,&inforec.base_msecs,sizeof(inforec.base_msecs));
inforec.base_msecs -= CStart_ms; /* elasped milliseconds calibration*/
/* calibration has completed, now lets us play cpu busy counter */
/* set this thread to lost prty, Idle class, bottom */
/* we will get cpu ONLY when there is NOTHING else to do */
/* given we know how much NOTHING we did, we can figure out */
/* how much something was done */
DosSetPrty(PRTYS_THREAD,PRTYC_IDLETIME,-31,0);
while (running) /* still collecting? */
inforec.counter++; /* count again */
DosExit(EXIT_THREAD,0); /* end this thread now */
}