Click here to Skip to main content
15,884,176 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.2K   629   11  
C++ class for shared and exclusive lock control.
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
<META NAME="Generator" CONTENT="Microsoft Word 97">
<META NAME="Template" CONTENT="E:\OFFICE\OFFICE\html.dot">
</HEAD>
<BODY LINK="#0000ff" VLINK="#800080">

<P><!-- HTML for article "Shared and Exclusive lock control" by Charles Bargar,Charles Bargar
     URL: http://www.codeproject.com/threads/Locker.asp
     Article content copyright Charles Bargar,Charles Bargar
     All formatting, additions and alterations Copyright � CodeProject, 1999-2004
--><!----------------------------- Ignore -->&lt; rel="stylesheet" type=text/css href="http://www.codeproject.com/styles/global.css" 
<B><P>Please choose 'View Source' in your browser to view the HTML, or File | Save to save this file to your hard drive for editing.</P>
</B><P><HR SIZE=0></P>
<P><!----------------------------- Ignore --><!----------------------------- Article Starts --></P>

<UL>
<LI><A HREF="http://www.codeproject.com/threads/Locker/locker.zip">Download source and demo project- 32.6 Kb</A> </LI></UL>

<H2>Introduction</H2>
<P>This article shows a C++ class that provides access to named locks on a Shared and Exclusive basis within a process. The function is similar to the IBM OS/390 ENQ/DEQ macros.</P>
<OL>

<LI>RET=HAVE is implied. </LI>
<LI>The lock name is LOCKNAME/LOCKNAME_LENGTH pair rather than a QNAME/RNAME/RNAMEL combination. </LI></OL>

<P>A thread can request exclusive or shared ownership of a lock. Ownership is granted based on the following table:</P>
<TABLE CELLSPACING=0 BORDER=0 WIDTH=495>
<TR><TD WIDTH="29%" VALIGN="MIDDLE" HEIGHT=16>
<P><TBODY><B>Request</B></TD>
<TD WIDTH="48%" VALIGN="MIDDLE" HEIGHT=16>
<B><P>Held by other threads</B></TD>
<TD WIDTH="23%" VALIGN="MIDDLE" HEIGHT=16>
<B><P>Action</B></TD>
</TR>
<TR><TD WIDTH="29%" VALIGN="MIDDLE" HEIGHT=16>
<P>EXCLUSIVE</TD>
<TD WIDTH="48%" VALIGN="MIDDLE" HEIGHT=16>
<P>NONE</TD>
<TD WIDTH="23%" VALIGN="MIDDLE" HEIGHT=16>
<P>Granted</TD>
</TR>
<TR><TD WIDTH="29%" VALIGN="MIDDLE" HEIGHT=16>
<P>EXCLUSIVE</TD>
<TD WIDTH="48%" VALIGN="MIDDLE" HEIGHT=16>
<P>ANY</TD>
<TD WIDTH="23%" VALIGN="MIDDLE" HEIGHT=16>
<P>Wait</TD>
</TR>
<TR><TD WIDTH="29%" VALIGN="MIDDLE" HEIGHT=16>
<P>SHARED</TD>
<TD WIDTH="48%" VALIGN="MIDDLE" HEIGHT=16>
<P>NONE/SHARED</TD>
<TD WIDTH="23%" VALIGN="MIDDLE" HEIGHT=16>
<P>Granted</TD>
</TR>
<TR><TD WIDTH="29%" VALIGN="MIDDLE" HEIGHT=16>
<P>SHARED</TD>
<TD WIDTH="48%" VALIGN="MIDDLE" HEIGHT=16>
<P>EXCLUSIVE (any)</TD>
<TD WIDTH="23%" VALIGN="MIDDLE" HEIGHT=16>
<P>Wait</TBODY></TD>
</TR>
</TABLE>

