<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <HTML> <HEAD> <META NAME="GENERATOR" CONTENT="SGML-Tools 1.0.9"> <TITLE> RPC2 User Guide and Reference Manual: The Lock Package</TITLE> <LINK HREF="rpc2_manual-10.html" REL=next> <LINK HREF="rpc2_manual-8.html" REL=previous> <LINK HREF="rpc2_manual.html#toc9" REL=contents> </HEAD> <BODY> <A HREF="rpc2_manual-10.html">Next</A> <A HREF="rpc2_manual-8.html">Previous</A> <A HREF="rpc2_manual.html#toc9">Contents</A> <HR> <H2><A NAME="s9">9. The Lock Package</A></H2> <P> <A NAME="LockPackage"></A> <P>The lock package contains a number of routines and macros that allow C programs that utilize the LWP abstraction to place read and write locks on data structures shared by several light-weight processes. Like the LWP package, the lock package was written with simplicity in mind -- there is no protection inherent in the model. <P>In order to use the locking mechanism for an object, an object of type <CODE>struct Lock</CODE> must be associated with the object. After being initialized, with a call to @Lock(Init), the lock is used in invocations of the macros ObtainReadLock, ObtainWriteLock, ReleaseReadLock and ReleaseWriteLock. <P>The semantics of a lock is such that any number of readers may hold a lock. But only a single writer (and no readers) may hold the clock at any time. The lock package guarantees fairness: each reader and writer will eventually have a chance to obtain a given lock. However, this fairness is only guaranteed if the priorities of the competing processes are identical. Note that no ordering is guaranteed by the package. <P>In addition, it is illegal for a process to request a particular lock more than once, without first releasing it. Failure to obey this restriction may cause deadlock. <P> <H2><A NAME="ss9.1">9.1 Key Design Choices</A> </H2> <P> <UL> <LI>The package must be simple and @u[fast]: in the case that a lock can be</LI> <LI>obtained immediately, it should require a minimum of instructions; </LI> <LI>All the processes using a lock are trustworthy; </LI> <LI>The lock routines ignore priorities;</LI> </UL> <P> <P> <H3>A Simple Example</H3> <P>@Begin(program) #include "lock.h" <P>struct Vnode { . . . struct Lock lock; /* Used to lock this vnode */ . . . }; <P>#define READ 0 #define WRITE 1 <P>struct Vnode *get_vnode (name, how) char *name; int how; { struct Vnode *v; <P>v = lookup (name); if (how == READ) ObtainReadLock (&v-> lock); else ObtainWriteLock (&v-> lock); } @End(program) <P> <P> <H2><A NAME="ss9.2">9.2 Lock Primitives</A> </H2> <P> <H3>Lock_Init -- Initialize a lock </H3> <P> <H3>Call:</H3> <P><EM> void Lock_Init(</EM> @w<<B>out</B> struct Lock *lock> <EM>)</EM> <H3>Parameters:</H3> <P> <DL> <DT><B>lock</B><DD><P>The (address of the) lock to be initialized, </DL> <H3>Completion Codes:</H3> <P><EM> N/A </EM> <H3>Description:</H3> <P>This routine must be called to initialize a lock before it is used. <P> <P> <H3>ObtainReadLock -- Obtain a read lock </H3> <P> <H3>Call:</H3> <P><EM> ObtainReadLock(</EM> @w<<B>in out</B> struct Lock *lock> <EM>)</EM> <H3>Parameters:</H3> <P> <DL> <DT><B>lock</B><DD><P>The lock to be read-locked, </DL> <H3>Completion Codes:</H3> <P><EM> N/A </EM> <H3>Description:</H3> <P>A read lock will be obtained on the specified lock. Note that this is a macro and not a routine. Thus, results are not guaranteed if the lock argument is a side-effect producing expression. <P> <H3>ObtainWriteLock -- Obtain a write lock </H3> <P> <H3>Call:</H3> <P><EM> ObtainWriteLock(</EM> @w<<B>in out</B> struct Lock *lock> <EM>)</EM> <H3>Parameters:</H3> <P> <DL> <DT><B>lock</B><DD><P>The lock to be write-locked </DL> <H3>Completion Codes:</H3> <P> <DL> <P><EM> N/A </EM> </DL> <H3>Description:</H3> <P>A write lock will be obtained on the specified lock. Note that this is a macro and not a routine. Thus, results are not guaranteed if the lock argument is a side-effect producing expression. ) <P> <H3>ReleaseReadLock -- Release a read lock </H3> <P> <H3>Call:</H3> <P><EM> ReleaseReadLock(</EM> @w<<B>in out</B> struct Lock *lock> <EM>)</EM> <H3>Parameters:</H3> <P> <DL> <DT><B>lock</B><DD><P>The lock to be released </DL> <H3>Completion Codes:</H3> <P><EM>N/A </EM> <H3>Description:</H3> <P>The specified lock will be released. This macro requires that the lock must have been previously read-locked. Note that this is a macro and not a routine. Thus, results are not guaranteed if the lock argument is a side-effect producing expression. <P> <H3>ReleaseWriteLock -- Release a write lock </H3> <P> <H3>Call:</H3> <P><EM> ReleaseWriteLock(</EM> @w<<B>in out</B> struct Lock *lock> <EM>)</EM> <H3>Parameters:</H3> <P> <DL> <DT><B>lock</B><DD><P>The lock to be released </DL> <H3>Completion Codes:</H3> <P> <DL> <P><EM>N/A </EM> </DL> <H3>Description:</H3> <P>The specified lock will be released. This macro requires that the lock must have been previously write-locked. Note that this is a macro and not a routine. Thus, results are not guaranteed if the lock argument is a side-effect producing expression. ) <P> <H3>CheckLock -- Check the status of a lock </H3> <P> <H3>Call:</H3> <P><EM> CheckLock(</EM> @w<<B>in</B> struct Lock *lock> <EM>)</EM> <H3>Parameters:</H3> <P> <DL> <DT><B>lock</B><DD><P>The lock to be checked </DL> <H3>Completion Codes:</H3> <P><EM> N/A </EM> <H3>Description:</H3> <P>This macro yields an integer that specifies the status of the indicated lock. The value will be -1 if the lock is write-locked 0 if unlocked, or a positive integer that indicates the numer of readers with read locks. Note that this is a macro and not a routine. Thus, results are not guaranteed if the lock argument is a side-effect producing expression. ) <P> <HR> <A HREF="rpc2_manual-10.html">Next</A> <A HREF="rpc2_manual-8.html">Previous</A> <A HREF="rpc2_manual.html#toc9">Contents</A> </BODY> </HTML>