00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "ProxyPullConsumer.h"
00025 #include "Orb.h"
00026 #include "omniEventsLog.h"
00027
00028 #define DB(l,x) ((omniORB::traceLevel >= l) && (cerr << x << endl))
00029
00030 namespace OmniEvents {
00031
00032
00033
00034
00035
00036 PortableServer::Servant
00037 ProxyPullConsumerManager::incarnate(
00038 const PortableServer::ObjectId& oid,
00039 PortableServer::POA_ptr poa
00040 )
00041 {
00042
00043 ProxyPullConsumer_i* result =new ProxyPullConsumer_i(_managedPoa,_queue);
00044 _servants.insert(result);
00045 return result;
00046 }
00047
00048 ProxyPullConsumerManager::ProxyPullConsumerManager(
00049 PortableServer::POA_ptr parentPoa,
00050 list<CORBA::Any*>& q
00051 )
00052 : ProxyManager(parentPoa,"ProxyPullConsumer"),
00053 _queue(q)
00054 {
00055
00056 }
00057
00058 CosEventChannelAdmin::ProxyPullConsumer_ptr
00059 ProxyPullConsumerManager::createObject()
00060 {
00061 return createNarrowedReference<CosEventChannelAdmin::ProxyPullConsumer>(
00062 _managedPoa,
00063 CosEventChannelAdmin::_tc_ProxyPullConsumer->id()
00064 );
00065 }
00066
00067
00068
00069 void ProxyPullConsumerManager::trigger()
00070 {
00071
00072 for(set<Proxy*>::iterator i =_servants.begin(); i!=_servants.end(); ++i)
00073 {
00074 ProxyPullConsumer_i* proxy=static_cast<ProxyPullConsumer_i*>(*i);
00075 proxy->trigger();
00076 }
00077 }
00078
00079
00080
00081
00082
00083
00084
00085
00086 void ProxyPullConsumer_i::connect_pull_supplier(
00087 CosEventComm::PullSupplier_ptr pullSupplier
00088 )
00089 {
00090 try
00091 {
00092 if(CORBA::is_nil(pullSupplier))
00093 throw CORBA::BAD_PARAM();
00094 if(!CORBA::is_nil(_target) || !CORBA::is_nil(_req))
00095 throw CosEventChannelAdmin::AlreadyConnected();
00096 _target=CosEventComm::PullSupplier::_duplicate(pullSupplier);
00097
00098 omniEventsLog::persist();
00099 }
00100 catch(...)
00101 {
00102 _target=CosEventComm::PullSupplier::_nil();
00103 deactivateObject();
00104 throw;
00105 }
00106 }
00107
00108 void ProxyPullConsumer_i::disconnect_pull_consumer()
00109 {
00110 DB(5,"ProxyPullConsumer_i::disconnect_pull_consumer()");
00111 deactivateObject();
00112 if(CORBA::is_nil(_target))
00113 {
00114 throw CORBA::BAD_INV_ORDER(
00115 omni::BAD_INV_ORDER_RequestUsedMoreThanOnce,
00116 CORBA::COMPLETED_YES
00117 );
00118 }
00119 else
00120 {
00121 CORBA::Request_var req=_target->_request("disconnect_pull_supplier");
00122 req->send_deferred();
00123 Orb::inst().orphanRequest(req._retn());
00124 _target=CosEventComm::PullSupplier::_nil();
00125 }
00126 }
00127
00128
00129
00130 ProxyPullConsumer_i::ProxyPullConsumer_i(
00131 PortableServer::POA_ptr poa,
00132 list<CORBA::Any*>& q
00133 )
00134 : Proxy(poa),
00135 _target(CosEventComm::PullSupplier::_nil()),
00136 _queue(q)
00137 {
00138 _exceptionCount[Pull]=0;
00139 _exceptionCount[TryPull]=0;
00140 }
00141
00142 void ProxyPullConsumer_i::trigger()
00143 {
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 CORBA::String_var opname ="pull";
00155
00156 if(!CORBA::is_nil(_req) && _req->poll_response())
00157 {
00158 opname=CORBA::string_dup(_req->operation());
00159
00160 CORBA::Environment_var env=_req->env();
00161 if(!CORBA::is_nil(env) && env->exception())
00162 {
00163 CORBA::Exception* ex =env->exception();
00164 DB(1,"ProxyPullConsumer got exception: "<<ex->_name()<<", op:"<<opname);
00165 _req=CORBA::Request::_nil();
00166 if(0==strcmp("pull",opname))
00167 {
00168 ++(_exceptionCount[Pull]);
00169 opname="try_pull";
00170 }
00171 else if(0==strcmp("try_pull",opname))
00172 {
00173 ++(_exceptionCount[TryPull]);
00174 opname="pull";
00175 }
00176 else
00177 DB(1,"Ignoring unrecognised response. operation:"<<opname);
00178 if(_exceptionCount[Pull]>=2 && _exceptionCount[TryPull]>=2)
00179 {
00180 _target=CosEventComm::PullSupplier::_nil();
00181 deactivateObject();
00182 return;
00183 }
00184 }
00185 else
00186 {
00187
00188 bool hasEvent=false;
00189 if(0==strcmp("pull",opname))
00190 {
00191 _exceptionCount[Pull]=0;
00192 hasEvent=true;
00193 }
00194 else if(0==strcmp("try_pull",opname))
00195 {
00196 _exceptionCount[TryPull]=0;
00197 CORBA::NVList_var args=_req->arguments();
00198 if(args->count()==1)
00199 {
00200 CORBA::NamedValue_var hasEventArg=args->item(0);
00201 if(0==strcmp(hasEventArg->name(),"has_event"))
00202 {
00203 CORBA::Any* a =hasEventArg->value();
00204 CORBA::Boolean b;
00205 CORBA::Any::to_boolean tb(b);
00206 hasEvent=(((*a)>>=tb) && b);
00207 }
00208 }
00209 }
00210
00211 if(hasEvent)
00212 {
00213 CORBA::Any* event =new CORBA::Any();
00214 _req->return_value() >>= (*event);
00215 _queue.push_back(event);
00216 }
00217 }
00218 _req=CORBA::Request::_nil();
00219 }
00221 if(CORBA::is_nil(_req) && !CORBA::is_nil(_target))
00222 {
00223 _req=_target->_request(opname);
00224 _req->set_return_type(CORBA::_tc_any);
00225 if(0==strcmp("try_pull",opname))
00226 _req->add_out_arg("has_event")<<=CORBA::Any::from_boolean(1);
00227 _req->send_deferred();
00228 }
00229 }
00230
00231 void ProxyPullConsumer_i::reincarnate(const OEP_prxy& prxy)
00232 {
00233 CosEventComm::PullSupplier_var pullSupplier =
00234 string_to_<CosEventComm::PullSupplier>(prxy.getIor());
00235
00236 activateObjectWithId(prxy.getKey());
00237 connect_pull_supplier(pullSupplier.in());
00238 }
00239
00240 void ProxyPullConsumer_i::output(ostream& os)
00241 {
00242 Output out =basicOutput(os,"pxyPullConsumer",3,this,_target.in());
00243 }
00244
00245 };