1 /******************************************************************************* 2 * Copyright (c) 2003, 2006 IBM Corporation and others. 3 * All rights reserved. This program and the accompanying materials 4 * are made available under the terms of the Eclipse Public License v1.0 5 * which accompanies this distribution, and is available at 6 * http://www.eclipse.org/legal/epl-v10.html 7 * 8 * Contributors: 9 * IBM - Initial API and implementation 10 *******************************************************************************/ 11 package org.eclipse.core.runtime.jobs; 12 13 /** 14 * A lock is used to control access to an exclusive resource. 15 * <p> 16 * Locks are reentrant. That is, they can be acquired multiple times by the same thread 17 * without releasing. Locks are only released when the number of successful acquires 18 * equals the number of successful releases. 19 * </p><p> 20 * Locks are capable of detecting and recovering from programming errors that cause 21 * circular waiting deadlocks. When a deadlock between two or more <tt>ILock</tt> 22 * instances is detected, detailed debugging information is printed to the log file. The 23 * locks will then automatically recover from the deadlock by employing a release 24 * and wait strategy. One thread will lose control of the locks it owns, thus breaking 25 * the deadlock and allowing other threads to proceed. Once that thread's locks are 26 * all available, it will be given exclusive access to all its locks and allowed to proceed. 27 * A thread can only lose locks while it is waiting on an <tt>acquire()</tt> call. 28 * 29 * </p><p> 30 * Successive acquire attempts by different threads are queued and serviced on 31 * a first come, first served basis. 32 * </p><p> 33 * It is very important that acquired locks eventually get released. Calls to release 34 * should be done in a finally block to ensure they execute. For example: 35 * <pre> 36 * try { 37 * lock.acquire(); 38 * // ... do work here ... 39 * } finally { 40 * lock.release(); 41 * } 42 * </pre> 43 * Note: although <tt>lock.acquire</tt> should never fail, it is good practice to place 44 * it inside the try block anyway. Releasing without acquiring is far less catastrophic 45 * than acquiring without releasing. 46 * </p><p> 47 * This interface is not intended to be implemented by clients. 48 * </p> 49 * @see IJobManager#newLock() 50 * @since 3.0 51 */ 52 public interface ILock { 53 /** 54 * Attempts to acquire this lock. If the lock is in use and the specified delay is 55 * greater than zero, the calling thread will block until one of the following happens: 56 * <ul> 57 * <li>This lock is available</li> 58 * <li>The thread is interrupted</li> 59 * <li>The specified delay has elapsed</li> 60 * </ul> 61 * <p> 62 * While a thread is waiting, locks it already owns may be granted to other threads 63 * if necessary to break a deadlock. In this situation, the calling thread may be blocked 64 * for longer than the specified delay. On returning from this call, the calling thread 65 * will once again have exclusive access to any other locks it owned upon entering 66 * the acquire method. 67 * 68 * @param delay the number of milliseconds to delay 69 * @return <code>true</code> if the lock was successfully acquired, and 70 * <code>false</code> otherwise. 71 * @exception InterruptedException if the thread was interrupted 72 */ 73 public boolean acquire(long delay) throws InterruptedException; 74 75 /** 76 * Acquires this lock. If the lock is in use, the calling thread will block until the lock 77 * becomes available. If the calling thread owns several locks, it will be blocked 78 * until all threads it requires become available, or until the thread is interrupted. 79 * While a thread is waiting, its locks may be granted to other threads if necessary 80 * to break a deadlock. On returning from this call, the calling thread will 81 * have exclusive access to this lock, and any other locks it owned upon 82 * entering the acquire method. 83 * <p> 84 * This implementation ignores attempts to interrupt the thread. If response to 85 * interruption is needed, use the method <code>acquire(long)</code> 86 */ 87 public void acquire(); 88 89 /** 90 * Returns the number of nested acquires on this lock that have not been released. 91 * This is the number of times that release() must be called before the lock is 92 * freed. 93 * 94 * @return the number of nested acquires that have not been released 95 */ 96 public int getDepth(); 97 98 /** 99 * Releases this lock. Locks must only be released by the thread that currently 100 * owns the lock. 101 */ 102 public void release(); 103 } 104