LockManager Class Reference

#include <Lock.h>

Collaboration diagram for LockManager:

Collaboration graph
[legend]

Public Member Functions

 LockManager (Database *sysDb_)
DbRetVal getSharedLock (void *tuple, Transaction **trans)
DbRetVal getExclusiveLock (void *tuple, Transaction **trans)
DbRetVal releaseLock (void *tuple)
DbRetVal isExclusiveLocked (void *tuple, Transaction **trans, bool &status)
void printUsageStatistics ()
void printDebugInfo ()

Data Fields

DatabasesystemDatabase_

Detailed Description

Definition at line 75 of file Lock.h.


Constructor & Destructor Documentation

LockManager::LockManager ( Database sysDb_  )  [inline]

Definition at line 87 of file Lock.h.

References systemDatabase_.

00087 { systemDatabase_ = sysDb_;}


Member Function Documentation

DbRetVal LockManager::getExclusiveLock ( void *  tuple,
Transaction **  trans 
)

Definition at line 318 of file LockManager.cxx.

References Bucket::bucketList_, Conf::config, DM_Lock, ErrLockTimeOut, Transaction::findInHasList(), Mutex::getLock(), Config::getLockSecs(), Config::getLockUSecs(), ProcessManager::hasLockList, LockHashNode::lInfo_, Bucket::mutex_, LockHashNode::next_, LockInfo::noOfReaders_, OK, printDebug, printError, Database::procSlot, LockHashNode::ptrToTuple_, Mutex::releaseLock(), os::select(), systemDatabase_, and LockInfo::waitWriters_.

Referenced by TableImpl::deleteTuple(), DatabaseManagerImpl::dropTable(), TableImpl::insertTuple(), and TableImpl::updateTuple().

