// ********************************************************************** // // 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__(); } } }