Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

Tagged as

Go to top

Shared and Exclusive lock control

, 31 Aug 2004
C++ class for shared and exclusive lock control.
locker.zip
sourcecode
locker
Locker.dsp
Locker.dsw
TLocker.dsp
release
TLocker.exe
#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

Share

About the Author

Charles Bargar
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.

| Advertise | Privacy | Mobile
Web02 | 2.8.140922.1 | Last Updated 1 Sep 2004
Article Copyright 2004 by Charles Bargar
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid