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

pushcons.cc

Go to the documentation of this file.
00001 // -*- Mode: C++; -*-
00002 //                            Package   : omniEvents
00003 //   pushcons.cc              Created   : 1/4/98
00004 //                            Author    : Paul Nader (pwn)
00005 //
00006 //    Copyright (C) 1998 Paul Nader.
00007 //
00008 //    This file is part of the omniEvents application.
00009 //
00010 //    omniEvents is free software; you can redistribute it and/or
00011 //    modify it under the terms of the GNU Lesser General Public
00012 //    License as published by the Free Software Foundation; either
00013 //    version 2.1 of the License, or (at your option) any later version.
00014 //
00015 //    omniEvents is distributed in the hope that it will be useful,
00016 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 //    Lesser General Public License for more details.
00019 //
00020 //    You should have received a copy of the GNU Lesser General Public
00021 //    License along with this library; if not, write to the Free Software
00022 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023 //
00024 // Description:
00025 //    Push Model consumer implementation
00026 //      
00027 
00028 /*
00029   $Log: pushcons.cc,v $
00030   Revision 1.3  2003/11/03 22:19:56  alextingle
00031   Removed all platform specific switches. Now uses autoconf, config.h.
00032   Removed stub header in order to allow makefile dependency checking to work
00033   correctly.
00034   Corrected usage of omni_condition/omni_mutex. Mutexes are now always unlocked by
00035   the same thread that locked them.
00036 
00037   Revision 1.1.1.1.2.1  2002/09/28 22:20:51  shamus13
00038   Added ifdefs to enable omniEvents to compile
00039   with both omniORB3 and omniORB4. If __OMNIORB4__
00040   is defined during compilation, omniORB4 headers
00041   and command line option syntax is used, otherwise
00042   fall back to omniORB3 style.
00043 
00044   Revision 1.1.1.1  2002/09/25 19:00:26  shamus13
00045   Import of OmniEvents source tree from release 2.1.1
00046 
00047   Revision 0.13  2000/08/30 04:39:48  naderp
00048   Port to omniORB 3.0.1.
00049 
00050   Revision 0.12  2000/03/16 05:37:27  naderp
00051   Added stdlib.h for getopt.
00052 
00053   Revision 0.11  2000/03/06 13:27:02  naderp
00054   Using util getRootNamingContext function.
00055   Using stub headers.
00056   Fixed error messages.
00057 
00058   Revision 0.10  2000/03/02 03:20:24  naderp
00059   Added retry resiliency for handling COMM_FAUILURE exceptions.
00060 
00061   Revision 0.9  1999/11/02 13:39:15  naderp
00062   Added <signal.h>
00063 
00064   Revision 0.8  1999/11/02 07:57:04  naderp
00065   Updated usage.
00066 
00067 Revision 0.7  99/11/01  18:10:29  18:10:29  naderp (Paul Nader)
00068 Added ahndling of COMM_FAILURE exception for connect_push_consumer.
00069 
00070 Revision 0.6  99/11/01  16:11:03  16:11:03  naderp (Paul Nader)
00071 omniEvents 2.0 Release.
00072 
00073 Revision 0.5  99/10/27  19:46:01  19:46:01  naderp (Paul Nader)
00074 Ignoring Unix SIGPIPE signal.
00075 Catching COMM_FAILURE exception for obtain_push_supplier.
00076 Continuing if it fails to obtain Proxy Supplier.
00077 Try/Catch block for disconnect_push_supplier.
00078 
00079 Revision 0.4  99/04/23  16:05:46  16:05:46  naderp (Paul Nader)
00080 gcc port.
00081 
00082 Revision 0.3  99/04/23  09:34:03  09:34:03  naderp (Paul Nader)
00083 Windows Port.
00084 
00085 Revision 0.2  99/04/21  18:06:26  18:06:26  naderp (Paul Nader)
00086 *** empty log message ***
00087 
00088 Revision 0.1.1.1  98/11/27  16:59:37  16:59:37  naderp (Paul Nader)
00089 Added -s option to sleep after disconnecting.
00090 
00091 Revision 0.1  98/11/25  14:08:21  14:08:21  naderp (Paul Nader)
00092 Initial Revision
00093 
00094 */
00095 
00096 #ifdef HAVE_CONFIG_H
00097 #  include "config.h"
00098 #endif
00099 
00100 #ifdef HAVE_GETOPT
00101 #  include <unistd.h>
00102 extern char* optarg;
00103 extern int optind;
00104 #else
00105 #  include "getopt.h"
00106 #endif
00107 
00108 #ifdef HAVE_IOSTREAM
00109 #  include <iostream>
00110 #else
00111 #  include <iostream.h>
00112 #endif
00113 
00114 #ifdef HAVE_STD_IOSTREAM
00115 using namespace std;
00116 #endif
00117 
00118 #ifdef HAVE_STDLIB_H
00119 #  include <stdlib.h>
00120 #endif
00121 
00122 #ifdef HAVE_SIGNAL_H
00123 #  include <signal.h>
00124 #endif
00125 
00126 #include "naming.h"
00127 
00128 #include "CosEventComm.hh"
00129 #include "CosEventChannelAdmin.hh"
00130 
00131 static omni_mutex mutex;
00132 static omni_condition connect_cond(&mutex);
00133 static void usage();
00134 
00135 class Consumer_i : virtual public CosEventComm::_sk_PushConsumer {
00136 public:
00137   Consumer_i (long disconnect = 0) : _disconnect(disconnect) {}
00138 
00139   void push (const CORBA::Any& data);
00140   void disconnect_push_consumer ();
00141 
00142 private:
00143   long _disconnect;
00144 };
00145 
00146 void Consumer_i::push (const CORBA::Any& data) {
00147   CORBA::ULong l;
00148   static int i = 0;
00149 
00150   i++;
00151   data >>= l;
00152   cout << "Push Consumer: push () called. Data : "
00153        << l
00154        << endl;
00155 
00156   // Exersize Disconnect
00157   if (i == _disconnect) {
00158      i = 0;
00159      // NOTE : The proxy_supplier object is disposed at the server
00160      //        during the disconnect_push_supplier call. Do NOT
00161      //        use the proxy_supplier reference after disconnecting.
00162 
00163      // Signal main thread to disconnect and re-connect.
00164      connect_cond.signal();
00165   }
00166 }
00167 
00168 void Consumer_i::disconnect_push_consumer () {
00169   cout << "Push Consumer: disconnected." << endl;
00170 }
00171 
00172 int
00173 main(int argc, char **argv)
00174 {
00175   //
00176   // Start orb and boa.
00177 #if defined(HAVE_OMNIORB4)
00178   CORBA::ORB_ptr orb = CORBA::ORB_init(argc,argv,"omniORB4");
00179   CORBA::BOA_ptr boa = orb->BOA_init(argc,argv,"omniORB4_BOA");
00180 #else
00181   CORBA::ORB_ptr orb = CORBA::ORB_init(argc,argv,"omniORB3");
00182   CORBA::BOA_ptr boa = orb->BOA_init(argc,argv,"omniORB3_BOA");
00183 #endif
00184 
00185   // Process Options
00186   int c;
00187   int discnum = 0;
00188   int sleepInterval = 0;
00189   char *channelName = (char *) "EventChannel";
00190   char *channelKind = (char *) "EventChannel";
00191 
00192   while ((c = getopt(argc,argv,"hd:s:n:k:")) != EOF)
00193   {
00194      switch (c)
00195      {
00196         case 'd': discnum = atoi(optarg);
00197                   break;
00198 
00199         case 's': sleepInterval = atoi(optarg);
00200                   break;
00201 
00202         case 'n': channelName = optarg;
00203                   break;
00204 
00205         case 'k': channelKind = optarg;
00206                   break;
00207 
00208         case 'h':
00209         default : usage();
00210                   exit(-1);
00211                   break;
00212      }
00213   }
00214 
00215 #ifdef HAVE_SIGNAL_H
00216   // Ignore broken pipes
00217   signal(SIGPIPE, SIG_IGN);
00218 #endif
00219 
00220   Consumer_i* consumer = new Consumer_i (discnum);
00221   consumer->_obj_is_ready(boa);
00222 
00223   // Let the BOA know we are ready.
00224   boa->impl_is_ready(0,1);
00225 
00226   //
00227   // Obtain and narrow reference to Name Service.
00228   CosNaming::NamingContext_ptr rootContext;
00229   rootContext = getRootNamingContext(orb);
00230 
00231   //
00232   // Obtain Event Channel Object
00233   CosNaming::Name name;
00234   name.length (1);
00235   name[0].id = CORBA::string_dup (channelName);
00236   name[0].kind = CORBA::string_dup (channelKind);
00237 
00238   cout << "Looking for EventChannel" << endl;
00239   CosEventChannelAdmin::EventChannel_var channel;
00240   try {
00241     CORBA::Object_var obj = rootContext->resolve(name);
00242     channel = CosEventChannelAdmin::EventChannel::_narrow(obj);
00243     if (CORBA::is_nil(channel))
00244     {
00245        cerr << "Failed to narrow Event Channel reference !" << endl;
00246        exit(1);
00247     }
00248   }
00249   catch (CORBA::COMM_FAILURE& ex) {
00250      cerr << "Caught system exception COMM_FAILURE, unable to contact the "
00251           << "naming service !" << endl;
00252      exit(1);
00253   }
00254   catch (omniORB::fatalException& ex) {
00255      cerr << "Caught Fatal Exception !" << endl;
00256      throw;
00257   }
00258   catch (...) {
00259      cerr << "Cannot find event channel ! [\""
00260           << channelName << "\", \"" << channelKind << "\"]"
00261           << endl;
00262      exit (1);
00263   }
00264 
00265   //
00266   // Get Consumer admin interface - retrying on Comms Failure.
00267   CosEventChannelAdmin::ConsumerAdmin_var consumer_admin;
00268   while (1)
00269   {
00270      try {
00271         consumer_admin = channel->for_consumers ();
00272         if (CORBA::is_nil (consumer_admin))
00273         {
00274            cerr << "Event Channel returned consumer_admin nil reference !"
00275                 << endl;
00276            exit (1);
00277         }
00278         break;
00279      }
00280      catch (CORBA::COMM_FAILURE& ex) {
00281         cerr << "Caught COMM_FAILURE exception "
00282              << "obtaining Consumer Admin !. Retrying..."
00283              << endl;
00284         continue;
00285      }
00286      catch (...) {
00287         cerr << "Unexpected System Exception."
00288              << "Failed to obtain ConsumerAdmin !" << endl;
00289         exit (1);
00290      }
00291   }
00292   cerr << "Obtained ConsumerAdmin." << endl;
00293 
00294   while (1) {
00295      //
00296      // Get proxy supplier - retrying on Comms Failure.
00297      CosEventChannelAdmin::ProxyPushSupplier_var proxy_supplier;
00298      while (1)
00299      {
00300         try {
00301            proxy_supplier = consumer_admin->obtain_push_supplier ();
00302            if (CORBA::is_nil (proxy_supplier))
00303            {
00304               cerr << "Consumer Admin returned proxy_supplier nil reference !"
00305                    << endl;
00306               exit (1);
00307            }
00308            break;
00309         }
00310         catch (CORBA::COMM_FAILURE& ex) {
00311            cerr << "Caught COMM_FAILURE Exception "
00312                 << "obtaining Push Supplier !. Retrying..."
00313                 << endl;
00314            continue;
00315         }
00316         catch (...) {
00317            cerr << "Unexpected System Exception."
00318                 << "Failed to obtain Proxy Supplier !"
00319                 << endl;
00320            exit (1);
00321         }
00322      }
00323      cerr << "Obtained ProxyPushSupplier." << endl;
00324    
00325      //
00326      // Connect Push Consumer - retrying on Comms Failure.
00327      CosEventComm::PushConsumer::_duplicate(consumer->_this());
00328      while (1)
00329      {
00330         try {
00331            proxy_supplier->connect_push_consumer(consumer->_this());
00332            break;
00333         }
00334         catch (CORBA::BAD_PARAM& ex) {
00335            cerr << "Caught BAD_PARAM Exception connecting Push Consumer !"
00336                 << endl;
00337            exit (1);
00338         }
00339         catch (CosEventChannelAdmin::AlreadyConnected& ex) {
00340            cerr << "Push Consumer already connected !" 
00341                 << endl;
00342            break;
00343         }
00344         catch (CORBA::COMM_FAILURE& ex) {
00345            cerr << "Caught COMM_FAILURE exception "
00346                 << "connecting push consumer !. Retrying..."
00347                 << endl;
00348            continue;
00349         }
00350         catch (...) {
00351            cerr << "Unexpected System Exception. "
00352                 << "Failed to connect Push Consumer !"
00353                 << endl;
00354            exit (1);
00355         }
00356      }
00357      cerr << "Connected Push Consumer." << endl;
00358 
00359      // Wait for indication to disconnect before re-connecting.
00360      {
00361        omni_mutex_lock condition_lock(mutex);
00362        connect_cond.wait();
00363      }
00364 
00365      // Disconnect - retrying on Comms Failure.
00366      while (1)
00367      {
00368         try {
00369            proxy_supplier->disconnect_push_supplier();
00370            break;
00371         }
00372         catch (CORBA::COMM_FAILURE& ex) {
00373            cerr << "Caught COMM_FAILURE Exception "
00374                 << "disconnecting Push Consumer !. Retrying..."
00375                 << endl;
00376            continue;
00377         }
00378         catch (...) {
00379            cerr << "Unexpected System Exception. "
00380                 << "Failed to disconnect Push Consumer!."
00381                 << endl;
00382            exit (1);
00383         }
00384      }
00385      cerr << "Disconnected Push Consumer." << endl;
00386    
00387      // Yawn
00388      cerr << "Sleeping " << sleepInterval << " Seconds." << endl;
00389      omni_thread::sleep(sleepInterval);
00390   }
00391 
00392   // Not Reached
00393   // Destory Channel
00394   channel->destroy();
00395   cerr << "Destroyed channel !" << endl;
00396 
00397   return 0;
00398 }
00399 
00400 static void
00401 usage()
00402 {
00403    cerr << "\nusage: pushcons [-d n [-s n]] [-n name] [-k kind] [-h]\n" << endl;
00404    cerr << "         -d n   disconnect after n pushes" << endl;
00405    cerr << "         -s n   sleep n seconds after disconnecting" << endl;
00406    cerr << "         -n name specify channel name [\"EventChannel\"]" << endl;
00407    cerr << "         -k kind specify channel kind [\"EventChannel\"]" << endl;
00408    cerr << "         -h     display usage" << endl;
00409    cerr << endl;
00410 }

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