001    package edu.rice.cs.cunit.record.graph;
002    
003    import com.sun.jdi.IncompatibleThreadStateException;
004    import com.sun.jdi.ObjectReference;
005    import com.sun.jdi.ThreadReference;
006    
007    import java.util.HashSet;
008    import java.util.Set;
009    
010    /**
011     * Information about a lock.
012     *
013     * @author Mathias Ricken
014     */
015    public class LockInfo {
016        /**
017         * Unique id of this object.
018         */
019        long _uniqueId;
020    
021        /**
022         * Description of this lock.
023         */
024        String _description;
025    
026        /**
027         * Unique id of thread that owns this lock.
028         */
029        Long _owningThreadId;
030    
031        /**
032         * Set of unique ids of the threads that wait for this lock.
033         */
034        Set<Long> _waitingThreadIds;
035    
036        /**
037         * Constructor for lock information.
038         * @param uniqueId lock's unique id
039         * @param description description of the lock
040         * @param owningThreadId unique id of thread owning this lock
041         * @param waitingThreadIds set of unique ids of the threads waiting for this lock
042         */
043        public LockInfo(Long uniqueId, String description, long owningThreadId, Set<Long> waitingThreadIds) {
044            _uniqueId = uniqueId;
045            _description = description;
046            _owningThreadId = owningThreadId;
047            _waitingThreadIds = new HashSet<Long>(waitingThreadIds);
048        }
049    
050        /**
051         * Constructor for lock information.
052         * @param objRef ObjectReference for lock
053         */
054        public LockInfo(ObjectReference objRef) {
055            _uniqueId = objRef.uniqueID();
056            _description = objRef.type().toString();
057            _waitingThreadIds = new HashSet<Long>();
058            try {
059                ThreadReference threadRef = objRef.owningThread();
060                if (threadRef!=null) {
061                    _owningThreadId = threadRef.uniqueID();
062                }
063                else {
064                    _owningThreadId = null;
065                }
066                for(ThreadReference tr:objRef.waitingThreads()) {
067                    _waitingThreadIds.add(tr.uniqueID());
068                }
069            }
070            catch(IncompatibleThreadStateException e) {
071                throw new RuntimeException(e);
072            }
073        }
074    
075        /**
076         * Returns the unique id.
077         * @return unique id
078         */
079        public long getUniqueId() {
080            return _uniqueId;
081        }
082    
083        /**
084         * Returns the unique id of the owning thread, or null if not owned.
085         * @return owning thread id, or null if not owned
086         */
087        public Long getOwningThreadId() {
088            return _owningThreadId;
089        }
090    
091        /**
092         * Sets the unique id of the owning thread, or null if not owned.
093         * @param owningThreadId owning thread id, or null if not owned
094         */
095        public void setOwningThreadId(Long owningThreadId) {
096            _owningThreadId = owningThreadId;
097        }
098    
099        /**
100         * Returns a list of unique ids of the threads waiting for this lock
101         * @return set of unique ids
102         */
103        public Set<Long> getWaitingThreadIds() {
104            return _waitingThreadIds;
105        }
106    
107        /**
108         * Returns the description.
109         * @return description.
110         */
111        public String getDescription() {
112            return _description;
113        }
114    
115        /**
116         * Returns a string representation of the object.
117         *
118         * @return a string representation of the object.
119         */
120        public String toString() {
121            StringBuilder sb = new StringBuilder();
122            sb.append(_description);
123            sb.append(" (id=");
124            sb.append(_uniqueId);
125            if (_owningThreadId!=null) {
126                sb.append("), owned by thread id=");
127                sb.append(_owningThreadId);
128            }
129            else {
130                sb.append("), not owned");
131            }
132            if (_waitingThreadIds.size()==0) {
133                sb.append(", not contended");
134            }
135            else
136            {
137                sb.append(", contended by thread ids=");
138                boolean first = true;
139                for (Long id:_waitingThreadIds) {
140                    if (!first) {
141                        sb.append(", ");
142                    }
143                    else {
144                        first = false;
145                    }
146                    sb.append(id);
147                }
148            }
149            return sb.toString();
150        }
151    }