#define INCL_DOSPROCESS
#define INCL_DOSEXCEPTIONS
#define INCL_DOSSEMAPHORES
#include <os2.h>
#include <stdio.h>
/* Prototipi delle funzioni */
ULONG APIENTRY ThreadException(PEXCEPTIONREPORTRECORD,
PEXCEPTIONREGISTRATIONRECORD,
PCONTEXTRECORD,
PVOID);
VOID APIENTRY Thread1(ULONG);
/* Variabili Globali */
HMTX hConsoleSem;
void main(void)
{
EXCEPTIONREGISTRATIONRECORD ExceptionReg={0,ThreadException};
/* L'EXCEPTIONREGISTRATIONRECORD deve stare sullo stack del thread che lo
registra */
APIRET rc;
TID tid1;
TID tid2;
DosSetExceptionHandler(&ExceptionReg);
rc=DosCreateMutexSem("\\sem32\\console.sem",&hConsoleSem,0,TRUE);
/* Semaforo Mutex per la gestione dell'output sullo schermo */
rc=DosCreateThread(&tid1,Thread1,100,CREATE_READY | STACK_SPARSE, 0x2000);
/* Crea e fa partire il primo thread, lo stack viene allocato dal SO */
printf("Created thread n.%d\n",tid1);
DosReleaseMutexSem(hConsoleSem);
/* Rilascia il semaforo per l'utilizzo dello schermo */
rc=DosCreateThread(&tid2,Thread1,50,CREATE_READY | STACK_SPARSE, 0x2000);
DosRequestMutexSem(hConsoleSem,SEM_INDEFINITE_WAIT);
printf("Created thread n.%d\n",tid2);
DosReleaseMutexSem(hConsoleSem);
DosSleep(500);
DosKillThread(tid1);
DosSleep(8000);
DosUnsetExceptionHandler(&ExceptionReg);
/* Toglie il nostro gestore delle eccezioni dalla catena, altrimenti il
meccanismo delle eccezioni non puo` funzionare piu` correttamente */
}
VOID APIENTRY Thread1(ULONG limit)
{
EXCEPTIONREGISTRATIONRECORD ExceptionReg={0,ThreadException};
PPIB pPib;
PTIB pTib;
int i,j;
DosSetExceptionHandler(&ExceptionReg);
DosGetInfoBlocks(&pTib,&pPib);
DosRequestMutexSem(hConsoleSem,SEM_INDEFINITE_WAIT);
printf("Started thread n.%d in process %d\n",pTib->tib_ptib2->tib2_ultid,
pPib->pib_ulpid);
DosReleaseMutexSem(hConsoleSem);
i=j=0;
while(j<10)
{
if(i++>limit)
{
DosRequestMutexSem(hConsoleSem,SEM_INDEFINITE_WAIT);
printf("Thread n.%d Count: %d\n",pTib->tib_ptib2->tib2_ultid,j++);
DosReleaseMutexSem(hConsoleSem);
i=0;
}
}
DosUnsetExceptionHandler(&ExceptionReg);
DosExit(EXIT_THREAD,0);
/* Conclude soltanto il thread corrente */
}
ULONG APIENTRY ThreadException(PEXCEPTIONREPORTRECORD pReport,
PEXCEPTIONREGISTRATIONRECORD pReg,
PCONTEXTRECORD pContext,
PVOID pv)
{
PPIB pPib;
PTIB pTib;
DosGetInfoBlocks(&pTib,&pPib);
switch(pReport->ExceptionNum)
{
case XCPT_PROCESS_TERMINATE:
break;
case XCPT_ASYNC_PROCESS_TERMINATE:
default:
printf("Thread: %d Exception: %X\n",pTib->tib_ptib2->tib2_ultid,
pReport->ExceptionNum);
break;
}
return XCPT_CONTINUE_SEARCH;
}