XrdSysXSLock.cc

Go to the documentation of this file.
00001 /******************************************************************************/
00002 /*                                                                            */
00003 /*                       X r d S y s X S L o c k . c c                        */
00004 /*                                                                            */
00005 /* (c) 2003 by the Board of Trustees of the Leland Stanford, Jr., University  */
00006 /*                            All Rights Reserved                             */
00007 /*   Produced by Andrew Hanushevsky for Stanford University under contract    */
00008 /*              DE-AC03-76-SFO0515 with the Department of Energy              */
00009 /******************************************************************************/
00010 
00011 //          $Id: XrdSysXSLock.cc 24468 2008-06-22 16:47:03Z ganis $
00012 
00013 const char *XrdSysXSLockCVSID = "$Id: XrdSysXSLock.cc 24468 2008-06-22 16:47:03Z ganis $";
00014   
00015 #include "XrdSys/XrdSysHeaders.hh"
00016 #include "XrdSys/XrdSysXSLock.hh"
00017 
00018 /******************************************************************************/
00019 /*                            D e s t r u c t o r                             */
00020 /******************************************************************************/
00021   
00022 XrdSysXSLock::~XrdSysXSLock()
00023 {
00024 
00025 // Prevent usage while destroying object but make sure no one else is using it
00026 //
00027    LockContext.Lock();
00028    if (cur_count || shr_wait || exc_wait)
00029       {LockContext.UnLock();
00030        throw "XSLock_delete: Lock object is still active.";
00031       }
00032    LockContext.UnLock();
00033 }
00034 
00035 /******************************************************************************/
00036 /*                                  L o c k                                   */
00037 /******************************************************************************/
00038   
00039 void XrdSysXSLock::Lock(const XrdSysXS_Type usage)
00040 {  int FirstTime = 1;
00041 
00042 // Serialize access to this object
00043 //
00044    LockContext.Lock();
00045 
00046 // This loop continues until we can acquire the resource. We are gauranteed
00047 // to eventually acquire it regardless of the unblocking order.
00048 //
00049    while(cur_count)
00050         {
00051         // If usage is compatible with current usage get the lock right away
00052         //
00053            if (usage == xs_Shared && cur_usage == xs_Shared && !exc_wait) break;
00054 
00055         // Indicate that we are waiting
00056         //
00057         if (FirstTime)
00058            {FirstTime = 0;
00059             if (usage == xs_Shared) shr_wait++;
00060                else exc_wait++;
00061            }
00062 
00063         // Usage is not compatible. We must wait for current lock mode to end
00064         //
00065            LockContext.UnLock();
00066            if (usage == xs_Shared) WantShr.Wait();
00067               else WantExc.Wait();
00068            LockContext.Lock();
00069         }
00070 
00071 // We obtained the right to use this object
00072 //
00073    cur_usage = usage;
00074    cur_count++;
00075    LockContext.UnLock();
00076 }
00077 
00078 /******************************************************************************/
00079 /*                                U n L o c k                                 */
00080 /******************************************************************************/
00081   
00082 void XrdSysXSLock::UnLock(const XrdSysXS_Type usage)
00083 {
00084 
00085 // Serialize access to our data
00086 //
00087    LockContext.Lock();
00088 
00089 // Make sure that the lock is currently being used
00090 //
00091    if (!cur_count)
00092       {LockContext.UnLock();
00093        cerr << "XSLock: Attempt to unlock inactive lock." <<endl;
00094        throw "XSLock: unlocking inactive lock.";
00095       }
00096 
00097 // Verify that usage is correct
00098 //
00099    if (usage && cur_usage != usage)
00100       {LockContext.UnLock();
00101        cerr << "XSLock: Incorrect unlock usage - "
00102             <<  (cur_usage == xs_Shared ? "shr" : "exc") << "!="
00103             <<  (    usage == xs_Shared ? "shr" : "exc") << endl;
00104        throw "XSLock: invalid unlock usage specified.";
00105       }
00106 
00107 // Unlock the current object. If no locks exist then check if we can let another
00108 // thread use this object. The logic is tricky but we are trying to avoid
00109 // starvation in an environment that has no thread ordering.
00110 //
00111    cur_count--;
00112    if (!cur_count)
00113       if (exc_wait && (toggle || !shr_wait)) 
00114                              {toggle = 0; WantExc.Post(); exc_wait--;}
00115          else           {while(shr_wait) {WantShr.Post(); shr_wait--;}
00116                               toggle = 1;}
00117       else if (!toggle) {while(shr_wait) {WantShr.Post(); shr_wait--;}
00118                               toggle = 1;}
00119 
00120    LockContext.UnLock();
00121 }

Generated on Tue Jul 5 14:47:03 2011 for ROOT_528-00b_version by  doxygen 1.5.1