// **********************************************************************
//
// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved.
//
// This copy of Ice is licensed to you under the terms described in the
// ICE_LICENSE file included in this distribution.
//
// **********************************************************************
namespace IceInternal
{
using System.Diagnostics;
public class IncomingAsync : IncomingBase, Ice.AMDCallback
{
public IncomingAsync(Incoming inc)
: base(inc)
{
_retriable = inc.isRetriable();
if(_retriable)
{
inc.setActive(this);
_active = true;
}
}
virtual public void ice_exception(System.Exception ex)
{
//
// Only call exception__ if this incoming is not retriable or if
// all the interceptors return true and no response has been sent
// yet.
//
if(_retriable)
{
try
{
if(interceptorAsyncCallbackList_ != null)
{
foreach(Ice.DispatchInterceptorAsyncCallback cb in interceptorAsyncCallbackList_)
{
if(cb.exception(ex) == false)
{
return;
}
}
}
}
catch(System.Exception)
{
return;
}
lock(this)
{
if(!_active)
{
return;
}
_active = false;
}
}
if(responseHandler_ != null)
{
exception__(ex);
}
else
{
//
// Response has already been sent.
//
if(instance_.initializationData().properties.getPropertyAsIntWithDefault("Ice.Warn.Dispatch", 1) > 0)
{
warning__(ex);
}
}
}
internal void deactivate__(Incoming inc)
{
Debug.Assert(_retriable);
lock(this)
{
if(!_active)
{
//
// Since __deactivate can only be called on an active object,
// this means the response has already been sent (see validateXXX below)
//
throw new Ice.ResponseSentException();
}
_active = false;
}
inc.adopt(this);
}
protected void response__()
{
try
{
if(locator_ != null && !servantLocatorFinished__(true))
{
return;
}
Debug.Assert(responseHandler_ != null);
if(response_)
{
if(observer_ != null)
{
observer_.reply(os_.size() - Protocol.headerSize - 4);
}
responseHandler_.sendResponse(current_.requestId, os_, compress_, true);
}
else
{
responseHandler_.sendNoResponse();
}
if(observer_ != null)
{
observer_.detach();
observer_ = null;
}
responseHandler_ = null;
}
catch(Ice.LocalException ex)
{
responseHandler_.invokeException(current_.requestId, ex, 1, true);
}
}
protected internal void exception__(System.Exception exc)
{
try
{
if(locator_ != null && !servantLocatorFinished__(true))
{
return;
}
handleException__(exc, true);
}
catch(Ice.LocalException ex)
{
responseHandler_.invokeException(current_.requestId, ex, 1, true);
}
}
protected internal BasicStream getOs__()
{
return os_;
}
protected bool validateResponse__(bool ok)
{
//
// Only returns true if this incoming is not retriable or if all
// the interceptors return true and no response has been sent
// yet. Upon getting a true return value, the caller should send
// the response.
//
if(_retriable)
{
try
{
if(interceptorAsyncCallbackList_ != null)
{
foreach(Ice.DispatchInterceptorAsyncCallback cb in interceptorAsyncCallbackList_)
{
if(cb.response(ok) == false)
{
return false;
}
}
}
}
catch(System.Exception)
{
return false;
}
lock(this)
{
if(!_active)
{
return false;
}
_active = false;
}
}
return true;
}
private readonly bool _retriable;
private bool _active = false; // only meaningful when _retriable == true
}
}
namespace Ice
{
///
/// Callback interface for Blobject AMD servants.
///
public interface AMD_Object_ice_invoke : Ice.AMDCallback
{
///
/// Indicates to the Ice run time that an operation
/// completed.
///
/// True indicates that the operation
/// completed successfully; false indicates that the
/// operation raised a user exception.
/// The encoded out-parameters for the operation or,
/// if ok is false, the encoded user exception.
void ice_response(bool ok, byte[] outEncaps);
}
sealed class _AMD_Object_ice_invoke : IceInternal.IncomingAsync, AMD_Object_ice_invoke
{
public _AMD_Object_ice_invoke(IceInternal.Incoming inc)
: base(inc)
{
}
public void ice_response(bool ok, byte[] outEncaps)
{
try
{
writeParamEncaps__(outEncaps, ok);
}
catch(Ice.LocalException ex)
{
exception__(ex);
return;
}
response__();
}
}
}