00319 {
00320    LockInfo linfo;
00321    linfo.noOfReaders_ = -1;
00322    printDebug(DM_Lock, "LockManager::getExclusiveLock Begin");
00323    //keeping it ready for the allocation, because when
00324    //lock node is not present in the list, then it means we are the first
00325    //to acquire lock so for sure we will get it.
00326 
00327    Bucket *bucket = getLockBucket(tuple);
00328    int lockRet = bucket->mutex_.getLock(systemDatabase_->procSlot);
00329    if (lockRet != 0)
00330    {
00331        printDebug(DM_Lock, "Unable to acquire bucket mutex:May be deadlock");
00332        printError(ErrLockTimeOut, "Unable to acquire bucket mutex");
00333        return ErrLockTimeOut;
00334    }
00335    LockHashNode *lockNode = (LockHashNode*) bucket->bucketList_;
00336    if (NULL == lockNode)
00337    {
00338         DbRetVal rv = OK;
00339         LockHashNode *node = allocLockNode(linfo, tuple, &rv);
00340         if (NULL == node)
00341         {
00342             printError(rv, "Could not allocate Lock node");
00343             return rv;
00344         }
00345         printDebug(DM_Lock, "No head. So new lock node allocated:%x",node);
00346         bucket->bucketList_ = (void*)node; //make it as head
00347         bucket->mutex_.releaseLock(systemDatabase_->procSlot);
00348         rv =OK;
00349         if (trans != NULL) 
00350            rv = (*trans)->insertIntoHasList(systemDatabase_, node);
00351         if (rv !=OK) linfo.noOfReaders_ = 0;
00352         printDebug(DM_Lock, "LockManager::getExclusiveLock End");
00353         return rv;
00354 
00355    }
00356    LockHashNode *cachedLockNode = NULL;
00357 
00358    LockHashNode *iter = lockNode;
00359    //Iterate though the list and find the element's lock info
00360    while(iter != NULL)
00361    {
00362        if(iter->ptrToTuple_ == tuple)
00363        {
00364            if (iter->lInfo_.noOfReaders_ != 0)
00365            {
00366                iter->lInfo_.waitWriters_++;
00367                bucket->mutex_.releaseLock(systemDatabase_->procSlot);
00368                if (trans != NULL) (*trans)->updateWaitLock(iter);
00369                cachedLockNode = iter;
00370                printDebug(DM_Lock, "Either some one has exclusive or shared lock:%x",iter);
00371                break;
00372            }
00373            else
00374            {
00375                iter->lInfo_.noOfReaders_ = -1;
00376                bucket->mutex_.releaseLock(systemDatabase_->procSlot);
00377                DbRetVal rv =OK;
00378                if (trans != NULL) 
00379                  rv = (*trans)->insertIntoHasList(systemDatabase_, iter);
00380                if (rv != OK) iter->lInfo_.noOfReaders_ = 0;
00381                printDebug(DM_Lock, "LockManager::getExclusiveLock End");
00382                return rv;
00383            }
00384        }
00385        printDebug(DM_Lock, "Finding the lock node. iter:%x",iter);
00386        iter = iter->next_;
00387    }
00388    if (NULL == cachedLockNode)
00389    {
00390         DbRetVal rv =OK;
00391         LockHashNode *node = allocLockNode(linfo, tuple, &rv);
00392         if (NULL == node)
00393         {
00394             bucket->mutex_.releaseLock(systemDatabase_->procSlot);
00395             if (trans != NULL) (*trans)->updateWaitLock(NULL);
00396             printError(rv, "Could not allocate Lock node");
00397             return rv;
00398         }
00399         printDebug(DM_Lock, "Not Found:Creating new lock node:%x",node);
00400         LockHashNode *it = lockNode;
00401         while (NULL != it->next_) it = it->next_;
00402         it->next_ = node;
00403         bucket->mutex_.releaseLock(systemDatabase_->procSlot);
00404         rv = OK;
00405         if (trans != NULL) 
00406           rv = (*trans)->insertIntoHasList(systemDatabase_, node);
00407         if (rv != OK) linfo.noOfReaders_ = 0;
00408          if (trans != NULL) (*trans)->removeWaitLock();
00409         printDebug(DM_Lock, "LockManager::getExclusiveLock End");
00410         return rv;
00411    }
00412    //bucket->mutex_.releaseLock();
00413    int tries = 0;
00414    int ret = 0;
00415    struct timeval timeout;
00416    timeout.tv_sec = Conf::config.getLockSecs();
00417    timeout.tv_usec = Conf::config.getLockUSecs();
00418 
00419    while (tries < Conf::config.getLockRetries())
00420    {
00421        lockRet = bucket->mutex_.getLock(systemDatabase_->procSlot);
00422        if (lockRet != 0)
00423        {
00424            printError(ErrLockTimeOut, "Unable to get bucket mutex");
00425            return ErrLockTimeOut;
00426        }
00427        if (cachedLockNode->lInfo_.noOfReaders_ == 0)
00428        {
00429            cachedLockNode->lInfo_.noOfReaders_ = -1;
00430            cachedLockNode->lInfo_.waitWriters_--;
00431            bucket->mutex_.releaseLock(systemDatabase_->procSlot);
00432            DbRetVal rv ;
00433            if (trans != NULL) 
00434                rv = (*trans)->insertIntoHasList(systemDatabase_, cachedLockNode);
00435            if (trans != NULL) (*trans)->removeWaitLock();
00436            printDebug(DM_Lock, "LockManager::getExclusiveLock End");
00437            return rv;
00438        }else if ( cachedLockNode->lInfo_.noOfReaders_ == 1)
00439        {
00440            if (trans !=NULL && (*trans)->findInHasList(systemDatabase_, cachedLockNode))
00441            {
00442                printDebug(DM_Lock, "upgrading shared to exclusive lock:%x",
00443                                                            cachedLockNode);
00444                //upgrade it to exclusive lock
00445                cachedLockNode->lInfo_.noOfReaders_ = -1;
00446                cachedLockNode->lInfo_.waitWriters_--;
00447                bucket->mutex_.releaseLock(systemDatabase_->procSlot);
00448                if (trans != NULL) (*trans)->removeWaitLock();
00449                printDebug(DM_Lock, "LockManager::getExclusiveLock End");
00450                return OK;
00451            }
00452            if (trans ==NULL && ProcessManager::hasLockList.exists(cachedLockNode->ptrToTuple_))
00453            {
00454                printDebug(DM_Lock, "upgrading shared to exclusive lock:%x",
00455                                                            cachedLockNode);
00456                //upgrade it to exclusive lock
00457                cachedLockNode->lInfo_.noOfReaders_ = -1;
00458                cachedLockNode->lInfo_.waitWriters_--;
00459                bucket->mutex_.releaseLock(systemDatabase_->procSlot);
00460                if (trans != NULL) (*trans)->removeWaitLock();
00461                printDebug(DM_Lock, "LockManager::getExclusiveLock End");
00462                return OK;
00463            }
00464        }else if ( cachedLockNode->lInfo_.noOfReaders_ == -1)
00465        {
00466            if (trans !=NULL && (*trans)->findInHasList(systemDatabase_, cachedLockNode))
00467            {
00468                printDebug(DM_Lock, "You already have exclusive lock:%x",
00469                                                         cachedLockNode);
00470                cachedLockNode->lInfo_.waitWriters_--;
00471                bucket->mutex_.releaseLock(systemDatabase_->procSlot);
00472                if (trans != NULL) (*trans)->removeWaitLock();
00473                printDebug(DM_Lock, "LockManager::getExclusiveLock End");
00474                return OK;
00475            }
00476            if (trans ==NULL && ProcessManager::hasLockList.exists(cachedLockNode->ptrToTuple_))
00477            {
00478                printDebug(DM_Lock, "You already have exclusive lock:%x",
00479                                                            cachedLockNode);
00480                cachedLockNode->lInfo_.waitWriters_--;
00481                bucket->mutex_.releaseLock(systemDatabase_->procSlot);
00482                if (trans != NULL) (*trans)->removeWaitLock();
00483                printDebug(DM_Lock, "LockManager::getExclusiveLock End");
00484                return OK;
00485            }
00486        }
00487        bucket->mutex_.releaseLock(systemDatabase_->procSlot);
00488        os::select(0, 0, 0, 0, &timeout);
00489        tries++;
00490        printDebug(DM_Lock, "Trying to lock the lock node:%x iteration:%d",cachedLockNode, tries);
00491    }
00492    printDebug(DM_Lock, "LockManager::getExclusiveLock End");
00493    if (trans != NULL) (*trans)->removeWaitLock();
00494    printError(ErrLockTimeOut, "Unable to acquire lock for long time.Timed out");
00495    return ErrLockTimeOut;
00496 }

