解决setcallback 时可能出现的并发问题 DUBBO-750
git-svn-id: http://code.alibabatech.com/svn/dubbo/trunk@43 1a56cb94-b969-4eaa-88fa-be21384802f2
This commit is contained in:
parent
3f34281f80
commit
6ffe440029
|
|
@ -38,7 +38,8 @@ import com.alibaba.dubbo.remoting.exchange.Response;
|
|||
/**
|
||||
* DefaultFuture.
|
||||
*
|
||||
* @author qian.lei
|
||||
* @author qian.lei
|
||||
* @author chao.liuc
|
||||
*/
|
||||
public class DefaultFuture implements ResponseFuture {
|
||||
|
||||
|
|
@ -110,8 +111,9 @@ public class DefaultFuture implements ResponseFuture {
|
|||
}
|
||||
|
||||
public void cancel(){
|
||||
response = new Response(id);
|
||||
response.setErrorMessage("request future has been canceled.");
|
||||
Response errorResult = new Response(id);
|
||||
errorResult.setErrorMessage("request future has been canceled.");
|
||||
response = errorResult ;
|
||||
FUTURES.remove(id);
|
||||
CHANNELS.remove(id);
|
||||
}
|
||||
|
|
@ -120,16 +122,39 @@ public class DefaultFuture implements ResponseFuture {
|
|||
return response != null;
|
||||
}
|
||||
|
||||
public void setCallback(ResponseCallback callback) {
|
||||
if (isDone()) {
|
||||
try {
|
||||
callback.done(returnFromResponse());
|
||||
} catch (Throwable e) {
|
||||
callback.caught(e);
|
||||
}
|
||||
} else {
|
||||
this.callback = callback;
|
||||
public void setCallback(ResponseCallback callback) {
|
||||
if (isDone()) {
|
||||
invokeCallback(callback);
|
||||
} else {
|
||||
boolean isdone = false;
|
||||
lock.lock();
|
||||
try{
|
||||
if (!isDone()) {
|
||||
this.callback = callback;
|
||||
} else {
|
||||
isdone = true;
|
||||
}
|
||||
}finally {
|
||||
lock.unlock();
|
||||
}
|
||||
if (isdone){
|
||||
invokeCallback(callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
private void invokeCallback(ResponseCallback c){
|
||||
if (c == null){
|
||||
throw new NullPointerException("callback cannot be null.");
|
||||
}
|
||||
ResponseCallback callbackCopy = c;
|
||||
c = null;
|
||||
Object result = null;
|
||||
try {
|
||||
result = returnFromResponse();
|
||||
} catch (Throwable e) {
|
||||
callbackCopy.caught(e);
|
||||
}
|
||||
callbackCopy.done(result);
|
||||
}
|
||||
|
||||
private long getId() {
|
||||
|
|
@ -198,14 +223,8 @@ public class DefaultFuture implements ResponseFuture {
|
|||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
ResponseCallback c = callback;
|
||||
if (c != null) {
|
||||
try {
|
||||
c.done(returnFromResponse());
|
||||
} catch (Throwable e) {
|
||||
c.caught(e);
|
||||
}
|
||||
callback = null;
|
||||
if (callback != null) {
|
||||
invokeCallback(callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -217,8 +236,6 @@ public class DefaultFuture implements ResponseFuture {
|
|||
if (res.getStatus() == Response.CLIENT_TIMEOUT || res.getStatus() == Response.SERVER_TIMEOUT) {
|
||||
throw new TimeoutException(res.getStatus() == Response.SERVER_TIMEOUT, channel, res.getErrorMessage());
|
||||
}
|
||||
FUTURES.remove(id);
|
||||
CHANNELS.remove(id);
|
||||
throw new RemotingException(channel, res.getErrorMessage());
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue