home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
NMPIPE.ZIP
/
SERVER.C
< prev
Wrap
Text File
|
1992-03-07
|
10KB
|
202 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. */
/* */
HEV SemHandle;
HFILE FileHandle;
ULONG Instance;
VOID ReadThread(PVOID);
main(int argc, char *argv[], char *envp[])
{
HPIPE PipeHandle; /* Pipe Handle value, per instance */
ULONG rc,BytesWritten; /* work values */
inforec.Interval=CalibrateTime; /* initial collection interval, in ms. */
/* create the system semaphore */
rc=DosCreateEventSem(SemName, /* name */
&SemHandle, /* handle on output */
DC_SEM_SHARED, /* MUST be public for sub thread to use it */
FALSE); /* System Semaphore name */
_beginthread(ReadThread,NULL,StackSize,NULL); /* start thread */
for( ; ; ) /* do forever loop */
{
/* make a named pipe or a new instance>first */
rc=DosCreateNPipe(PipeName, /* name */
&PipeHandle, /* handle on output */
NP_ACCESS_DUPLEX, /* Duplex pipe, no constant defined */
/* read and write messages */
/* unlimited instance count */
NP_WMESG | NP_RMESG | NP_ICOUNT,
/* write message buffer size */
/* don't forget message length size */
Server_WriteSize+PipeMsgHdr,
/* read message buffer size */
/* don't forget message length size */
Server_ReadSize+PipeMsgHdr,
/* client will wait indefinately for */
/* server to issue DosConnectNmPipe */
SEM_INDEFINITE_WAIT);
/* pipe was created, so attach the */
/* semaphore to it */
/* all handles will have the SAME */
/* semaphore, so we can use QNmSemState */
/* set the unique identifier to the */
/* instance handle so we can use it later */
/* to read/write from/to the client */
rc=DosSetNPipeSem(PipeHandle,(HSEM)SemHandle,PipeHandle);
DosConnectNPipe(PipeHandle); /* now wait for client to call */
Instance++; /* client has called, so count instance */
/* write collection interval to new client now */
DosWrite(PipeHandle,&inforec.Interval,Server_WriteSize,&BytesWritten);
} /* end for */
}
/* */
/* This is the main processing thread. It Waits on the System Semaphore */
/* then issues the DosQNmPipeSemState to get the status records for ANY */
/* instances that may have written data to the server. */
/* */
/* */
/* */
/* */
/* */
VOID ReadThread(PVOID f)
{
PIREC Pirec; /* incoming data record pointer */
ULONG Bufsize,Iwork,BytesRead,rc,qrc,BytesWritten; /* work variables */
PPIPESEMSTATE NmPipeData,NpDataEnd,Buffer; /* status record pointers */
HPIPE PipeHandle; /* handle of pipe being processed */
ULONG AdjBaseCount,PostCount; /* normalized base count */
#define NpssSize sizeof(PIPESEMSTATE) /* size of Named Pipe status record */
for(; ; ) /* forever loop */
{
/* wait for semaphore to be cleared */
DosWaitEventSem(SemHandle,SEM_INDEFINITE_WAIT);
DosResetEventSem(SemHandle,&PostCount); /* reset semaphore for next wait */
while(1) /* processing loop */
{
/* allocate a buffer for the status records */
/* room for number of instances + 1 */
/* for end of records, record */
Bufsize=(Iwork=Instance+1)*NpssSize;
NmPipeData=Buffer=(PPIPESEMSTATE)malloc(Bufsize);
/* get the status records now */
qrc=DosQueryNPipeSemState((HSEM)SemHandle, NmPipeData, Bufsize);
for( NpDataEnd=NmPipeData+Iwork; /* loop thru the records */
NmPipeData<NpDataEnd; /* while there are some */
NmPipeData++) /* point to next record */
{
/* get the key value, which is the pipe handle */
PipeHandle=(HPIPE)NmPipeData->usKey;
switch(NmPipeData->fStatus) /* process based on status */
{
case NPSS_EOI : /* no more status records */
NmPipeData=NpDataEnd;
break;
case NPSS_WSPACE: /* write space is available */
/* since we don't care, we ignore`it */
break;
case NPSS_RDATA : /* inbound data from a client */
/* allocate buffer for data */
/* SHOULD check via DosQNmPipeInfo */
/* but we KNOW how big they SHOULD be */
Pirec=(PIREC)malloc(Server_ReadSize);
/* read a message */
rc=DosRead(PipeHandle,(PBYTE)Pirec,Server_ReadSize,&BytesRead);
/* does client Interval match Server? */
if(Pirec->Interval!=inforec.Interval) /* if not, tell client */
/* write new Interval to client */
rc=DosWrite(PipeHandle,(PBYTE)&inforec.Interval,Server_WriteSize,&BytesWritten);
/* use the data just enough to */
/* report on the client CPU busy state */
AdjBaseCount=(Pirec->base/Pirec->base_msecs)*Pirec->delta_msec;
if(AdjBaseCount<Pirec->current)
Pirec->current=AdjBaseCount;
printf("Busy=%ld Base=%ld Count=%ld elapsed_ms=%ld Base_ms=%ld\n",
(ULONG)(((AdjBaseCount-Pirec->current)*100L)/AdjBaseCount),
// Pirec->base,Pirec->current, Pirec->delta_msec,Pirec->base_msecs);
AdjBaseCount,Pirec->current, Pirec->delta_msec,Pirec->base_msecs);
free((char *)Pirec); /* free the receive buffer */
break;
case NPSS_CLOSE : /* client closed its end of the pipe */
/* close server end as well */
DosClose((HFILE)NmPipeData->usKey);
Instance--; /* reduce active instance count */
break;
default: /* should not occur */
/* but we process anyway */
printf("Unknown Pipe State=%d\n",NmPipeData->fStatus);
break;
} /* end switch */
} /* end for */
free((char *)Buffer); /* free status record buffer */
/* there is the possibility that even tho we think we allocated */
/* enough room for all active client status records, that the */
/* write space available records (cause we wrote out an interval*/
/* record) might not fit in the buffer */
/* in this case we do NOT want to wait on the semaphore again */
/* but just go get the records now */
if (qrc==NO_ERROR)
break;
}
} /* end forever loop */
}