Here is the call graph for this function:

Here is the caller graph for this function:

DbRetVal LockManager::getSharedLock ( void *  tuple,
Transaction **  trans 
)

Definition at line 93 of file LockManager.cxx.

References Bucket::bucketList_, Conf::config, DM_Lock, ErrLockTimeOut, Transaction::findInHasList(), Mutex::getLock(), Config::getLockSecs(), Config::getLockUSecs(), LockHashNode::lInfo_, Bucket::mutex_, LockHashNode::next_, LockInfo::noOfReaders_, OK, printDebug, printError, Database::procSlot, LockHashNode::ptrToTuple_, Mutex::releaseLock(), os::select(), systemDatabase_, LockInfo::waitReaders_, and LockInfo::waitWriters_.

Referenced by TableImpl::fetchNoBind().

00094 {
00095    //get the bucket list
00096    //take the bucket mutex for read
00097    //go the the next level bucket list
00098    //get the bucket iterator
00099    //go the node where the lock info resides
00100    //check which mode the lock is taken
00101    // if shared then
00102    //      upgrade the bucket mutex to write
00103    //      take it and increment the readers count
00104    //      release bucket mutex and exit
00105    // if exclusive then
00106    //       go into the loop
00107    //       upgrade the bucket mutex to write
00108    //       increment waitReaders count
00109    //       release the bucket mutex
00110    //       wait for timeout period or (takes shared lock and release it ) till it becomes free.
00111    //       if times out
00112    //            take bucket mutex for write
00113    //            decrement waitReaders count
00114    //            releaese bucket mutex
00115 
00116    //            return
00117    //       if it becomes free
00118    //            take bucket mutex for write
00119    //            increment readers
00120    //            releaese bucket mutex
00121 
00122    //            return
00123    LockInfo linfo;
00124    linfo.noOfReaders_ = 1;
00125    //keeping it ready for the allocation, because when
00126    //lock node is not present in the list, then it means we are the first
00127    //to acquire lock so for sure we will get it.
00128    printDebug(DM_Lock, "LockManager::getSharedLock Begin");
00129    Bucket *bucket = getLockBucket(tuple);
00130    int lockRet = bucket->mutex_.getLock(systemDatabase_->procSlot);
00131    if (lockRet != 0)
00132    {
00133        printDebug(DM_Lock, "LockManager::getSharedLock:End-Unable to get mutex");
00134        printError(ErrLockTimeOut,"Unable to acquire bucket mutex");
00135        return ErrLockTimeOut;
00136    }
00137    LockHashNode *lockNode = (LockHashNode*) bucket->bucketList_;
00138    if (NULL == lockNode)
00139    {
00140         DbRetVal rv = OK;
00141         LockHashNode *node = allocLockNode(linfo, tuple, &rv);
00142         if (NULL == node)
00143         {
00144             printError(rv, "Could not allocate Lock node");
00145             return rv;
00146             }
00147         printDebug(DM_Lock, "Bucket list is null: Allocating new LockHashNode %x", node);
00148         bucket->bucketList_ = (void*)node; //make it as head
00149         bucket->mutex_.releaseLock(systemDatabase_->procSlot);
00150         rv = OK;
00151         if (trans != NULL) 
00152             rv = (*trans)->insertIntoHasList(systemDatabase_, node);
00153         if (rv !=OK) linfo.noOfReaders_--;
00154         printDebug(DM_Lock, "LockManager::getSharedLock End");
00155         return rv;
00156    }
00157    LockHashNode *cachedLockNode = NULL;
00158 
00159    LockHashNode *iter = lockNode;
00160    //Iterate though the list and find the element's lock info
00161    while(iter != NULL)
00162    {
00163        if(iter->ptrToTuple_ == tuple)
00164        {
00165            if (iter->lInfo_.noOfReaders_ == -1)
00166            {
00167 
00168                iter->lInfo_.waitReaders_++;
00169                        cachedLockNode = iter;
00170                bucket->mutex_.releaseLock(systemDatabase_->procSlot);
00171                if (trans != NULL) (*trans)->updateWaitLock(iter);
00172                printDebug(DM_Lock, "lock node:%x exclusive locked",iter);
00173                break;
00174            }
00175            else if (iter->lInfo_.noOfReaders_ == 0)
00176            {
00177                if(iter->lInfo_.waitWriters_ >0)
00178                {
00179                    iter->lInfo_.waitReaders_++;
00180                    cachedLockNode = iter;
00181                    bucket->mutex_.releaseLock(systemDatabase_->procSlot);
00182                    if (trans != NULL) (*trans)->updateWaitLock(iter);
00183                    printDebug(DM_Lock, "lock node:%x Writers waiting.",iter);
00184                    break;
00185                }
00186                else
00187                {
00188                    iter->lInfo_.noOfReaders_++;
00189                    bucket->mutex_.releaseLock(systemDatabase_->procSlot);
00190                    DbRetVal rv = OK;
00191                    if (trans != NULL) 
00192                      rv = (*trans)->insertIntoHasList(systemDatabase_, iter);
00193                    if (rv != OK) iter->lInfo_.noOfReaders_--;
00194                    printDebug(DM_Lock, "lock node:%x First to take shared lock",
00195                                                                           iter);
00196                    printDebug(DM_Lock, "LockManager::getSharedLock End");
00197                    return rv;
00198                 }
00199            }else
00200            {
00201                iter->lInfo_.noOfReaders_++;
00202                bucket->mutex_.releaseLock(systemDatabase_->procSlot);
00203                DbRetVal rv = OK;
00204                if (trans != NULL) 
00205                  rv = (*trans)->insertIntoHasList(systemDatabase_, iter);
00206                if (rv != OK) iter->lInfo_.noOfReaders_--;
00207                printDebug(DM_Lock, "lock node:%x incr readers",iter);
00208                printDebug(DM_Lock, "LockManager::getSharedLock End");
00209                return rv;
00210            }
00211        }
00212        printDebug(DM_Lock, "Finding the lock node. iter:%x",iter);
00213        iter = iter->next_;
00214    }
00215    if (NULL == cachedLockNode)
00216    {
00217         DbRetVal rv =OK;
00218         LockHashNode *node = allocLockNode(linfo, tuple, &rv);
00219         if (NULL == node)
00220         {
00221             bucket->mutex_.releaseLock(systemDatabase_->procSlot);
00222             printError(rv, "Could not allocate Lock node");
00223             if (trans != NULL) (*trans)->removeWaitLock();
00224             return rv;
00225         }
00226         printDebug(DM_Lock,"Not Found.Created new lock node:%x",node);
00227         LockHashNode *it = lockNode;
00228         while (NULL != it->next_) it = it->next_;
00229         it->next_ = node;
00230         bucket->mutex_.releaseLock(systemDatabase_->procSlot);
00231         rv = OK;
00232         if (trans != NULL) 
00233           rv = (*trans)->insertIntoHasList(systemDatabase_, node);
00234         if (rv != OK) linfo.noOfReaders_--;
00235         if (trans != NULL) (*trans)->removeWaitLock();
00236         printDebug(DM_Lock, "LockManager::getSharedLock End");
00237         return rv;
00238    }
00239    //bucket->mutex_.releaseLock();
00240    int tries = 0;
00241    int ret = 0;
00242    struct timeval timeout;
00243    timeout.tv_sec = Conf::config.getLockSecs();
00244    timeout.tv_usec = Conf::config.getLockUSecs();
00245 
00246    //printDebug(DM_Lock, "Trying to get mutex: for bucket %x\n", bucket);
00247    while (tries < Conf::config.getLockRetries())
00248    {
00249        lockRet = bucket->mutex_.getLock(systemDatabase_->procSlot);
00250        if (lockRet != 0)
00251        {
00252            printDebug(DM_Lock, "Mutex is waiting for long time:May be deadlock");
00253            printDebug(DM_Lock, "LockManager::getSharedLock End");
00254            printError(ErrLockTimeOut, "Unable to get bucket mutex");
00255            if (trans != NULL) (*trans)->removeWaitLock();
00256            return ErrLockTimeOut;
00257        }
00258        if (cachedLockNode->lInfo_.noOfReaders_ == 0)
00259        {
00260            //if there are waiters allow then to take the lock
00261            if (cachedLockNode->lInfo_.waitWriters_ <0)
00262            {
00263                cachedLockNode->lInfo_.noOfReaders_++;
00264                cachedLockNode->lInfo_.waitReaders_--;
00265                bucket->mutex_.releaseLock(systemDatabase_->procSlot);
00266                DbRetVal rv = OK;
00267                if (trans != NULL) 
00268                  rv = (*trans)->insertIntoHasList(systemDatabase_, cachedLockNode);
00269                if (rv !=OK) {
00270                    cachedLockNode->lInfo_.noOfReaders_--;
00271                    cachedLockNode->lInfo_.waitReaders_++;
00272                    if (trans != NULL) (*trans)->removeWaitLock();
00273                    return rv;
00274                }
00275                if (trans != NULL) (*trans)->removeWaitLock();
00276                printDebug(DM_Lock, "LockManager::getSharedLock End");
00277                return OK;
00278            }
00279        } else if (cachedLockNode->lInfo_.noOfReaders_ == -1)
00280        {
00281            if (trans !=NULL && (*trans)->findInHasList(systemDatabase_, cachedLockNode))
00282            {
00283                bucket->mutex_.releaseLock(systemDatabase_->procSlot);
00284                if (trans != NULL) (*trans)->removeWaitLock();
00285                printDebug(DM_Lock, "LockManager::getSharedLock End");
00286                return OK;
00287            }
00288        } else
00289        {
00290            cachedLockNode->lInfo_.noOfReaders_++;
00291            cachedLockNode->lInfo_.waitReaders_--;
00292            bucket->mutex_.releaseLock(systemDatabase_->procSlot);
00293            DbRetVal rv =OK;
00294            if (trans != NULL) 
00295               rv = (*trans)->insertIntoHasList(systemDatabase_, cachedLockNode);
00296            if (rv !=OK) {
00297                cachedLockNode->lInfo_.noOfReaders_--;
00298                cachedLockNode->lInfo_.waitReaders_++;
00299            }
00300            if (trans != NULL) (*trans)->removeWaitLock();
00301            printDebug(DM_Lock, "LockManager::getSharedLock End");
00302            return rv;
00303        }
00304 
00305        bucket->mutex_.releaseLock(systemDatabase_->procSlot);
00306        os::select(0, 0, 0, 0, &timeout);
00307        tries++;
00308        printDebug(DM_Lock, "Trying to lock the lock node:%x iteration:%d",cachedLockNode, tries);
00309    }
00310    printDebug(DM_Lock, "Mutex is waiting for long time:May be deadlock");
00311    printDebug(DM_Lock, "LockManager::getSharedLock End");
00312    printError(ErrLockTimeOut, "Unable to acquire lock for long time.Timed out");
00313    if (trans != NULL) (*trans)->removeWaitLock();
00314    return ErrLockTimeOut;
00315 
00316 }

