giop_s.cc
来自「编译工具」· CC 代码 · 共 827 行 · 第 1/2 页
CC
827 行
// -*- Mode: C++; -*-// Package : omniORB// GIOP_S.cc Created on: 05/01/2001// Author : Sai Lai Lo (sll)//// Copyright (C) 2001 AT&T Laboratories Cambridge//// This file is part of the omniORB library//// The omniORB library is free software; you can redistribute it and/or// modify it under the terms of the GNU Library General Public// License as published by the Free Software Foundation; either// version 2 of the License, or (at your option) any later version.//// This library is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU// Library General Public License for more details.//// You should have received a copy of the GNU Library General Public// License along with this library; if not, write to the Free// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA// 02111-1307, USA////// Description:// *** PROPRIETORY INTERFACE ***///* $Log: GIOP_S.cc,v $ Revision 1.1.4.29 2005/11/15 11:07:57 dgrisby More shutdown cleanup. Revision 1.1.4.28 2005/04/08 00:06:15 dgrisby Remove all remaining uses of logf. Revision 1.1.4.27 2005/01/04 18:09:29 dgrisby SkipRequestBody did not call notifyWkPreUpCall, which meant requests would be mislaid if they came in the same buffer as a skipped request. Revision 1.1.4.26 2004/10/17 21:48:38 dgrisby Support CancelRequest better. Revision 1.1.4.25 2003/07/16 14:22:38 dgrisby Speed up oneway handling a little. More tracing for split messages. Revision 1.1.4.24 2002/11/26 16:54:34 dgrisby Fix exception interception. Revision 1.1.4.23 2002/11/26 14:51:49 dgrisby Implement missing interceptors. Revision 1.1.4.22 2002/07/04 15:14:40 dgrisby Correct usage of MessageErrors, fix log messages. Revision 1.1.4.21 2002/05/22 15:56:33 dgrisby IRIX, FreeBSD fixes. Revision 1.1.4.20 2002/03/27 11:44:51 dpg1 Check in interceptors things left over from last week. Revision 1.1.4.19 2002/03/18 12:38:25 dpg1 Lower trace(0) to trace(1), propagate fatalException. Revision 1.1.4.18 2002/03/13 16:05:38 dpg1 Transport shutdown fixes. Reference count SocketCollections to avoid connections using them after they are deleted. Properly close connections when in thread pool mode. Revision 1.1.4.17 2001/12/03 18:46:25 dpg1 Race condition in giopWorker destruction. Revision 1.1.4.16 2001/11/12 13:47:09 dpg1 Minor fixes. Revision 1.1.4.15 2001/10/17 16:33:27 dpg1 New downcast mechanism for cdrStreams. Revision 1.1.4.14 2001/09/20 11:30:59 sll On the server, the final state of a GIOP_S is ReplyCompleted instead of Idle. This is necessary because the idle connection management code treats Idle as a state where the idle counter can be restarted. Revision 1.1.4.13 2001/09/10 17:44:34 sll Added stopIdleCounter() call inside dispatcher when the header has been received. Revision 1.1.4.12 2001/09/04 14:38:51 sll Added the boolean argument to notifyCommFailure to indicate if omniTransportLock is held by the caller. Revision 1.1.4.11 2001/08/15 10:26:11 dpg1 New object table behaviour, correct POA semantics. Revision 1.1.4.10 2001/08/03 17:41:17 sll System exception minor code overhaul. When a system exeception is raised, a meaning minor code is provided. Revision 1.1.4.9 2001/07/31 16:28:01 sll Added GIOP BiDir support. Revision 1.1.4.8 2001/07/13 15:22:45 sll Call notifyWkPreUpCall at the right time and determine if there are buffered data to be served by another thread. Revision 1.1.4.7 2001/06/29 16:26:01 dpg1 Reinstate tracing messages for new connections and handling locate requests. Revision 1.1.4.6 2001/05/31 16:18:12 dpg1 inline string matching functions, re-ordered string matching in _ptrToInterface/_ptrToObjRef Revision 1.1.4.5 2001/05/29 17:03:50 dpg1 In process identity. Revision 1.1.4.4 2001/05/04 13:55:27 sll When a system exception is raised, send the exception before skipping rest of the input message. Helpful if the client sends a message shorter than the header indicates. Otherwise the server will sit there waiting for the remaining bytes that will never come. Eventually the server side timeout mechanism kicks in but by then the server will just close the connection rather than telling the client it has detected a marshalling exception. Revision 1.1.4.3 2001/05/02 14:22:05 sll Cannot rely on the calldescriptor still being there when a user exception is raised. Revision 1.1.4.2 2001/05/01 16:07:32 sll All GIOP implementations should now work with fragmentation and abitrary sizes non-copy transfer. Revision 1.1.4.1 2001/04/18 18:10:51 sll Big checkin with the brand new internal APIs. */#include <omniORB4/CORBA.h>#include <omniORB4/callDescriptor.h>#include <omniORB4/callHandle.h>#include <initRefs.h>#include <exceptiondefs.h>#include <objectTable.h>#include <objectAdapter.h>#include <giopStrand.h>#include <giopStream.h>#include <giopStreamImpl.h>#include <invoker.h>#include <giopServer.h>#include <giopWorker.h>#include <GIOP_S.h>#include <omniORB4/minorCode.h>#include <omniORB4/omniInterceptors.h>#include <interceptors.h>#include <poaimpl.h>OMNI_NAMESPACE_BEGIN(omni)////////////////////////////////////////////////////////////////////////GIOP_S_Holder::GIOP_S_Holder(giopStrand* g, giopWorker* work) : pd_strand(g) { pd_iop_s = g->acquireServer(work);}////////////////////////////////////////////////////////////////////////GIOP_S_Holder::~GIOP_S_Holder() { if (pd_iop_s) pd_strand->releaseServer(pd_iop_s);}////////////////////////////////////////////////////////////////////////GIOP_S::GIOP_S(giopStrand* g) : giopStream(g), pd_state(UnUsed), pd_worker(0), pd_calldescriptor(0), pd_requestType(GIOP::MessageError), pd_operation((char*)pd_op_buffer), pd_principal(pd_pr_buffer), pd_principal_len(0), pd_response_expected(1), pd_result_expected(1){}////////////////////////////////////////////////////////////////////////GIOP_S::GIOP_S(const GIOP_S& src) : giopStream(src.pd_strand), pd_state(UnUsed), pd_worker(0), pd_calldescriptor(0), pd_requestType(GIOP::MessageError), pd_operation((char*)pd_op_buffer), pd_principal(pd_pr_buffer), pd_principal_len(0), pd_response_expected(1), pd_result_expected(1){}////////////////////////////////////////////////////////////////////////GIOP_S::~GIOP_S() { if (pd_operation != (char*)pd_op_buffer) delete [] pd_operation; if (pd_principal != pd_pr_buffer) delete [] pd_principal;}////////////////////////////////////////////////////////////////////////void*GIOP_S::ptrToClass(int* cptr){ if (cptr == &GIOP_S ::_classid) return (GIOP_S*) this; if (cptr == &giopStream::_classid) return (giopStream*)this; if (cptr == &cdrStream ::_classid) return (cdrStream*) this; return 0;}int GIOP_S::_classid;////////////////////////////////////////////////////////////////////////CORBA::BooleanGIOP_S::dispatcher() { OMNIORB_ASSERT(pd_state == Idle); try { pd_state = WaitForRequestHeader; impl()->inputMessageBegin(this,impl()->unmarshalWildCardRequestHeader); { omni_tracedmutex_lock sync(*omniTransportLock); pd_state = RequestHeaderIsBeingProcessed; if (!pd_strand->stopIdleCounter()) { // This strand has been expired by the scavenger. Don't // process this call. if (omniORB::trace(1)) { omniORB::logger l; l << "dispatcher cannot stop idle counter.\n"; } pd_strand->state(giopStrand::DYING); return 0; } } if (pd_requestType == GIOP::Request) { return handleRequest(); } else if (pd_requestType == GIOP::LocateRequest) { return handleLocateRequest(); } else if (pd_requestType == GIOP::CancelRequest) { return handleCancelRequest(); } else { if( omniORB::trace(1) ) { omniORB::logger l; l << "Unexpected message type (" << (CORBA::ULong) pd_requestType << ")received by a server thread at " << __FILE__ << ": line " << __LINE__ << "\n"; } return 0; } } catch(const giopStream::CommFailure&) { return 0; } catch(const omniORB::fatalException& ex) { if( omniORB::trace(1) ) { omniORB::logger l; l << "omniORB fatalException caught by a server thread at " << ex.file() << ": line " << ex.line() << ", message: " << ex.errmsg() << "\n"; } return 0; } catch (...) { if ( omniORB::trace(1) ) { omniORB::logger l; l << "Unknown exception caught by a server thread at " << __FILE__ << ": line " << __LINE__ << "\n"; } return 0; }}////////////////////////////////////////////////////////////////////////CORBA::BooleanGIOP_S::handleRequest() { try { impl()->unmarshalRequestHeader(this); pd_state = RequestIsBeingProcessed; { omniInterceptors::serverReceiveRequest_T::info_T info(*this); omniInterceptorP::visit(info); } // Create a callHandle object omniCallHandle call_handle(this); // Can we find the object in the local object table? if (keysize() < 0) OMNIORB_THROW(OBJECT_NOT_EXIST,OBJECT_NOT_EXIST_NoMatch, CORBA::COMPLETED_NO); CORBA::ULong hash = omni::hash(key(), keysize()); omni::internalLock->lock(); omniLocalIdentity* id; id = omniObjTable::locateActive(key(), keysize(), hash, 1); if( id ) { id->dispatch(call_handle); return 1; } omni::internalLock->unlock(); // Can we create a suitable object on demand? omniObjAdapter_var adapter(omniObjAdapter::getAdapter(key(),keysize())); if( adapter ) { adapter->dispatch(call_handle, key(), keysize()); return 1; } // Or is it the bootstrap agent? if( keysize() == 4 && !memcmp(key(), "INIT", 4) && omniInitialReferences::invoke_bootstrap_agentImpl(call_handle) ) return 1; // Oh dear. if (omniObjAdapter::isDeactivating()) OMNIORB_THROW(OBJ_ADAPTER, OBJ_ADAPTER_POAUnknownAdapter, CORBA::COMPLETED_NO); else OMNIORB_THROW(OBJECT_NOT_EXIST, OBJECT_NOT_EXIST_NoMatch, CORBA::COMPLETED_NO); } catch(omniORB::LOCATION_FORWARD& ex) { // This is here to provide a convenient way to implement // location forwarding. The object implementation can throw // a location forward exception to re-direct the request // to another location. if( omniORB::traceInvocations ) { omniORB::logger l; l << "Implementation of '" << operation() << "' generated LOCATION_FORWARD.\n"; } CORBA::Object_var release_it(ex.get_obj()); if (pd_state == RequestIsBeingProcessed) { SkipRequestBody(); } if (response_expected()) { impl()->sendLocationForwardReply(this,release_it,ex.is_permanent()); } // If the client does not expect a response, we quietly drop // the location forward. } catch (const terminateProcessing&) { }#define MARSHAL_USER_EXCEPTION() do { \ OMNIORB_ASSERT(calldescriptor() != 0); \ int i, repoid_size; \ const char* repoid = ex._NP_repoId(&repoid_size); \ for( i = 0; i < pd_n_user_excns; i++ ) \ if( omni::strMatch(pd_user_excns[i], repoid) ) { \ impl()->sendUserException(this,ex); \ break; \ } \ if( i == pd_n_user_excns ) { \ if( omniORB::trace(1) ) { \ omniORB::logger l; \ l << "WARNING -- method \'" << operation() \ << "\' on: " << pd_key \ << "\n raised the exception: " << repoid << '\n'; \ } \ CORBA::UNKNOWN sex(UNKNOWN_UserException, \ (CORBA::CompletionStatus) completion()); \ impl()->sendSystemException(this,sex); \ } \} while (0)#define MARSHAL_SYSTEM_EXCEPTION() do { \ if (pd_state == WaitForRequestHeader || \ pd_state == RequestHeaderIsBeingProcessed ) { \ impl()->sendMsgErrorMessage(this); \ return 0; \ } else if (response_expected()) { \ impl()->sendSystemException(this,ex); \ } \ if (pd_state == RequestIsBeingProcessed) { \ SkipRequestBody(); \ } \} while (0) # ifndef HAS_Cplusplus_catch_exception_by_base // We have to catch each type of system exception separately // here to support compilers which cannot catch more derived // types.# define CATCH_AND_MARSHAL(name) \ catch (CORBA::name& ex) { \
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?