giopserver.cc
来自「编译工具」· CC 代码 · 共 1,880 行 · 第 1/4 页
CC
1,880 行
}/////////////////////////////////////////////////////////////////////////////staticCORBA::BooleanregisterGiopServer(omniInterceptors::createORBServer_T::info_T& info) { info.servers.push_back(giopServer::singleton()); return 1;}/////////////////////////////////////////////////////////////////////////////// Handlers for Configuration Options ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////class threadPerConnectionPolicyHandler : public orbOptions::Handler {public: threadPerConnectionPolicyHandler() : orbOptions::Handler("threadPerConnectionPolicy", "threadPerConnectionPolicy = 0 or 1", 1, "-ORBthreadPerConnectionPolicy < 0 | 1 >") {} void visit(const char* value,orbOptions::Source) throw (orbOptions::BadParam) { CORBA::Boolean v; if (!orbOptions::getBoolean(value,v)) { throw orbOptions::BadParam(key(),value, orbOptions::expect_boolean_msg); } orbParameters::threadPerConnectionPolicy = v; } void dump(orbOptions::sequenceString& result) { orbOptions::addKVBoolean(key(),orbParameters::threadPerConnectionPolicy, result); }};static threadPerConnectionPolicyHandler threadPerConnectionPolicyHandler_;/////////////////////////////////////////////////////////////////////////////class threadPerConnectionUpperLimitHandler : public orbOptions::Handler {public: threadPerConnectionUpperLimitHandler() : orbOptions::Handler("threadPerConnectionUpperLimit", "threadPerConnectionUpperLimit = n >= 1", 1, "-ORBthreadPerConnectionUpperLimit < n >= 1 >") {} void visit(const char* value,orbOptions::Source) throw (orbOptions::BadParam) { CORBA::ULong v; if (!orbOptions::getULong(value,v) || v < 1) { throw orbOptions::BadParam(key(),value, orbOptions::expect_greater_than_zero_ulong_msg); } orbParameters::threadPerConnectionUpperLimit = v; } void dump(orbOptions::sequenceString& result) { orbOptions::addKVULong(key(),orbParameters::threadPerConnectionUpperLimit, result); }};static threadPerConnectionUpperLimitHandler threadPerConnectionUpperLimitHandler_;/////////////////////////////////////////////////////////////////////////////class threadPerConnectionLowerLimitHandler : public orbOptions::Handler {public: threadPerConnectionLowerLimitHandler() : orbOptions::Handler("threadPerConnectionLowerLimit", "threadPerConnectionLowerLimit = n >= 1", 1, "-ORBthreadPerConnectionLowerLimit < n >= 1 >") {} void visit(const char* value,orbOptions::Source) throw (orbOptions::BadParam) { CORBA::ULong v; if (!orbOptions::getULong(value,v) || v < 1) { throw orbOptions::BadParam(key(),value, orbOptions::expect_greater_than_zero_ulong_msg); } orbParameters::threadPerConnectionLowerLimit = v; } void dump(orbOptions::sequenceString& result) { orbOptions::addKVULong(key(),orbParameters::threadPerConnectionLowerLimit, result); }};static threadPerConnectionLowerLimitHandler threadPerConnectionLowerLimitHandler_;/////////////////////////////////////////////////////////////////////////////class maxServerThreadPerConnectionHandler : public orbOptions::Handler {public: maxServerThreadPerConnectionHandler() : orbOptions::Handler("maxServerThreadPerConnection", "maxServerThreadPerConnection = n >= 1", 1, "-ORBmaxServerThreadPerConnection < n >= 1 >") {} void visit(const char* value,orbOptions::Source) throw (orbOptions::BadParam) { CORBA::ULong v; if (!orbOptions::getULong(value,v) || v < 1) { throw orbOptions::BadParam(key(),value, orbOptions::expect_greater_than_zero_ulong_msg); } orbParameters::maxServerThreadPerConnection = v; } void dump(orbOptions::sequenceString& result) { orbOptions::addKVULong(key(),orbParameters::maxServerThreadPerConnection, result); }};static maxServerThreadPerConnectionHandler maxServerThreadPerConnectionHandler_;/////////////////////////////////////////////////////////////////////////////class maxServerThreadPoolSizeHandler : public orbOptions::Handler {public: maxServerThreadPoolSizeHandler() : orbOptions::Handler("maxServerThreadPoolSize", "maxServerThreadPoolSize = n >= 1", 1, "-ORBmaxServerThreadPoolSize < n >= 1 >") {} void visit(const char* value,orbOptions::Source) throw (orbOptions::BadParam) { CORBA::ULong v; if (!orbOptions::getULong(value,v) || v < 1) { throw orbOptions::BadParam(key(),value, orbOptions::expect_greater_than_zero_ulong_msg); } orbParameters::maxServerThreadPoolSize = v; } void dump(orbOptions::sequenceString& result) { orbOptions::addKVULong(key(),orbParameters::maxServerThreadPoolSize, result); }};static maxServerThreadPoolSizeHandler maxServerThreadPoolSizeHandler_;/////////////////////////////////////////////////////////////////////////////class threadPoolWatchConnectionHandler : public orbOptions::Handler {public: threadPoolWatchConnectionHandler() : orbOptions::Handler("threadPoolWatchConnection", "threadPoolWatchConnection = n >= 0", 1, "-ORBthreadPoolWatchConnection < n >= 0 >") {} void visit(const char* value,orbOptions::Source) throw (orbOptions::BadParam) { CORBA::ULong v; if (!orbOptions::getULong(value,v)) { throw orbOptions::BadParam(key(),value, orbOptions::expect_ulong_msg); } orbParameters::threadPoolWatchConnection = v; } void dump(orbOptions::sequenceString& result) { orbOptions::addKVULong(key(),orbParameters::threadPoolWatchConnection, result); }};static threadPoolWatchConnectionHandler threadPoolWatchConnectionHandler_;/////////////////////////////////////////////////////////////////////////////class connectionWatchImmediateHandler : public orbOptions::Handler {public: connectionWatchImmediateHandler() : orbOptions::Handler("connectionWatchImmediate", "connectionWatchImmediate = 0 or 1", 1, "-ORBconnectionWatchImmediate < 0 | 1 >") {} void visit(const char* value,orbOptions::Source) throw (orbOptions::BadParam) { CORBA::Boolean v; if (!orbOptions::getBoolean(value,v)) { throw orbOptions::BadParam(key(),value, orbOptions::expect_boolean_msg); } orbParameters::connectionWatchImmediate = v; } void dump(orbOptions::sequenceString& result) { orbOptions::addKVBoolean(key(),orbParameters::connectionWatchImmediate, result); }};static connectionWatchImmediateHandler connectionWatchImmediateHandler_;/////////////////////////////////////////////////////////////////////////////// Module initialiser ///////////////////////////////////////////////////////////////////////////////class omni_giopserver_initialiser : public omniInitialiser {public: omni_giopserver_initialiser() { orbOptions::singleton().registerHandler(threadPerConnectionPolicyHandler_); orbOptions::singleton().registerHandler(threadPerConnectionUpperLimitHandler_); orbOptions::singleton().registerHandler(threadPerConnectionLowerLimitHandler_); orbOptions::singleton().registerHandler(maxServerThreadPerConnectionHandler_); orbOptions::singleton().registerHandler(maxServerThreadPoolSizeHandler_); orbOptions::singleton().registerHandler(threadPoolWatchConnectionHandler_); orbOptions::singleton().registerHandler(connectionWatchImmediateHandler_); } void attach() { omniInterceptors* interceptors = omniORB::getInterceptors(); interceptors->createORBServer.add(registerGiopServer); } void detach() { }};static omni_giopserver_initialiser initialiser;omniInitialiser& omni_giopserver_initialiser_ = initialiser;OMNI_NAMESPACE_END(omni)////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// The following diagram illustrates the state transition of a connection// when it is managed under the thread pool policy.//// Under this policy, the connection is watched by the rendezvouser// thread. When data arrive, the rendezvouser calls notifyRzReadable and// a worker thread is dispatched. The worker unmarshal data from the// connection. When it finishes unmarshaling all the arguments, worker// calls notifyWkPreUpCall before doing the upcall into the// implementation. In notifyWkPreUpCall, the connection is again// registered to be watched by the rendezvouser. When the worker has// finished the upcall, it calls notifyWkDone. If data for another call// arrives, the whole cycle repeats again.//// The state diagram below illustrates what happens://// Legend:// +----------+ x = 1 : the connection is watched// + (x,y,z) + 0 : the connection is not watched// +----------+ y = 1 : rendezvouser detected data arrival// 0 : no new data have arrived// z = n >= 0 : no. of threads serving the// connection////// +---------+// | (1,0,0) |<----------------------+// +----+----+ |// | |// | DataArrive |// | |// V |// +---------+ |notifyWkDone**// | (0,1,0) | | **-tell the rendezvouser// +----+----+ | to watch immediately// | |// | notifyRzReadable |// | |// V |// +---------+ +-+-------+// +-->| (0,0,1) +------------------->| (1,0,1) |// | +---------+ notifyWkPreUpCall +--+------+// | | ^// | +--------------------------+ |// | | DataArrive |// | V |// | +---------+ |//notifyWkDone | | (0,1,1) | |// | +----+----+ |notifyWkDone// | | |// | | notifyRzReadable |// | | |// | V |// | +---------+ +----+----+// +---+ (0,0,2) +------------------->| (1,0,2) |// +-->+---------+ notifyWkPreUpCall +--+------+// | | ^// | +--------------------------+ |// | | DataArrive |// | V |// | +---------+ |//notifyWkDone | | (0,1,2) | |// | +----+----+ |notifyWkDone// | | |// | | notifyRzReadable |// | | |// | V |// | +---------+ +----+----+// +---+ (0,0,3) +------------------->| (1,0,3) |// +---------+ notifyWkPreUpCall +--+------+// .... And so on...////// To summarise, here are what the transition function should do:// notifyRzReadable()// - Always create a temporary worker//// notifyWkPreUpCall()// - setSelectable//// notifyWkDone()// - setSelectable(2) if n worker == 1.//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// The following diagram illustrates the state transition of a connection// when it is managed under the thread-per-connection policy.//// Under this policy, each connection has a dedicated worker thread.// When a call arrives, the worker unmarshalls all the arguments and do// an upcall. Before it does the upcall, it calls notifyWkPreUpCall. In// notifyWkPreUpCall, the connection is registered to be watched by// the rendezvouser. When the worker has finished the upcall, it calls// notifyWkDone, the connnection is un-registered with the rendezvouser.// The worker then waits for another call to arrive and the whole cycle// repeats again.// If while the worker is performing the upcall another call has arrived,// the rendezvouser calls notifyRzReadable and a temporary worker thread// is dispatched. This thread is 'temporary' in the sense that it is only// dispatched to serve one call.// The interaction of the dedicated worker, the temporary worker and// the rendezvouser is summarised by the state diagram below://// Legend:// +----------+ x = 1 : the connection is watched// + (x,y,z) + 0 : the connection is not watched// +----------+ y = 1 : rendezvouser detected data arrival// 0 : no new data have arrived// z = n >= 0 : no. of threads serving the// connection. The dedicated thread// is not watching the connection.// z* = same as z except that the dedicated// thread is watching the connection.//// notifyWkDone - transition executed by the temporary workers//// notifyWkDone - transition executed by the dedicated worker// ^^^^^^^^^^^^////// +---------+// +--->| (0,0,1*)|<--------------------+// | +----+----+ |// | | notifyWkPreUpCall |// | | ^^^^^^^^^^^^^^^^^ |//notifyWkDone| | |//^^^^^^^^^^^^| | |// | V |// | +---------+ |// +----+ (1,0,1) + |notifyWkDone// +--->+----+----+ |// | | |// | |DataArrive |// | | |// | V |// | +---------+ |// | | (0,1,1) + |// | +----+----+ |// | | |// | |notifyRzReadable | notifyWkPreUpCall//notifyWkDone| | | +--+// | | | | |// | | | | |// | V | V |// | +---------+ ++------+-+// +-|--->| (0,0,2) +------------------->| (0,0,2*)|// | | +----+----+ notifyWkDone +---------+// | | | ^^^^^^^^^^^^ | ^ ^// | | | | | |// | | |notifyWkPreUpCall | | |// | | | | | |// | | | +-----------------------+ | |// | | V V notifyWkPreUpCall(1) | |// | | +---------+ ^^^^^^^^^^^^^^^^^^^^ | |// | +----+ (1,0,2) +-----------------------+ |// | +->+----+----+ notifyWkDone |notifyWkDone// +-+ | | ^^^^^^^^^^^^ |// | | | |// | | |DataArrive |// | | | |// | | V |// | | +---------+ |// | | | (0,1,2) + |// | | +----+----+ +---+// | | | |// | | |notifyRzReadable | notifyWkPreUpCall//notifyWkDone| | | | +--+// | | | | | |// | | | | | |// | | V | V |// | | +---------+ ++------+-+// +----+ (0,0,3) +------------------->| (0,0,3*)|// | +----+----+ notifyWkDone +---------+// | | ^^^^^^^^^^^^ | ^// | | | |// notifyWkDone| |notifyWkPreUpCall | |// | | | |// | | +----------------------+ |// | V V notifyWkPreUpCall(1) |// | +---------+ ^^^^^^^^^^^^^^^^^^^^ |// +--+ (1,0,3) +-------------------------+// +----+----+ notifyWkDone// | ^^^^^^^^^^^^//// Note: (1) May also happen under a race condition- if dedicated thread // gets the read lock before the temporary worker.//// And So On...////// To summarise, here are what the transition function should do:// notifyRzReadable()// - Always create a temporary worker//// notifyWkPreUpCall()// dedicated thread - setSelectable unless n workers != 1// temporary thread - setSelectable only if the dedicated thread is// in the upcall//// notifyWkDone()// dedicated thread - clearSelectable// temporary thread - Do nothing//
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?