lockhandleradapter.java
来自「java版ace,java程序员值得一看」· Java 代码 · 共 381 行
JAVA
381 行
package JACE.netsvcs.Token;
import java.util.*;
import JACE.ASX.*;
import JACE.OS.*;
import JACE.Concurrency.*;
/**
* LockHandler implementation for any AbstractLock.
* <P>
* Provides the dispatching to appropriate methods on an AbstractLock
* as requests come in.
*/
public class LockHandlerAdapter implements LockHandler
{
/**
* Constructor taking an AbstractLock to use as the locking
* mechanism the requests work on.
*/
public LockHandlerAdapter (AbstractLock lock)
{
lock_ = lock;
}
/**
* Default constructor.
*/
public LockHandlerAdapter ()
{
lock_ = null;
}
/**
* Dispatch the request according to its type, calling the
* appropriate methods on the AbstractLock member.
*
*@param caller TokenRequestHandler which called handleRequest (unused)
*@param request request to process
*@return appropriate reply to send to the client
*/
public TokenReply handleRequest (TokenRequestHandler caller,
TokenRequest request)
{
String client = request.clientID ();
String token = request.tokenName ();
TokenReply result = null;
// Dispatch according to operation type
switch (request.operationType ())
{
case LockOperations.ACQUIRE:
ACE.DEBUG (client + " begins ACQUIRE for " + token);
result = acquireDispatcher (request);
break;
case LockOperations.RELEASE:
ACE.DEBUG (client + " begins RELEASE for " + token);
result = release (request);
break;
case LockOperations.RENEW:
ACE.DEBUG (client + " begins RENEW for " + token);
result = renew (request);
break;
case LockOperations.REMOVE:
ACE.DEBUG (client + " begins REMOVE for " + token);
result = remove (request);
break;
case LockOperations.TRY_ACQUIRE:
ACE.DEBUG (client + " begins TRY_ACQUIRE for " + token);
result = tryAcquireDispatcher (request);
break;
default:
ACE.ERROR ("Unknown operation: " + request.operationType ());
break;
}
ACE.DEBUG (client + " result: " + result);
return result;
}
/**
* Create a TimeValue from the given request's timeout information. Note
* that the time in the request is an absolute time timeout.
*
*@param request request to obtain the timeout info from
*@return null if useTimeout is false, otherwise a TimeValue
* representing the appropriate time period
*/
protected TimeValue getTimeout (TokenRequest request)
{
if (request.useTimeout ())
return new TimeValue (request.sec (),
request.usec () * 1000);
else
return null;
}
/**
* Call acquireWrite on the lock, returning its return value.
*
*@see AbstractLock#acquireWrite
*@return value from the lock's operation
*/
protected int acquireWrite (TokenRequest request, TimeValue timeout)
throws LockException, TimeoutException, InterruptedException
{
int result;
if (timeout != null)
result = lock_.acquireWrite (timeout);
else
result = lock_.acquireWrite ();
return result;
}
/**
* Call acquireRead on the lock, returning its return value.
*
*@see AbstractLock#acquireRead
*@return value from the lock's operation
*/
protected int acquireRead (TokenRequest request, TimeValue timeout)
throws LockException, TimeoutException, InterruptedException
{
int result;
if (timeout != null)
result = lock_.acquireRead (timeout);
else
result = lock_.acquireRead ();
return result;
}
/**
* Call acquire on the lock, returning its return value.
*
*@see AbstractLock#acquire
*@return value from the lock's operation
*/
protected int acquire (TokenRequest request, TimeValue timeout)
throws LockException, TimeoutException, InterruptedException
{
int result;
if (timeout != null)
result = lock_.acquire (timeout);
else
result = lock_.acquire ();
return result;
}
/**
* Dispatch to the appropriate acquire method. In C++ ACE, when
* the type is LockTypes.RWLOCK and the proxy type is
* LockTypes.WRITE_LOCK_PROXY, then this calls acquireWrite.
* If it's RWLOCK and the proxy is READ_LOCK_PROXY, it calls
* acquireRead. In the normal case, it just calls acquire.
*
*@return reply to be sent back to the client (values for errno
* include constants in TokenReply such as EFAULT, ETIME,
* EINTR, or NO_ERRORS)
*/
protected TokenReply acquireDispatcher (TokenRequest request)
{
int result;
TimeValue timeout = getTimeout (request);
try {
/*
ACE specifies that when requesting a reader lock, the
token type will be RWLOCK and the proxy type is 0.
When it's a writer lock, the proxy type is 1.
*/
if (request.tokenType () == LockTypes.RWLOCK) {
if (request.proxyType () == LockTypes.READ_LOCK_PROXY)
result = acquireRead (request, timeout);
else
result = acquireWrite (request, timeout);
} else
result = acquire (request, timeout);
} catch (LockException e) {
return new TokenReply (TokenReply.EFAULT,
request.arg ());
} catch (TimeoutException e) {
return new TokenReply (TokenReply.ETIME,
request.arg ());
} catch (InterruptedException e) {
return new TokenReply (TokenReply.EINTR,
request.arg ());
}
if (result == AbstractLock.FAILURE) {
return new TokenReply (TokenReply.EFAULT,
request.arg ());
} else {
return new TokenReply (TokenReply.NO_ERRORS,
request.arg ());
}
}
/**
* Process a release request and construct a reply. The values
* for errno include TokenReply constants EFAULT, EACCES, or
* NO_ERRORS.
*/
protected TokenReply release (TokenRequest request)
{
int result;
try {
result = lock_.release ();
} catch (LockException e) {
return new TokenReply (TokenReply.EFAULT,
request.arg ());
}
if (result == AbstractLock.FAILURE) {
return new TokenReply (TokenReply.EACCES,
request.arg ());
} else {
return new TokenReply (TokenReply.NO_ERRORS,
request.arg ());
}
}
/**
* Process a renew request and construct a reply. The values for
* errno include TokenReply constants EFAULT, ETIME, EINTR, EACCES,
* or NO_ERRORS.
*/
protected TokenReply renew (TokenRequest request)
{
int result = AbstractLock.FAILURE;
TimeValue timeout = getTimeout (request);
try {
if (timeout != null) {
result = lock_.renew (request.requeuePosition (),
timeout);
} else {
result = lock_.renew (request.requeuePosition ());
}
} catch (LockException e) {
return new TokenReply (TokenReply.EFAULT,
request.arg ());
} catch (TimeoutException e) {
return new TokenReply (TokenReply.ETIME,
request.arg ());
} catch (InterruptedException e) {
return new TokenReply (TokenReply.EINTR,
request.arg ());
}
if (result == AbstractLock.FAILURE) {
return new TokenReply (TokenReply.EACCES,
request.arg ());
} else {
return new TokenReply (TokenReply.NO_ERRORS,
request.arg ());
}
}
/**
* Process a remove request and construct a reply. This currently
* is not supported in the normal AbstractLock interface, so the
* default implementation returns a reply with errno set to
* TokenReply.ENOTSUP.
*/
protected TokenReply remove (TokenRequest request)
{
ACE.ERROR ("Remove is unimplemented");
return new TokenReply (TokenReply.ENOTSUP,
request.arg ());
}
/**
* Call tryAcquireWrite on the lock, returning the result.
*/
protected int tryAcquireWrite (TokenRequest request)
throws LockException
{
return lock_.tryAcquireWrite ();
}
/**
* Call tryAcquireRead on the lock, returning the result.
*/
protected int tryAcquireRead (TokenRequest request)
throws LockException
{
return lock_.tryAcquireRead ();
}
/**
* Call tryAcquire on the lock, returning the result.
*/
protected int tryAcquire (TokenRequest request) throws LockException
{
return lock_.tryAcquire ();
}
/**
* Dispatch to the appropriate tryAcquire method. In C++ ACE, when
* the type is LockTypes.RWLOCK and the proxy type is
* LockTypes.WRITE_LOCK_PROXY, then this calls acquireWrite.
* If it's RWLOCK and the proxy is READ_LOCK_PROXY, it calls
* acquireRead. In the normal case, it just calls acquire.
*
*@return reply to be sent back to the client (values for errno
* include constants in TokenReply such as EFAULT,
* EWOULDBLOCK, or NO_ERRORS).
*/
protected TokenReply tryAcquireDispatcher (TokenRequest request)
{
int result;
try {
/*
ACE specifies that when requesting a reader lock, the
token type will be RWLOCK and the proxy type is 0.
When it's a writer lock, the proxy type is 1.
*/
if (request.tokenType () == LockTypes.RWLOCK) {
if (request.proxyType () == LockTypes.READ_LOCK_PROXY)
result = tryAcquireRead (request);
else
result = tryAcquireWrite (request);
} else
result = tryAcquire (request);
} catch (LockException e) {
return new TokenReply (TokenReply.EFAULT,
request.arg ());
}
if (result == AbstractLock.FAILURE) {
return new TokenReply (TokenReply.EWOULDBLOCK,
request.arg ());
} else {
return new TokenReply (TokenReply.NO_ERRORS,
request.arg ());
}
}
/**
* Abandon any claim the specified client has on the lock.
*
*@param clientID identification of the client
*/
public void abandonLock (String clientID)
{
ACE.DEBUG (clientID + " abandoning lock");
try {
int nesting_level = 0;
while (lock_.release () != AbstractLock.FAILURE)
{
nesting_level++;
// Loop until not the owner in case the lock
// supports nested acquires
}
if (nesting_level == 0)
ACE.DEBUG (clientID + " was not the owner");
else
ACE.DEBUG (clientID + " had " + nesting_level + " locks");
} catch (LockException e) {
ACE.ERROR ("While abandoning lock: " + e.getMessage ());
// Don't need to send a reply to the client
}
}
protected AbstractLock lock_;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?