Click here to Skip to main content
15,893,266 members
Articles / Programming Languages / C++

Shared and Exclusive lock control

Rate me:
Please Sign up or sign in to vote.
3.05/5 (7 votes)
31 Aug 20042 min read 44.3K   629   11  
C++ class for shared and exclusive lock control.
#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;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior)
United States United States
Application and systems programmer since 1972.
Mostly mainframe programming - Assembler, PL/X.
Products: IBM: DFSMSHSM, Candle Corp: Omegamon (IMS and MVS), PKWARE: SecureZIP


Dabble in Windows and Linux at home - C++ and Intel Assembler.

Comments and Discussions