Here is the call graph for this function:

Here is the caller graph for this function:

DbRetVal LockManager::isExclusiveLocked ( void *  tuple,
Transaction **  trans,
bool &  status 
)

Definition at line 582 of file LockManager.cxx.

References Bucket::bucketList_, DM_Lock, ErrLockTimeOut, Transaction::findInHasList(), Mutex::getLock(), LockHashNode::lInfo_, Bucket::mutex_, LockHashNode::next_, LockInfo::noOfReaders_, OK, printDebug, printError, Database::procSlot, LockHashNode::ptrToTuple_, Mutex::releaseLock(), and systemDatabase_.

Referenced by TableImpl::fetchNoBind().

00583 {
00584    Bucket *bucket = getLockBucket(tuple);
00585    printDebug(DM_Lock,"Bucket is %x", bucket);
00586    int lockRet = bucket->mutex_.getLock(systemDatabase_->procSlot);
00587    if (lockRet != 0)
00588    {
00589        printDebug(DM_Lock, "Mutex is waiting for long time:May be deadlock");
00590        printDebug(DM_Lock, "LockManager:releaseLock End");
00591        printError(ErrLockTimeOut, "Unable to get bucket mutex");
00592        return ErrLockTimeOut;
00593    }
00594    LockHashNode *lockNode = (LockHashNode*) bucket->bucketList_;
00595    if (NULL == lockNode)
00596    {
00597        bucket->mutex_.releaseLock(systemDatabase_->procSlot);
00598        printDebug(DM_Lock, "bucketList is empty. so data element not locked");
00599        status = false;
00600        return OK;
00601    }
00602 
00603    LockHashNode *iter = lockNode;
00604    //Iterate though the list and find the element's lock info
00605    //Only exclusive locks are checked. shared locks are not considered for this
00606    while(iter != NULL)
00607    {
00608        if(iter->ptrToTuple_ == tuple)
00609        {
00610            if (iter->lInfo_.noOfReaders_ == -1)
00611            {
00612                if (trans != NULL && (*trans)->findInHasList(systemDatabase_, iter))
00613                {
00614                    printDebug(DM_Lock, "You already have exclusive Lock: %x", iter);
00615                    status = false;
00616                }
00617                else 
00618                    status = true;
00619                bucket->mutex_.releaseLock(systemDatabase_->procSlot);
00620                return OK;
00621            }
00622        }
00623        printDebug(DM_Lock, "Finding the lock node. iter:%x",iter);
00624        iter = iter->next_;
00625    }
00626    bucket->mutex_.releaseLock(systemDatabase_->procSlot);
00627    status = false;
00628    return OK;
00629 }

