|
<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 -->< 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->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 > MAXLOCKNAME)
rc=Lockset->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 > MAXLOCKNAME)
rc=Lockset->RelLock(const char *lname, int lnamel);
Returns LOCK_OK (lock released)
LOCK_NOT_HELD (lock wasn't held)
LOCK_ERROR (LNAMEL > MAXLOCKNAME)
rc=Lockset->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 > 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.
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.