home *** CD-ROM | disk | FTP | other *** search
- /*==============================================================*\
- * Svrpthrd.c - pipe processing routine: initialization and
- * and message display threads.
- *
- * Copyright 1992, IBM Corp.
- *
- * DISCLAIMER OF WARRANTIES. The following [enclosed] code is
- * sample code created by IBM Corporation. This sample code is not
- * part of any standard or IBM product and is provided to you solely
- * for the purpose of assisting you in the development of your
- * applications. The code is provided "AS IS", without
- * warranty of any kind. IBM shall not be liable for any damages
- * arising out of your use of the sample code, even if they have been
- * advised of the possibility of such damages. *
- *
- *
- \*==============================================================*/
-
-
- #define INCL_DOSPROCESS
- #define INCL_DOSNMPIPES
- #define INCL_DOSSEMAPHORES
- #define INCL_DOSMEMMGR
- #define INCL_WINMESSAGEMGR
- #define INCL_DOSERRORS
- #define INCL_DOSFILEMGR
-
- #include <os2.h>
-
- #include <stddef.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdio.h>
-
- #include "svrpglbl.h"
- #include "svrpmain.h"
- #include "svrpxtrn.h"
- #include "namepipe.h"
-
-
- #define STACKSIZE 8192
-
-
- HEV hevMsgRcvd; /* event semaphore for displaying pipe messages */
- HPIPE hpStartPipe; /* handle to pipe through which start requests are made */
-
-
- /* setup and start threads to manage pipes */
- HPIPE InitThreads()
- {
- BOOL fSuccess=FALSE;
- ULONG ulErrorMsg=0;
-
- if ((BOOL)DosCreateEventSem(NULL, &hevMsgRcvd, 0L, FALSE))
- {
- ulErrorMsg = IDMSG_CREATE_SEM_FAILED;
- }
-
- else if((BOOL)DosCreateNPipe(START_PIPE_NAME,
- &hpStartPipe,
- FS_SVR_STARTPIPE_OPEN_MODE,
- FS_SVR_STARTPIPE_PIPE_MODE,
- sizeof(PIPE_MSG)*3,
- sizeof(PIPE_MSG)*3,
- PIPE_TIMEOUT))
- {
- ulErrorMsg = IDMSG_CREATE_PIPE_FAILED;
- }
-
- else if (0 > _beginthread(DisplayPipeMsg,
- NULL,
- STACKSIZE,
- NULL))
- {
- ulErrorMsg = IDMSG_CREATE_THREAD_FAILED;
- }
-
- else if (0 > _beginthread(ConnectPlayer,
- NULL,
- STACKSIZE,
- NULL))
- {
- ulErrorMsg = IDMSG_CREATE_THREAD_FAILED;
- }
-
- else
- {
- fSuccess = TRUE;
- }
-
- if (!fSuccess)
- {
- MessageBox(hwndMain, ulErrorMsg, MB_OK | MB_ERROR, TRUE);
- hpStartPipe = (HPIPE)0; /* TEST CODE */
- }
-
- return (hpStartPipe); /* TEST CODE */
- }
-
-
- VOID ConnectPlayer(VOID *dummy)
- {
- USHORT usMsgType, usErrorMsg=0;
- HPIPE hpGamePipe[2]; /* buffer pipe handles */
- BOOL fExit=FALSE;
- int iPipeIndex=0;
- APIRET apirc;
-
- while (!fAppExit && /* test for end before */
- !fExit &&
- !(BOOL)(apirc=DosConnectNPipe(hpStartPipe)) && /* wait to connect next player */
- !fAppExit) /* and after waiting */
- {
- usMsgType = ERROR_MSG;
-
- if ((BOOL)DosCreateNPipe(GAME_PIPE_NAME, /* create pipe for next player */
- &hpGamePipe[iPipeIndex],
- FS_SVR_GAMEPIPE_OPEN_MODE,
- FS_SVR_GAMEPIPE_PIPE_MODE,
- sizeof(PIPE_MSG)*3,
- sizeof(PIPE_MSG)*3,
- PIPE_TIMEOUT))
- {
- usErrorMsg = IDMSG_CREATE_PIPE_FAILED;
- }
-
- else if (0 > _beginthread(GameThread, /* begin game thread */
- NULL,
- STACKSIZE,
- (VOID *)&hpGamePipe[iPipeIndex]))
- {
- usErrorMsg = IDMSG_CREATE_THREAD_FAILED;
- DosClose(hpGamePipe[iPipeIndex]); /* close the created pipe */
- }
-
- else
- {
- usMsgType = START_MSG;
- }
-
- /* write start message to client, if we have an error, notify him */
- /* and close pipe, 'cause we could care less about him now */
- if ((BOOL)Pipe_IO(SERVER, hpStartPipe, &usMsgType, &usErrorMsg, 0) &&
- usMsgType != ERROR_MSG)
- {
- usErrorMsg = IDMSG_PIPE_WRITE_FAILED;
- }
-
- /* read confirmation from client. if he has an error, this is how he notifies us */
- else if ((BOOL)Pipe_IO(CLIENT, hpStartPipe, &usMsgType, &usErrorMsg, 0))
- {
- usErrorMsg = IDMSG_PIPE_READ_FAILED;
- }
-
- else if (ERROR_MSG == usMsgType) /* the client cannot use the game pipe */
- {
- /* notify the thread here. We can write to its pipe like
- we were the client and tell it of a fatal error condition. */
- if (Pipe_IO(SERVER, hpGamePipe[iPipeIndex], &usMsgType, &usErrorMsg, 0))
- {
- /* if we cannot talk to the thread, we are in deep doo-doo, as the
- next client might try to grab the same busted pipe. Disconnect
- it, hope for the best, and let the game thread do what it will */
- DosDisConnectNPipe(hpGamePipe[iPipeIndex]);
- DosClose(hpGamePipe[iPipeIndex]);
- }
- }
-
- else
- {
- iPipeIndex = 1 - iPipeIndex; /* flip index value */
- }
-
- if ((BOOL)DosDisConnectNPipe(hpStartPipe)) /* disconnect start pipe */
- {
- usErrorMsg = IDMSG_START_PIPE_ERROR;
- fExit = TRUE;
- }
-
- if ((BOOL)usErrorMsg)
- {
- WinPostMsg(hwndMain, WM_MSG, MPFROMLONG(usErrorMsg), MPVOID);
- usErrorMsg = 0;
- }
- }
-
- /* if the connect bombed, and not because we closed the pipe on it... */
- if (!fAppExit)
- {
- WinPostMsg(hwndMain, WM_MSG, MPFROMLONG(IDMSG_CONNECT_FAILED), MPVOID);
- WinPostMsg(hwndMain, WM_COMMAND, MPFROMLONG(IDM_FILEEXIT), MPVOID);
- fAppExit = TRUE;
- }
-
- DosPostEventSem(hevMsgRcvd); /* notify DisplayPipeMsg */
- DosClose(hpGamePipe[0]); /* close what you can in case */
- DosClose(hpGamePipe[1]); /* the game thread can't. */
- fThrdsDead = TRUE; /* outta here... */
- }
-
-
- #define BUFFSIZE 10
-
- /* buffer for pipe messages to be formatted and displayed */
- struct
- {
- BOOL fServer;
- ULONG ulID;
- PIPE_MSG pmsgMsg;
- CHAR pszMsgString[MESSAGE_LEN];
- }
- stMsgBuff[BUFFSIZE];
-
-
- /* Write or read to given pipe and write message to display buffer.
- */
- APIRET Pipe_IO(BOOL fServer, HPIPE hpPipe, USHORT *usType, USHORT *usData, ULONG ulID)
- {
- static int iMsgIndex=0;
- PIPE_MSG pmsgPipeMsg;
- APIRET apiRC;
- ULONG ulCount;
-
- if (fServer) /* outgoing, from the server */
- {
- pmsgPipeMsg.usMsgType = *usType;
- pmsgPipeMsg.usMsgData = *usData;
- apiRC = DosWrite(hpPipe, (VOID *)&pmsgPipeMsg, sizeof(PIPE_MSG), &ulCount);
-
- DosEnterCritSec(); /* the update to the message buffer should be atomic */
-
- stMsgBuff[iMsgIndex].fServer = fServer;
- stMsgBuff[iMsgIndex].pmsgMsg.usMsgType = *usType;
- stMsgBuff[iMsgIndex].pmsgMsg.usMsgData = *usData;
- stMsgBuff[iMsgIndex].ulID = ulID;
- iMsgIndex = (iMsgIndex < BUFFSIZE-1) ? iMsgIndex+1 : 0;
-
- DosExitCritSec();
-
- DosPostEventSem(hevMsgRcvd); /* tell displaypipemsg() to display */
- }
-
- else if(!(apiRC = DosRead(hpPipe, (VOID *)&pmsgPipeMsg, sizeof(PIPE_MSG), &ulCount))
- && ulCount > 0)
- {
- *usType = pmsgPipeMsg.usMsgType;
- *usData = pmsgPipeMsg.usMsgData;
-
- DosEnterCritSec();
-
- stMsgBuff[iMsgIndex].fServer = fServer;
- stMsgBuff[iMsgIndex].pmsgMsg.usMsgType = *usType;
- stMsgBuff[iMsgIndex].pmsgMsg.usMsgData = *usData;
- stMsgBuff[iMsgIndex].ulID = ulID;
- iMsgIndex = (iMsgIndex < BUFFSIZE-1) ? iMsgIndex+1 : 0;
-
- DosExitCritSec();
-
- DosPostEventSem(hevMsgRcvd);
- }
-
- /* DosRead returns an error code of 0 and 0 bytes read with a broken pipe */
-
- else if (0 == ulCount)
- {
- apiRC = ERROR_BROKEN_PIPE;
- }
-
- return(apiRC);
- }
-
-
- VOID DisplayPipeMsg(VOID *dummy)
- {
- ULONG ulPosts;
- static int iMsgIndex=0;
- CHAR *pszSender, *pszType;
-
- while (!DosWaitEventSem(hevMsgRcvd, SEM_INDEFINITE_WAIT) &&
- !fAppExit)
- {
- DosResetEventSem(hevMsgRcvd, &ulPosts);
- while (ulPosts-- > 0) /* format all of the messages posted */
- {
- /* format pipe message here */
- if (stMsgBuff[iMsgIndex].fServer)
- {
- pszSender = "SERVER";
- }
-
- else
- {
- pszSender = "CLIENT";
- }
-
- switch (stMsgBuff[iMsgIndex].pmsgMsg.usMsgType)
- {
- case START_MSG:
- pszType = START_MSG_TEXT;
- break;
-
- case CLIENT_MOVE:
- pszType = CLIENT_MOVE_TEXT;
- break;
-
- case YOU_FIRST:
- pszType = YOU_FIRST_TEXT;
- break;
-
- case ERROR_MSG:
- pszType = ERROR_MSG_TEXT;
- break;
-
- case CLIENT_QUIT:
- pszType = CLIENT_QUIT_TEXT;
- break;
-
- case WIN_CLIENT:
- pszType = WIN_CLIENT_TEXT;
- break;
-
- case WIN_SERVER:
- pszType = WIN_SERVER_TEXT;
- break;
-
- case SERVER_MOVE:
- pszType = SERVER_MOVE_TEXT;
- break;
-
- case WIN_DRAW:
- pszType = WIN_DRAW_TEXT;
- break;
-
- default:
- pszType = "UNKNOWN";
- }
-
- /* format the text of the message */
- sprintf(stMsgBuff[iMsgIndex].pszMsgString, "Thread %03u, %s Message: %s: %u", stMsgBuff[iMsgIndex].ulID, pszSender, pszType, stMsgBuff[iMsgIndex].pmsgMsg.usMsgData);
-
- /* post pointer to said message to the PM thread */
- WinPostMsg(hwndMain, WM_PIPEMSG, MPFROMP(stMsgBuff[iMsgIndex].pszMsgString), MPVOID);
-
- /* increment circular list index */
- iMsgIndex = (iMsgIndex < BUFFSIZE-1) ? iMsgIndex+1 : 0;
- }
- }
-
- DosCloseEventSem(hevMsgRcvd);
- }
-