Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

ProxyPushSupplier.cc

Go to the documentation of this file.
00001 //                            Package   : omniEvents
00002 // ProxyPushSupplier.cc       Created   : 2003/12/04
00003 //                            Author    : Alex Tingle
00004 //
00005 //    Copyright (C) 2003 Alex Tingle.
00006 //
00007 //    This file is part of the omniEvents application.
00008 //
00009 //    omniEvents is free software; you can redistribute it and/or
00010 //    modify it under the terms of the GNU Lesser General Public
00011 //    License as published by the Free Software Foundation; either
00012 //    version 2.1 of the License, or (at your option) any later version.
00013 //
00014 //    omniEvents is distributed in the hope that it will be useful,
00015 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017 //    Lesser General Public License for more details.
00018 //
00019 //    You should have received a copy of the GNU Lesser General Public
00020 //    License along with this library; if not, write to the Free Software
00021 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 //
00023 
00024 #include "ProxyPushSupplier.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 //  ProxyPushSupplierManager
00034 //
00035 
00036 PortableServer::Servant
00037 ProxyPushSupplierManager::incarnate(
00038   const PortableServer::ObjectId& oid,
00039   PortableServer::POA_ptr         poa
00040 )
00041 {
00042   // ?? Check that OID is valid here.
00043   ProxyPushSupplier_i* result =new ProxyPushSupplier_i(_managedPoa,_queue);
00044   {
00045     omni_mutex_lock l(_lock);
00046     _servants.insert(result);
00047   }
00048   _condition.signal(); // Wake up the thread if it's asleep.
00049   return result;
00050 }
00051 
00052 void
00053 ProxyPushSupplierManager::etherealize(
00054   const PortableServer::ObjectId& oid,
00055   PortableServer::POA_ptr         adapter,
00056   PortableServer::Servant         serv,
00057   CORBA::Boolean                  cleanup_in_progress,
00058   CORBA::Boolean                  remaining_activations
00059 )
00060 {
00061   omni_mutex_lock l(_lock);
00062   ProxyManager::etherealize(oid,adapter,serv,
00063     cleanup_in_progress,remaining_activations);
00064 }
00065 
00066 
00067 ProxyPushSupplierManager::ProxyPushSupplierManager(
00068   PortableServer::POA_ptr parentPoa,
00069   EventQueue& q
00070 )
00071 : ProxyManager(parentPoa,"ProxyPushSupplier"),
00072   _queue(q),
00073   _lock(),_conditionLock(),_condition(&_conditionLock),
00074   _shutdownRequested(false)
00075 {
00076   start_undetached();
00077 }
00078 
00079 CosEventChannelAdmin::ProxyPushSupplier_ptr
00080 ProxyPushSupplierManager::createObject()
00081 {  
00082   return createNarrowedReference<CosEventChannelAdmin::ProxyPushSupplier>(
00083            _managedPoa,
00084            CosEventChannelAdmin::_tc_ProxyPushSupplier->id()
00085          );
00086 }
00087 
00088 void*
00089 ProxyPushSupplierManager::run_undetached(void*)
00090 {
00091   omni_mutex_lock cl(_conditionLock);
00092   while(true)
00093   {
00094     bool moreWorkToDo=false;
00095     {
00096       omni_mutex_lock l(_lock); // Block here when paused.
00097       if(_shutdownRequested)
00098           break;
00099 
00100       // Trigger each servant in turn.
00101       for(set<Proxy*>::iterator i =_servants.begin(); i!=_servants.end(); ++i)
00102       {
00103         ProxyPushSupplier_i* proxy=static_cast<ProxyPushSupplier_i*>(*i);
00104         if(proxy->trigger())
00105             moreWorkToDo=true;
00106       }
00107     }
00108     
00109     // Wait
00110     if(moreWorkToDo)
00111         omni_thread::yield();
00112     else
00113         _condition.wait(); // wait until something happens.
00114   }
00115   return NULL;
00116 }
00117 
00118 
00119 //
00120 //  ProxyPushSupplier_i
00121 //
00122 
00123 void ProxyPushSupplier_i::connect_push_consumer(
00124   CosEventComm::PushConsumer_ptr pushConsumer)
00125 {
00126   try
00127   {
00128     if(CORBA::is_nil(pushConsumer))
00129         throw CORBA::BAD_PARAM();
00130     if(!CORBA::is_nil(_target) || !CORBA::is_nil(_req))
00131         throw CosEventChannelAdmin::AlreadyConnected();
00132     _target=CosEventComm::PushConsumer::_duplicate(pushConsumer);
00133 
00134     omniEventsLog::persist();
00135   }
00136   catch(...)
00137   {
00138     _target=CosEventComm::PushConsumer::_nil(); // disconnected.
00139     deactivateObject();
00140     throw;
00141   }
00142 }
00143 
00144 
00145 void ProxyPushSupplier_i::disconnect_push_supplier()
00146 {
00147   DB(5,"ProxyPushSupplier_i::disconnect_push_supplier()");
00148   deactivateObject();
00149   if(CORBA::is_nil(_target))
00150   {
00151     throw CORBA::BAD_INV_ORDER(
00152       omni::BAD_INV_ORDER_RequestUsedMoreThanOnce,
00153       CORBA::COMPLETED_YES
00154     );
00155   }
00156   else
00157   {
00158     CORBA::Request_var req=_target->_request("disconnect_push_consumer");
00159     req->send_deferred();
00160     Orb::inst().orphanRequest(req._retn());
00161     _target=CosEventComm::PushConsumer::_nil();
00162   }
00163 }
00164 
00165 
00166 ProxyPushSupplier_i::ProxyPushSupplier_i(
00167   PortableServer::POA_ptr poa,
00168   EventQueue&             q
00169 )
00170 : Proxy(poa),
00171   EventQueue::Reader(q),
00172   _target(CosEventComm::PushConsumer::_nil())
00173 {
00174   // pass
00175 }
00176 
00177 
00178 bool ProxyPushSupplier_i::trigger()
00179 {
00180   if(!CORBA::is_nil(_req) && _req->poll_response()) // response has arrived
00181   {
00182     CORBA::Environment_var env=_req->env();
00183     if(!CORBA::is_nil(env) && env->exception())
00184     {
00185       CORBA::Exception* ex =env->exception(); // No need to free exception.
00186       DB(1,"ProxyPushSupplier got exception: "<<ex->_name());
00187       _req=CORBA::Request::_nil();
00188       _target=CosEventComm::PushConsumer::_nil(); // disconnected.
00189       deactivateObject();
00190       return false; // No more work to do
00191     }
00192     _req=CORBA::Request::_nil();
00193   }
00194   if(CORBA::is_nil(_req) && !CORBA::is_nil(_target) && moreEvents())
00195   {
00196     _req=_target->_request("push");
00197     _req->add_in_arg() <<= *(nextEvent());
00198     _req->send_deferred();
00199   }
00200   return !CORBA::is_nil(_req); // More work to do, if _req NOT nil.
00201 }
00202 
00203 
00204 void ProxyPushSupplier_i::reincarnate(const OEP_prxy& prxy)
00205 {
00206   CosEventComm::PushConsumer_var pushConsumer =
00207     string_to_<CosEventComm::PushConsumer>(prxy.getIor());
00208   // Do not activate until we know that we have read a valid target.
00209   activateObjectWithId(prxy.getKey());
00210   connect_push_consumer(pushConsumer.in());
00211 }
00212 
00213 
00214 void ProxyPushSupplier_i::output(ostream &os)
00215 {
00216   Output out =basicOutput(os,"pxyPushSupplier",3,this,_target.in());
00217 }
00218 
00219 
00220 }; // end namespace OmniEvents

Generated on Fri Dec 12 10:53:03 2003 for OmniEvents by doxygen1.2.15