<P>Threads placed in a wait state are released when the lock becomes available. Any EXCLUSIVE request blocks all requests following it until the EXCLUSIVE request is released.</P>
<H2>Background</H2>
<P>Written in ANSI C++, except for the three internal classes described below.</P>
<P>Needed to be able to refine the Windows <CODE>CRITICAL_SECTION</CODE> function into shareable and exclusive locks for thread control.</P>
<P>Can be ported to other environments with minimal changes.</P>
<P>Replace:</P>

<UL>
<LI>Internal class <CODE>EXCLUSIVE_EX</CODE>. </LI>
<LI>Internal class <CODE>Semaphore</CODE>. </LI>
<LI>Internal class <CODE>ThreadIdentity</LI></UL>

</CODE><H2>Using the code</H2>
<P>Lock names may contain binary codes, for instance, an address. All compares, copies, etc. use the <CODE>mem***</CODE> C++ functions. The maximum length for a lock name is 64 bytes (parameterized within <I>locker.h</I>).</P>
<H4>How to use Locker:</H4>
<P>In the parent thread, create an instance of the <CODE>Locker</CODE> class.</P>
<PRE>Locker  *Lockset;
Lockset=new Locker()</PRE>
<P>Pass <CODE>Lockset</CODE> to child threads that need access to the locks.</P>
<P>In any thread with access to <CODE>Lockset</CODE>:</P>
<PRE>    int rc;

    rc=Lockset-&gt;GetSharedLock(const char *lname, int lnamel);
      Returns LOCK_OK        (lock established)
              LOCK_SHARED    (Shared lock already held)
              LOCK_EXCL      (Exclusive lock already held)
              LOCK_ERROR     (LNAMEL &gt; MAXLOCKNAME)

    rc=Lockset-&gt;GetExclLock(const char *lname, int lnamel);
      Returns LOCK_OK     (lock established)
              LOCK_SHARED (Shared lock already held)
                          The lock state was NOT changed
                          to Exclusive, and remains in
                          effect as Shared.
              LOCK_EXCL   (Exclusive lock already held)
              LOCK_ERROR  (LNAMEL &gt; MAXLOCKNAME)

    rc=Lockset-&gt;RelLock(const char *lname, int lnamel);
      Returns LOCK_OK          (lock released)
              LOCK_NOT_HELD    (lock wasn't held)
              LOCK_ERROR       (LNAMEL &gt; MAXLOCKNAME)

    rc=Lockset-&gt;TestLock(const char *lname, int lnamel);
      Returns LOCK_SHARED   (Shared lock held)
              LOCK_EXCL     (Exclusive lock held)
              LOCK_NOT_HELD (lock wasn't held)
              LOCK_ERROR    (LNAMEL &gt; MAXLOCKNAME)</PRE>
<P>When all threads are no longer using the <CODE>Lockset</CODE>:</P>
<PRE>delete Lockset;</PRE>
<P>If any threads are still using the <CODE>Lockset</CODE>, the destructor terminates the process with an <CODE>assert(0)</CODE>, preventing program checks in the active threads when they attempt to access the deleted class.</P>
<H2>History</H2>
<P>First release.</P>
<P>Version 1.1</P>
<OL>

<LI>Fixed a bug that caused a loop during RelLock</LI>
<LI>Performance enhancement  and code simplification - changed RelLock to not remove the Lock structure when no users of a lock remain. Lock structures are now removed a destructor time only.</LI>
<LI>Updated Locker.h Locker.cpp to move all Windows-specific code into Locker internal classes, making ports to other systems easier.</LI>
<LI>Updated Tlocker.cpp to use the data base address as the lock.</LI>
<LI>Added tlocker_readme.txt file to describe the test program and how to run it.</LI>
<LI>Created a separate VC workspace that contains only the Locker project (Locker.dws, Locker.dsp, and Tlocker.dsp).</LI></OL>

<P><!----------------------------- Article Ends --></P></BODY>
</HTML>

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