bool OutgoingAsync::completed() { // // NOTE: this method is called from ConnectionI.parseMessage // with the connection locked. Therefore, it must not invoke // any user callbacks. // assert(_proxy->ice_isTwoway()); // Can only be called for twoways. if(_childObserver) { _childObserver->reply(static_cast<Int>(_is.b.size() - headerSize - 4)); _childObserver.detach(); } Byte replyStatus; try { _is.read(replyStatus); switch(replyStatus) { case replyOK: { break; } case replyUserException: { _observer.userException(); break; } case replyObjectNotExist: case replyFacetNotExist: case replyOperationNotExist: { Identity ident; _is.read(ident); // // For compatibility with the old FacetPath. // vector<string> facetPath; _is.read(facetPath); string facet; if(!facetPath.empty()) { if(facetPath.size() > 1) { throw MarshalException(__FILE__, __LINE__); } facet.swap(facetPath[0]); } string operation; _is.read(operation, false); IceUtil::UniquePtr<RequestFailedException> ex; switch(replyStatus) { case replyObjectNotExist: { ex.reset(new ObjectNotExistException(__FILE__, __LINE__)); break; } case replyFacetNotExist: { ex.reset(new FacetNotExistException(__FILE__, __LINE__)); break; } case replyOperationNotExist: { ex.reset(new OperationNotExistException(__FILE__, __LINE__)); break; } default: { assert(false); break; } } ex->id = ident; ex->facet = facet; ex->operation = operation; ex->ice_throw(); } case replyUnknownException: case replyUnknownLocalException: case replyUnknownUserException: { string unknown; _is.read(unknown, false); IceUtil::UniquePtr<UnknownException> ex; switch(replyStatus) { case replyUnknownException: { ex.reset(new UnknownException(__FILE__, __LINE__)); break; } case replyUnknownLocalException: { ex.reset(new UnknownLocalException(__FILE__, __LINE__)); break; } case replyUnknownUserException: { ex.reset(new UnknownUserException(__FILE__, __LINE__)); break; } default: { assert(false); break; } } ex->unknown = unknown; ex->ice_throw(); } default: { throw UnknownReplyStatusException(__FILE__, __LINE__); } } return finished(replyStatus == replyOK); } catch(const Exception& ex) { return completed(ex); } }
ConnectionIPtr IceInternal::OutgoingConnectionFactory::create(const vector<EndpointIPtr>& endpts, bool hasMore, Ice::EndpointSelectionType selType, bool& compress) { assert(!endpts.empty()); // // Apply the overrides. // vector<EndpointIPtr> endpoints = applyOverrides(endpts); // // Try to find a connection to one of the given endpoints. // Ice::ConnectionIPtr connection = findConnection(endpoints, compress); if(connection) { return connection; } IceUtil::UniquePtr<Ice::LocalException> exception; // // If we didn't find a connection with the endpoints, we create the connectors // for the endpoints. // vector<ConnectorInfo> connectors; for(vector<EndpointIPtr>::const_iterator p = endpoints.begin(); p != endpoints.end(); ++p) { // // Create connectors for the endpoint. // try { vector<ConnectorPtr> cons = (*p)->connectors(selType); assert(!cons.empty()); for(vector<ConnectorPtr>::const_iterator r = cons.begin(); r != cons.end(); ++r) { assert(*r); connectors.push_back(ConnectorInfo(*r, *p)); } } catch(const Ice::LocalException& ex) { exception.reset(ex.ice_clone()); handleException(ex, hasMore || p != endpoints.end() - 1); } } if(connectors.empty()) { assert(exception.get()); exception->ice_throw(); } // // Try to get a connection to one of the connectors. A null result indicates that no // connection was found and that we should try to establish the connection (and that // the connectors were added to _pending to prevent other threads from establishing // the connection). // connection = getConnection(connectors, 0, compress); if(connection) { return connection; } // // Try to establish the connection to the connectors. // DefaultsAndOverridesPtr defaultsAndOverrides = _instance->defaultsAndOverrides(); const CommunicatorObserverPtr& obsv = _instance->getObserver(); vector<ConnectorInfo>::const_iterator q; for(q = connectors.begin(); q != connectors.end(); ++q) { ObserverPtr observer; if(obsv) { observer = obsv->getConnectionEstablishmentObserver(q->endpoint, q->connector->toString()); if(observer) { observer->attach(); } } try { connection = createConnection(q->connector->connect(), *q); connection->start(0); if(observer) { observer->detach(); } if(defaultsAndOverrides->overrideCompress) { compress = defaultsAndOverrides->overrideCompressValue; } else { compress = q->endpoint->compress(); } connection->activate(); break; } catch(const Ice::CommunicatorDestroyedException& ex) { if(observer) { observer->failed(ex.ice_name()); observer->detach(); } exception.reset(ex.ice_clone()); handleConnectionException(*exception.get(), hasMore || q != connectors.end() - 1); connection = 0; break; // No need to continue } catch(const Ice::LocalException& ex) { if(observer) { observer->failed(ex.ice_name()); observer->detach(); } exception.reset(ex.ice_clone()); handleConnectionException(*exception.get(), hasMore || q != connectors.end() - 1); connection = 0; } } // // Finish creating the connection (this removes the connectors from the _pending // list and notifies any waiting threads). // if(connection) { finishGetConnection(connectors, *q, connection, 0); } else { finishGetConnection(connectors, *exception.get(), 0); } if(!connection) { assert(exception.get()); exception->ice_throw(); } return connection; }