Here is the call graph for this function:

Here is the caller graph for this function:

void LockManager::printDebugInfo (  ) 

Definition at line 57 of file LockManager.cxx.

References Bucket::bucketList_, Database::getLockHashBuckets(), Database::getSystemDatabaseChunk(), LOCK_BUCKET_SIZE, LockTableId, LockHashNode::next_, LockHashNode::print(), systemDatabase_, and Chunk::totalPages().

Referenced by DatabaseManagerImpl::printDebugLockInfo().

00058 {
00059    Bucket* buckets = systemDatabase_->getLockHashBuckets();
00060    Bucket* bucket;
00061    LockHashNode *lockNode;
00062    int nodeCount =0, bucketCount =0;
00063    printf("<LockTable>\n");
00064    for (int i =0; i< LOCK_BUCKET_SIZE; i++)
00065    {
00066        nodeCount =0;
00067        bucket = &(buckets[i]);
00068        //if (bucket) bucketCount++; else continue;
00069        lockNode = (LockHashNode*) bucket->bucketList_;
00070 
00071        while (NULL != lockNode) 
00072        { 
00073            nodeCount++; 
00074            lockNode->print();
00075            lockNode = lockNode->next_; 
00076        }
00077        if (nodeCount) {
00078            bucketCount++;
00079            printf("  <LockBucket> \n");
00080            printf("    <BucketNo> %d </BucketNo> \n", i); 
00081            printf("    <TotalNodes> %d </TotalNodes>\n", nodeCount); 
00082            printf("  <LockBucket>\n");
00083        }
00084    }
00085 
00086    printf("  <TotalUsedBuckets> %d </TotalUsedBuckets>\n", bucketCount); 
00087    Chunk *chunk = systemDatabase_->getSystemDatabaseChunk(LockTableId);
00088    printf("  <TotalPages> %d </TotalPages>\n", chunk->totalPages()); 
00089    printf("</LockTable>\n");
00090 
00091 }

