00001 // -*- C++ -*- 00002 00003 //============================================================================= 00004 /** 00005 * @file Offer_Database.h 00006 * 00007 * $Id: Offer_Database.h 77001 2007-02-12 07:54:49Z johnnyw $ 00008 * 00009 * @author Seth Widoff <sbw1@cs.wustl.edu> 00010 */ 00011 //============================================================================= 00012 00013 00014 #ifndef TAO_OFFER_DATABASE_H 00015 #define TAO_OFFER_DATABASE_H 00016 #include /**/ "ace/pre.h" 00017 00018 #include "orbsvcs/Trader/Trader.h" 00019 #include "orbsvcs/Trader/Offer_Iterators.h" 00020 #include "ace/Null_Mutex.h" 00021 00022 TAO_BEGIN_VERSIONED_NAMESPACE_DECL 00023 00024 template <class LOCK_TYPE> class TAO_Service_Offer_Iterator; 00025 00026 /** 00027 * @class TAO_Offer_Database 00028 * 00029 * The TAO_Offer_Database encapsulates the mapping of service 00030 * types to those offers exported with that service types. The 00031 * underlying structure is a map of maps. The first maps maps the 00032 * service type name to a map of exported offers. The second map 00033 * maps the identifying index for that offer within the service 00034 * types. So a service type name and an index uniquely identifies an 00035 * exported offer. In fact, when the register export interface 00036 * returns a CosTrading::OfferId, it's returning no more than a 00037 * simple string concatenation of these two values. In addition to 00038 * all these wonderful things, the TAO_Offer_Database has built-in 00039 * locking, one reader/writer-style lock for modifying the top-level 00040 * map and a reader/writer-style for each of the offer 00041 * maps. Needless to say the locks are acquired when the 00042 * TAO_Offer_Database performs operations on the structures they 00043 * guard. 00044 * NOTE: TAO_Offer_Database needs to be parameterized by a 00045 * READER/WRITER LOCK, a RECURSIVE MUTEX, or a NULL MUTEX, not a 00046 * simple binary mutex! Mutexes will cause deadlock when you try to 00047 * contruct an iterator (which acquires a read lock on the map under 00048 * an existing read lock). Just don't do it, ok? 00049 */ 00050 template <class LOCK_TYPE> 00051 class TAO_Offer_Database 00052 { 00053 friend class TAO_Service_Offer_Iterator<LOCK_TYPE>; 00054 public: 00055 00056 // Traits 00057 typedef TAO_Service_Offer_Iterator<LOCK_TYPE> offer_iterator; 00058 00059 /// No arg constructor. 00060 TAO_Offer_Database (void); 00061 00062 ~TAO_Offer_Database (void); 00063 00064 /// Add an offer of type <type> and generate a CosTrading::OfferId 00065 /// for it. Returns 0 on failure. 00066 CosTrading::OfferId insert_offer (const char* type, 00067 CosTrading::Offer* offer); 00068 00069 int remove_offer (const CosTrading::OfferId offer_id); 00070 00071 /// Lookup an offer whose offer_id is <offer_id>, and return 00072 /// it. Otherwise, throw the appropriate exception. 00073 CosTrading::Offer* lookup_offer (const CosTrading::OfferId offer_id); 00074 00075 /** 00076 * Lookup an offer whose OfferId is <offer_id> and return in 00077 * <type_name> the type name of the object. Type name is just a 00078 * pointer to a location in offer_id, so DON'T DELETE IT. 00079 */ 00080 CosTrading::Offer* lookup_offer (const CosTrading::OfferId offer_id, 00081 char*& type_name); 00082 00083 /// Return an iterator that will traverse and return all the offer 00084 /// ids in the service type map. 00085 TAO_Offer_Id_Iterator* retrieve_all_offer_ids (void); 00086 00087 struct Offer_Map_Entry 00088 { 00089 TAO_Offer_Map* offer_map_; 00090 CORBA::ULong counter_; 00091 LOCK_TYPE lock_; 00092 }; 00093 00094 typedef ACE_Hash_Map_Manager_Ex 00095 < 00096 CORBA::String_var, 00097 Offer_Map_Entry*, 00098 ACE_Hash<CORBA::String_var>, 00099 ACE_Equal_To<CORBA::String_var>, 00100 ACE_Null_Mutex 00101 > 00102 Offer_Database; 00103 00104 private: 00105 00106 // The internal id is a pointer here, not only to avoid copying, 00107 // since we would only copy on insertion, and we only insert once 00108 // --- with an empty Offer_Map_Entry --- but also since most locks 00109 // have unimplemented copy constructors. 00110 00111 /// Lookup an offer whose type is <type> and id, <id>. Return 0 on 00112 /// failure. 00113 CosTrading::Offer* lookup_offer (const char* type, 00114 CORBA::ULong id); 00115 00116 /** 00117 * Remove an offers whose id is <offer_id>. Returns 0 on success, -1 00118 * on failure, and throws a CosTrading::IllegalOfferId if it can't 00119 * parse the CosTrading::OfferId. 00120 */ 00121 int remove_offer (const char* type, CORBA::ULong id); 00122 00123 /// Take in a service type name for the offer the current value of 00124 /// of the counter and generate an offer id. 00125 static CosTrading::OfferId generate_offer_id (const char *type_name, 00126 CORBA::ULong id); 00127 00128 /// Take in a previously generated offer id and return the type 00129 /// and id that were used to generate the offer id. 00130 static void parse_offer_id (const CosTrading::OfferId offer_id, 00131 char* &service_type, 00132 CORBA::ULong& id); 00133 00134 // = Disallow these operations. 00135 ACE_UNIMPLEMENTED_FUNC (void operator= (const TAO_Offer_Database<LOCK_TYPE> &)) 00136 ACE_UNIMPLEMENTED_FUNC (TAO_Offer_Database (const TAO_Offer_Database<LOCK_TYPE> &)) 00137 00138 LOCK_TYPE db_lock_; 00139 00140 Offer_Database offer_db_; 00141 // The protected data structure. 00142 }; 00143 00144 /** 00145 * @class TAO_Service_Offer_Iterator 00146 * 00147 * @brief TAO_Service_Offer_Iterator iterates over the set of exported 00148 * offers for a given type. Handily, it takes care of all the 00149 * necessary locking, acquiring them in the constructor, and 00150 * releasing them in the destructor. 00151 */ 00152 template <class LOCK_TYPE> 00153 class TAO_Service_Offer_Iterator 00154 { 00155 public: 00156 00157 typedef TAO_Offer_Database<LOCK_TYPE> Offer_Database; 00158 00159 TAO_Service_Offer_Iterator (const char* type, 00160 TAO_Offer_Database<LOCK_TYPE>& offer_database); 00161 00162 /// Release all the locks acquired. 00163 ~TAO_Service_Offer_Iterator (void); 00164 00165 /// Returns 1 if there are more offers, 0 otherwise. 00166 int has_more_offers (void); 00167 00168 /// Get the id for the current offer. 00169 CosTrading::OfferId get_id (void); 00170 00171 /// Returns the next offer in the series. 00172 CosTrading::Offer* get_offer (void); 00173 00174 /// Advances the iterator 1. 00175 void next_offer (void); 00176 00177 private: 00178 // Protected constructor. 00179 00180 /// Lock the top_level map. 00181 TAO_Offer_Database<LOCK_TYPE>& stm_; 00182 00183 /// Lock for the internal map. 00184 LOCK_TYPE* lock_; 00185 00186 /// Iterator over the actual offer map. 00187 TAO_Offer_Map::iterator* offer_iter_; 00188 00189 /// The name of the type. Used for constructing offer ids. 00190 const char* type_; 00191 }; 00192 00193 TAO_END_VERSIONED_NAMESPACE_DECL 00194 00195 #if defined (ACE_TEMPLATES_REQUIRE_SOURCE) 00196 #include "orbsvcs/Trader/Offer_Database.cpp" 00197 #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ 00198 00199 #include /**/ "ace/post.h" 00200 #endif /* TAO_SERVICE_TYPE_MAP_H */