Package org.chaidb.db.lock

Source Code of org.chaidb.db.lock.Lock

/*
* Copyright (C) 2006  http://www.chaidb.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
*/

package org.chaidb.db.lock;

import org.apache.log4j.Logger;
import org.chaidb.db.exception.ChaiDBException;
import org.chaidb.db.exception.ErrorCode;

/**
* The lock class
*/
public class Lock {
    /**
     * locker held this lock
     */
    int lockerId;
    /**
     * object this lock applies to
     */
    LockableObject object;
    /**
     * mode of this lock, for the constant of mode ,pls refer to LockManager
     */
    int mode;
    /**
     * reference count on this lock
     */
    int refCount;
    /**
     * status of this lock
     */
    int status;
    /**
     * Free list or holder/waiter list.
     */
    Lock links;
    /**
     * List of locks held by a locker.
     */
    Lock locker_links;
    /**
     * the flag of notified
     */
    private boolean bNotified;

    private boolean keepLockAutoCommit;//keep the read lock when autocommit = false;

    public String ThreadName;
    /**
     * Lock's status
     */
    public static final int LSTAT_FREE = 0;   // Lock is unallocated.
    public static final int LSTAT_ABORTED = 1;//Lock belongs to an aborted txn.
    public static final int LSTAT_ERR = 2;    //Lock is bad
    public static final int LSTAT_HELD = 3;   // Lock is currently held.
    public static final int LSTAT_NOGRANT = 4;// Lock is not granted.
    public static final int LSTAT_PENDING = 5;//Lock is waiting and has been promoted;
    //waiting for the owner to run and upgrade it to held
    public static final int LSTAT_WAITING = 6;// Lock is one the wait queue

    // invalid lock mode constant
    public static final int LOCK_INVALID = -1;

    private static final Logger logger = Logger.getLogger(Lock.class);

    /**
     * Constructor
     */
    public Lock() {
        reset();
    }

    /**
     * set the member variable to initial state
     */
    public void reset() {
        lockerId = 0;
        object = null;
        mode = LOCK_INVALID;
        refCount = 0;
        status = LSTAT_FREE;
        locker_links = null;
        links = null;
        bNotified = false;
        keepLockAutoCommit = false;
        ThreadName = null;
    }

    public void setKeepLockAutoCommit(boolean flag) {
        this.keepLockAutoCommit = flag;
    }

    public boolean getKeepLockAutoCommit() {
        return this.keepLockAutoCommit;
    }

    //block the thread that hold this lock
    synchronized void lock() throws ChaiDBException {
        try {
            if (!bNotified) wait();
        } catch (InterruptedException e) {
            String errMessage = "The waiting lock is interrupted" + e.getMessage();
            logger.error(errMessage);
            throw new ChaiDBException(ErrorCode.LOCK_INTERRUPTED, errMessage);
        }
    }

    //notify the thread that hold this lock
    synchronized void unlock() {
        bNotified = true;
        notify();
    }

    public String toString() {
        String mode, status;
        StringBuffer sbuf = new StringBuffer();
        switch (this.mode) {
            case LockManager.LOCK_NG:
                mode = "NG";
                break;
            case LockManager.LOCK_READ:
                mode = "READ";
                break;
            case LockManager.LOCK_WRITE:    // Exclusive/write.
                mode = "WRITE";
                break;
            case LockManager.LOCK_WAIT:      //Wait event
                mode = "WAIT";
                break;
            case LockManager.LOCK_IWRITE:    // Intent exclusive/write.
                mode = "IWRITE";
                break;
            case LockManager.LOCK_IREAD:    // Intent to share/read.
                mode = "IREAD";
                break;
            case LockManager.LOCK_IWR:    // Intent to read and write.
                mode = "IWR";
                break;
            default:
                mode = "UNKNOWN";
                break;
        }

        switch (this.status) {
            case LSTAT_FREE:
                status = "FREE";
                break;
            case LSTAT_ABORTED:
                status = "ABORT";
                break;
            case LSTAT_ERR:
                status = "ERROR";
                break;
            case LSTAT_HELD:
                status = "HELD";
                break;
            case LSTAT_NOGRANT:
                status = "NONE";
                break;
            case LSTAT_WAITING:
                status = "WAIT";
                break;
            case LSTAT_PENDING:
                status = "PENDING";
                break;
            default:
                status = "UNKNOWN";
                break;
        }
        String lineSep = System.getProperty("line.separator");
        sbuf.append("<lock>").append(lineSep)
                .append("<lockerid>").append(lockerId).append("</lockerid>").append(lineSep)
                .append("<mode>").append(mode).append("</mode>").append(lineSep)
                .append("<status>").append(status).append("</status>").append(lineSep)
                .append("<Thread>").append(this.ThreadName).append("</Thread>").append(lineSep)
                .append("<refcount>").append(refCount).append("</refcount>").append(lineSep);
        if ((object != null) && (object.lockObject != null)) sbuf.append(object.lockObject);
        else sbuf.append("<object>null</object>").append(lineSep);
        sbuf.append("</lock>").append(lineSep);
        return sbuf.toString();
    }

    public int getRefCount() {
        return this.refCount;
    }

    /**
     * get locker Id
     */
    public int getLockerId() {
        return lockerId;
    }

    /**
     * get locked object type
     */
    public byte getLockObjectType() {
        if ((object != null) && (object.lockObject != null)) return object.lockObject.getType();
        else return -1;
    }

    /**
     * get locked object
     */
    public Object getLockObject() {
        if ((object != null) && (object.lockObject != null)) return object.lockObject.getObject();
        else return null;
    }

    /**
     * add by leon for debug
     *
     * @return id of object locked by this lock
     */
    public long getLockID() {
        if ((object != null) && (object.lockObject != null)) return object.lockObject.getId();
        else return -1;
    }

    /**
     * get the lock mode
     *
     * @return mode of lock
     */
    public int getMode() {
        return mode;
    }
}
TOP

Related Classes of org.chaidb.db.lock.Lock

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.