Here is the call graph for this function:

Here is the caller graph for this function:

void LockManager::printUsageStatistics (  ) 

Definition at line 36 of file LockManager.cxx.

References Bucket::bucketList_, Database::getLockHashBuckets(), LOCK_BUCKET_SIZE, LockHashNode::next_, and systemDatabase_.

Referenced by DatabaseManagerImpl::printUsageStatistics().

00037 {
00038    Bucket* buckets = systemDatabase_->getLockHashBuckets();
00039    Bucket* bucket;
00040    LockHashNode *lockNode;
00041    int nodeCount =0, bucketCount =0;
00042    for (int i =0; i< LOCK_BUCKET_SIZE; i++)
00043    {
00044        bucket = &(buckets[i]);
00045        lockNode = (LockHashNode*) bucket->bucketList_;
00046        if (lockNode) bucketCount++; else continue;
00047        while (NULL != lockNode) { nodeCount++; lockNode = lockNode->next_; }
00048    }
00049    printf("<LockTable>\n");
00050    printf("  <TotalBuckets> %d  </TotalBuckets>\n", LOCK_BUCKET_SIZE);
00051    printf("  <UsedBuckets> %d  </UsedBuckets>\n", bucketCount);
00052    printf("  <TotalLockNodes> %d  </TotalLockNodes>\n", nodeCount);
00053    printf("</LockTable>\n");
00054 
00055 }

