?? tgiglob.c
字號:
/*
* Task Gateway Interface
* A. Montefusco
* June 10, 1995
*
*
*/
#pragma option -zR_SHAREDATA
#pragma option -zS_SHAREGROUP
#pragma option -zT_SHARECLASS
#include <string.h>
#ifdef _DEBUG
#include <stdio.h>
#endif
#define INCL_DOSSEMAPHORES
#define INCL_DOSPROCESS
#define INCL_DOSMEMMGR
#include <os2.h>
#include "debug.h"
#include "tgi.h"
#include "tgiglob.h"
/*
* Shared DLL variables
*
* Each task using the DLL shares these data
*/
int nClient = 0;
HMTX hGlobMutex = NULLHANDLE;
extern HMTX hLocMutex;
int nMod = 0;
TGI_MODULE modTab [MAX_MOD] = { "", 0, 0 };
int nInst = 0;
PROC_INSTANCE instTab [MAX_INST] = { 0, 0, 0, 0 };
static VOID APIENTRY _UnloadModule (void);
static void *_AllocTgiData (TGI_DATA *pData);
long _TgiRunning (void)
{
if (hGlobMutex == NULLHANDLE) {
return TGI_NOT_RUN;
} else {
return TGI_OK;
} /* endif */
}
long _LockData (void)
{
if (hGlobMutex == NULLHANDLE)
return TGI_NOT_RUN;
else {
APIRET krc;
if (hLocMutex == NULLHANDLE) {
hLocMutex = hGlobMutex;
krc = DosOpenMutexSem (NULL, &hLocMutex);
TRACE(fprintf (stderr, "DosOpenMutexSem: %d\n", krc););
if (krc)
return TGI_LOC_OPEN_SEM;
}
krc = DosRequestMutexSem (hLocMutex, SEM_INDEFINITE_WAIT);
TRACE(fprintf (stderr, "DosRequestMutexSem: %d\n", krc););
if (krc)
return TGI_REQUEST;
}
return TGI_OK;
}
long _UnLockData (void)
{
if (hGlobMutex == NULLHANDLE)
return TGI_NOT_RUN;
else {
if (DosReleaseMutexSem (hLocMutex)) return TGI_LOC_RELEASE_SEM;
}
return TGI_OK;
}
long _InitModule (void)
{
APIRET krc;
if (hGlobMutex == NULLHANDLE) {
int i;
krc = DosCreateMutexSem (0, &hGlobMutex, DC_SEM_SHARED, TRUE);
TRACE(fprintf (stderr, "DosCreateMutexSem: %d\n", krc););
// to simulate side effect of first missing _LockData in the server task
hLocMutex = hGlobMutex;
krc = DosOpenMutexSem (NULL, &hLocMutex);
TRACE(fprintf (stderr, "DosOpenMutexSem: %d\n", krc););
if (krc)
return TGI_LOC_OPEN_SEM;
// init all globals data here ....
for (i=0; i<MAX_MOD; ++i) {
modTab [i].szName[0] = '\0';
modTab [i].pNextInstance = NULL;
modTab [i].pFn = NULL;
} /* endfor */
/*
* Deinit module automatically
*/
DosExitList (EXLST_ADD, (PFNEXITLIST)_UnloadModule);
return _UnLockData ();
} else {
return TGI_ALREADY_INIT;
}
}
static VOID APIENTRY _UnloadModule (void)
{
if (hGlobMutex != NULLHANDLE) {
int i;
_LockData ();
// unlock all waiting instances
for (i=0; i<MAX_MOD; ++i)
if (modTab[i].szName[i] != '\0') {
PROC_INSTANCE *pInst = modTab [i].pNextInstance;
while (pInst != NULL) {
APIRET krc;
ULONG ulPostCt;
HEV hInst = pInst->hInstAva;
krc = DosOpenEventSem (NULL, &hInst);
TRACE(fprintf (stderr, "DosOpenEventSem: %d\n", krc););
krc = DosPostEventSem (hInst);
TRACE(fprintf (stderr, "DosPostEventSem: %d\n", krc););
krc = DosCloseEventSem (hInst);
TRACE(fprintf (stderr, "DosCloseEventSem: %d\n", krc););
pInst = pInst->pNext;
}
}
DosEnterCritSec ();
DosReleaseMutexSem (hGlobMutex);
DosCloseMutexSem (hGlobMutex);
hGlobMutex = NULLHANDLE;
DosExitCritSec ();
} /* endif */
}
/*
* Module table management
*
*/
TGI_MODULE * _GetFreeMod (void)
{
int i;
for (i=0; i<MAX_MOD; ++i)
if (modTab [i].szName[0] == '\0') {
modTab [i].pNextInstance = NULL;
modTab [i].pFn = NULL;
nMod++;
return &(modTab [i]);
}
return NULL;
}
/*
* Instance list is scanned and all instaces are freed
*/
long _DeleteMod (TGI_MODULE *pMod)
{
int i;
for (i=0; i<MAX_MOD; ++i)
if (pMod == &(modTab [i])) {
PROC_INSTANCE *pInst = modTab [i].pNextInstance;
while (pInst != NULL) {
PROC_INSTANCE *pTmp = pInst->pNext;
_DeleteInst (pInst) ;
pInst = pTmp;
}
modTab[i].szName[i] = '\0';
modTab [i].pNextInstance = NULL;
modTab [i].pFn = NULL;
nMod--;
return TGI_OK;
}
return TGI_MOD_NOT_FOUND;
}
/*
* search in module table for pszName
*/
long _SearchModule (char *pszName, TGI_MODULE **ppMod)
{
int i;
for (i=0; i<MAX_MOD; ++i)
if (!strcmp(modTab[i].szName, pszName)) {
if (ppMod) *ppMod = &(modTab [i]);
return TGI_OK;
}
if (ppMod) *ppMod = NULL;
return TGI_MOD_NOT_FOUND;
}
/*
* Instance table management
*
*/
PROC_INSTANCE * _GetFreeInst (void)
{
int i;
for (i=0; i<MAX_INST; ++i)
if (instTab [i].hInstAva == 0) {
memset (&(instTab [i]), 0, sizeof(instTab [i]));
nInst++;
return &(instTab [i]);
}
return NULL;
}
long _DeleteInst (PROC_INSTANCE *pInst)
{
int i;
for (i=0; i<MAX_INST; ++i)
if (pInst == &(instTab [i])) {
memset (&(instTab [i]), 0, sizeof(instTab [i]));
nInst--;
return TGI_OK;
}
return TGI_INST_NOT_FOUND;
}
/*
* Used by server to unlock a instance
*
*/
long _UnlockModuleInstance (char *pszName, TGI_DATA *pData)
{
long rc;
TGI_MODULE *pMod;
_LockData ();
TRACE(fprintf (stderr, "_UnlockModuleInstance: accessing to global data\n"););
if ((rc = _SearchModule (pszName, &pMod)) == TGI_OK) {
/*
* module found
* search a free instance down to the list
*/
PROC_INSTANCE *pInst = pMod->pNextInstance ;
void *pShrMem = _AllocTgiData (pData) ;
if (pShrMem != NULL) {
rc = TGI_MODULE_BUSY;
while (pInst != NULL) {
APIRET krc;
ULONG ulPostCt;
HEV hInst = pInst->hInstAva;
krc = DosOpenEventSem (NULL, &hInst);
TRACE(fprintf (stderr, "DosOpenEventSem: %d\n", krc););
krc = DosQueryEventSem (hInst, &ulPostCt);
TRACE(fprintf (stderr, "DosQueryEventSem: %d\n", krc););
if ((krc == 0) && (ulPostCt == 0)) {
HMBX hMbx;
unsigned int msgLen;
// create a mailbox for callback data
sprintf (pInst->szMbxName, "%p", pInst);
MbxCreate (pInst->szMbxName, Local, &hMbx);
// initialize pointer to shared memory object
// that contains callback data
pInst->pTgiData = (TGI_DATA *) pShrMem;
// create instance termination semaphore
pInst->hInstEnded = NULLHANDLE;
DosCreateEventSem (NULL, &(pInst->hInstEnded),
DC_SEM_SHARED, FALSE);
// unlock client thread
_UnLockData ();
krc = DosPostEventSem (hInst);
TRACE(fprintf (stderr, "DosPostEventSem: %d\n", krc););
// extract data from the queue
// and send them to client
for (;;) {
char buf [MAX_BIF_LEN];
msgLen = sizeof(buf);
if ( (MbxGetMsg (hMbx, buf, &msgLen) == MLBX_OK)
&& (msgLen != 0)
&& (pData->pSrvFn != NULL) ) {
pData->pSrvFn (buf, msgLen, pData->pSrvCbData);
} else
break;
}
MbxClose (hMbx);
_LockData ();
// wait for the external routine termination
if (!krc)
DosWaitEventSem (pInst->hInstEnded, SEM_INDEFINITE_WAIT);
DosCloseEventSem (pInst->hInstEnded);
pInst = NULL;
rc = TGI_OK;
} else {
pInst = pInst->pNext;
} /* endif */
krc = DosCloseEventSem (hInst);
TRACE(fprintf (stderr, "DosCloseEventSem: %d\n", krc););
}
DosFreeMem (pShrMem);
} else {
rc = TGI_NO_MEM;
} /* endif */
}
_UnLockData ();
return rc;
}
/*
* Used by server to built a shared memory block initialized with
* request's data
*/
void *_AllocTgiData (TGI_DATA *pData)
{
int len = sizeof (TGI_DATA) +
strlen (pData->pszPathInfo ) + 1 +
strlen (pData->pszQueryInfo) + 1 +
strlen (pData->pszFormData ) + 1 +
strlen (pData->pszRedirFile) + 1 ;
void *pMem;
APIRET krc = DosAllocSharedMem (&pMem, NULL, len, PAG_COMMIT |
OBJ_GETTABLE |
PAG_READ |
PAG_WRITE
);
TRACE(fprintf (stderr, "DosAllocSharedMem: %d\n", krc););
if (!krc) {
TGI_DATA *pNew = (TGI_DATA *) pMem;
pNew->pszPathInfo = (char *)pMem + sizeof(TGI_DATA);
pNew->pszQueryInfo = pNew->pszPathInfo + strlen (pData->pszPathInfo) + 1;
pNew->pszFormData = pNew->pszQueryInfo+ strlen (pData->pszQueryInfo) + 1;
pNew->pszRedirFile = pNew->pszFormData + strlen (pData->pszFormData) + 1;
strcpy (pNew->pszPathInfo , pData->pszPathInfo );
strcpy (pNew->pszQueryInfo, pData->pszQueryInfo);
strcpy (pNew->pszFormData , pData->pszFormData );
strcpy (pNew->pszRedirFile, pData->pszRedirFile);
return pMem;
} else {
return NULL;
} /* endif */
}
/*
* Error message table
*
*/
typedef struct {
long errCode;
char *pszMsg;
} TGI_ERROR;
TGI_ERROR ErrTab [] = {
{ TGI_OK , "No error " },
{ TGI_EXIT , "Exiting " },
{ TGI_UNLOCK , "Unlock client " },
{ TGI_NOT_RUN , "TGI not running " },
{ TGI_LOC_OPEN_SEM , "TGI_LOC_OPEN_SEM " },
{ TGI_REQUEST , "TGI_REQUEST " },
{ TGI_ALREADY_INIT , "TGI_ALREADY_INIT " },
{ TGI_LOC_RELEASE_SEM , "TGI_LOC_RELEASE_SEM " },
{ TGI_TOO_MANY_MOD , "TGI_TOO_MANY_MOD " },
{ TGI_BAD_PARAM , "TGI_BAD_PARAM " },
{ TGI_UNLOCK_OK , "TGI_UNLOCK_OK " },
{ TGI_MOD_NOT_FOUND , "TGI_MOD_NOT_FOUND " },
{ TGI_BAD_INSTANCE , "TGI_BAD_INSTANCE " },
{ TGI_SEM_CREATE , "TGI_SEM_CREATE " },
{ TGI_UNLOCK_ERROR , "TGI_UNLOCK_ERROR " },
{ TGI_MOD_ALREADY_REG , "Module already registe" },
{ TGI_INST_NOT_FOUND , "TGI_INST_NOT_FOUND " },
{ TGI_MODULE_BUSY , "No free instance found" },
{ TGI_NOT_INIT , "TGI not initialized " },
{ TGI_NO_MEM , "Insufficient memory " },
{ TGI_MLBX_OPEN , "Callback mailbox open " }
};
char *TgiStrError ( long tgiErr )
{
int i;
for (i=0; i<(sizeof(ErrTab)/sizeof(ErrTab[0])); ++i)
if (ErrTab [i].errCode == tgiErr)
return ErrTab [i].pszMsg;
return "Unknow error code";
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -