#include "locker.h"
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
typedef struct
{
int value;
char *name;
} DBASE, *PDBASE;
DBASE DBA={0,"A"};
DBASE DBB={0,"B"};
typedef struct
{
Locker *locks;
int thrdnum;
BOOL locktype;
PDBASE *db;
} ThrdParm, *PThrdParm;
FILE *stream;
BOOL done=FALSE;
static void wait(char *msg)
{
while (_kbhit()!=0) _getch();
if (msg!=NULL)
fprintf(stderr,"%s\n",msg);
else
fprintf(stderr,"Press any key to continue.\n");
_getch();
}
DWORD WINAPI ThrdRtn(LPVOID lpParameter)
{
PThrdParm parms;
Locker *locks;
int rc, waittime, tnum, dbv, RNAMEL;
BOOL lockexcl;
char *indent, dbn[20];
PDBASE db;
void *RNAME;
parms=(PThrdParm)lpParameter;
tnum=parms->thrdnum;
locks=parms->locks;
db=*parms->db;
RNAME=parms->db;
RNAMEL=sizeof(parms->db);
strcpy(dbn,db->name);
lockexcl=parms->locktype;
char *locktype;
if (lockexcl)
{
locktype="EXCLUSIVE";
indent=" ";
}
else
{
locktype="SHARED";
indent=" ";
}
printf("%sThread %i starting (%s lock). DB.name=%s, %s lock\n", indent,tnum,locktype,dbn,locktype);
fflush(stream);
while (!done)
{
printf("%sThread %i requesting %s lock. DB.name=%s\n", indent,tnum,locktype,dbn);
fflush(stream);
if (lockexcl)
rc=locks->GetExclLock(RNAME,RNAMEL);
else
rc=locks->GetSharedLock(RNAME,RNAMEL);
strcpy(dbn,db->name);
dbv=db->value;
printf("%sThread %i got %s lock, DB.name=%s, DB.value=%i\n",
indent,tnum,locktype,dbn, dbv);
fflush(stream);
waittime=10;
if (lockexcl)
{
dbv=++db->value;
printf("%sThread %i incremented value to %i\n",indent,tnum,db->value);
fflush(stream);
if (tnum%2) waittime=500; // UNBALANCE execution times.. ODD update threads wait MUCH longer
}
else
{
rc=locks->TestLock(RNAME,RNAMEL);
printf("%sThread %i testlock=%i\n",indent,tnum,rc);
}
if (!done) Sleep(waittime);
printf("%s%sThread %i releasing %s lock, DB.name=%s, DB.value=%i\n",
indent,indent,tnum,locktype,dbn,dbv);
fflush(stream);
rc=locks->RelLock(RNAME,RNAMEL);
printf("%sThread %i released %s lock, DB.name=%s, DB.value=%i\n",
indent,tnum,locktype,dbn, dbv);
fflush(stream);
}
printf("Thread %i ended\n",parms->thrdnum);
fflush(stream);
ExitThread(0);
}
int main(int argc, char **argv)
{
Locker *locks;
#define NUMTHREADS 6
ThrdParm parms[NUMTHREADS];
int rc=0, i, ne;
DWORD tids[NUMTHREADS];
HANDLE hndls[NUMTHREADS];
BOOL locktypes[NUMTHREADS];
for (i=0; i<NUMTHREADS; i++)
locktypes[i]=FALSE;
locktypes[2]=TRUE;
locktypes[5]=TRUE;
ne=2;
stream=freopen("tlocker.txt","w",stdout );
locks=new Locker();
fprintf(stderr,"Testing Locker class %i threads, %i exclusive\n",NUMTHREADS, ne);
printf("Testing Locker class %i threads, %i exclusive\n",NUMTHREADS, ne);
fflush(stream);
fprintf(stderr,"Testing LNAME>MAXLOCKNAME\n");
printf("Testing LNAME>MAXLOCKNAME\n");
rc=locks->GetExclLock("TEST STRING",MAXLOCKNAME+1);
printf(" GetExclLock(\"TEST STRING\",MAXLOCKNAME+1) returned %i\n",rc);
rc=locks->GetSharedLock("TEST STRING",MAXLOCKNAME+1);
printf(" GetSharedLock(\"TEST STRING\",MAXLOCKNAME+1) returned %i\n",rc);
rc=locks->TestLock("TEST STRING",MAXLOCKNAME+1);
printf(" GetTestLock(\"TEST STRING\",MAXLOCKNAME+1) returned %i\n",rc);
rc=locks->RelLock("TEST STRING",MAXLOCKNAME+1);
printf(" RelLock(\"TEST STRING\",MAXLOCKNAME+1) returned %i\n",rc);
fprintf(stderr,"MAXLOCKNAME test complete\n\n");
printf("Starting %i Threads\n",NUMTHREADS);
fprintf(stderr,"Starting %i Threads\n",NUMTHREADS);
PDBASE dba=&DBA, dbb=&DBB;
for (i=0; i<NUMTHREADS; i++)
{
parms[i].thrdnum=i;
parms[i].locks=locks;
parms[i].locktype=locktypes[i];
if (i%2)
parms[i].db=&dba;
else
parms[i].db=&dbb;
hndls[i]=CreateThread(NULL,0,&ThrdRtn,&parms[i],NULL,&tids[i]);
printf("Thread %i started: ThreadId %08X, Locktype=%i\n",i,tids[i], locktypes[i]);
fflush(stream);
fprintf(stderr," Thread %i started: ThreadId %08X, Locktype=%i\n",i,tids[i], locktypes[i]);
};
fprintf(stderr,"\nTest running -- will complete in 20 seconds....\n");
Sleep(20*1000);
done=TRUE;
printf("\n===> Waiting for threads to end......\n\n");
fprintf(stderr,"Waiting for threads to end......\n");
for (i=0; i<NUMTHREADS; i++)
{
BOOL texit=FALSE;
DWORD exitcode;
do
{
GetExitCodeThread(hndls[i],&exitcode);
if (exitcode!=STILL_ACTIVE) texit=TRUE;
}
while (!texit);
}
delete locks;
printf("Test complete\n");
fprintf(stderr,"Test complete\nConsole log directed to tlocker.txt\n");
fclose( stream );
return rc;
}