Here is the call graph for this function:

Here is the caller graph for this function:

DbRetVal LockManager::releaseLock ( void *  tuple  ) 

Definition at line 498 of file LockManager.cxx.

References Bucket::bucketList_, DM_Lock, ErrLockTimeOut, ErrSysFatal, Mutex::getLock(), LockHashNode::lInfo_, Bucket::mutex_, LockHashNode::next_, LockInfo::noOfReaders_, OK, printDebug, printError, Database::procSlot, LockHashNode::ptrToTuple_, Mutex::releaseLock(), systemDatabase_, LockInfo::waitReaders_, and LockInfo::waitWriters_.

Referenced by TableImpl::deleteTuple(), DatabaseManagerImpl::dropTable(), TableImpl::insertTuple(), Transaction::releaseAllLocks(), and TableImpl::updateTuple().

00499 {
00500    LockInfo linfo;
00501    linfo.noOfReaders_ = 0;
00502    //keeping it ready for the allocation, because when
00503    //lock node is not present in the list, then it means we are the first
00504    //to acquire lock so for sure we will get it.
00505    printDebug(DM_Lock, "LockManager:releaseLock Start");
00506    Bucket *bucket = getLockBucket(tuple);
00507    printDebug(DM_Lock,"Bucket is %x", bucket);
00508    int lockRet = bucket->mutex_.getLock(systemDatabase_->procSlot);
00509    if (lockRet != 0)
00510    {
00511        printDebug(DM_Lock, "Mutex is waiting for long time:May be deadlock");
00512        printDebug(DM_Lock, "LockManager:releaseLock End");
00513        printError(ErrLockTimeOut, "Unable to get bucket mutex");
00514        return ErrLockTimeOut;
00515    }
00516    LockHashNode *lockNode = (LockHashNode*) bucket->bucketList_;
00517    if (NULL == lockNode)
00518    {
00519        bucket->mutex_.releaseLock(systemDatabase_->procSlot);
00520        printDebug(DM_Lock, "LockManager:releaseLock End");
00521        printError(ErrSysFatal, "Lock Element Not found: Probable Data Corruption.\n");
00522        return ErrSysFatal;
00523    }
00524 
00525    LockHashNode *iter = lockNode;
00526    //Iterate though the list and find the element's lock info
00527    while(iter != NULL)
00528    {
00529        if(iter->ptrToTuple_ == tuple)
00530        {
00531 
00532            if (iter->lInfo_.noOfReaders_ == -1)
00533            {
00534                iter->lInfo_.noOfReaders_ = 0;
00535                if (iter->lInfo_.waitWriters_ == 0 || iter->lInfo_.waitReaders_ ==0)
00536                {
00537                    deallocLockNode(iter, bucket);
00538                    bucket->mutex_.releaseLock(systemDatabase_->procSlot);
00539                    printDebug(DM_Lock, "Releasing exclusive lock and dealloc node:%x",
00540                                                                                 iter);
00541                    printDebug(DM_Lock, "LockManager:releaseLock End");
00542                    return OK;
00543                }
00544                else
00545                {
00546                    bucket->mutex_.releaseLock(systemDatabase_->procSlot);
00547                    printDebug(DM_Lock, "Releasing exclusive lock");
00548                    printDebug(DM_Lock, "LockManager:releaseLock End");
00549                    return OK;
00550                }
00551            }
00552            else if (iter->lInfo_.noOfReaders_ == 1)
00553            {
00554                iter->lInfo_.noOfReaders_ = 0;
00555                if (iter->lInfo_.waitWriters_ == 0 || iter->lInfo_.waitReaders_ ==0)
00556                {
00557                    deallocLockNode(iter, bucket);
00558                    bucket->mutex_.releaseLock(systemDatabase_->procSlot);
00559                    printDebug(DM_Lock, "Releasing read lock and dealloc node:%x",iter);
00560                    printDebug(DM_Lock, "LockManager:releaseLock End");
00561                    return OK;
00562                }
00563            }
00564            else
00565            {
00566                iter->lInfo_.noOfReaders_--;
00567                bucket->mutex_.releaseLock(systemDatabase_->procSlot);
00568                printDebug(DM_Lock, "Decrementing read lock:%x",iter);
00569                printDebug(DM_Lock, "LockManager:releaseLock End");
00570                return OK;
00571            }
00572 
00573        }
00574        printDebug(DM_Lock, "Finding the lock node. iter:%x",iter);
00575        iter = iter->next_;
00576    }
00577    bucket->mutex_.releaseLock(systemDatabase_->procSlot);
00578    printError(ErrSysFatal, "Lock Element Not found: Probable Data Corruption");
00579    return ErrSysFatal;
00580 }

Here is the call graph for this function:

Here is the caller graph for this function:


Field Documentation

Database* LockManager::systemDatabase_

Definition at line 78 of file Lock.h.

Referenced by TransactionManager::commit(), getExclusiveLock(), getSharedLock(), isExclusiveLocked(), LockManager(), printDebugInfo(), printUsageStatistics(), Transaction::releaseAllLocks(), releaseLock(), TransactionManager::rollback(), and TransactionManager::startTransaction().


The documentation for this class was generated from the following files:
Generated on Mon Jun 9 22:48:35 2008 for csql by  doxygen 1.4.7