summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/orbsvcs/Trader/Offer_Database.h
blob: 3087ea49d944b52fe1d6531298b3d52139791c79 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
// -*- C++ -*-

//=============================================================================
/**
 *  @file    Offer_Database.h
 *
 *  $Id$
 *
 *  @author Seth Widoff <sbw1@cs.wustl.edu>
 */
//=============================================================================


#ifndef TAO_OFFER_DATABASE_H
#define TAO_OFFER_DATABASE_H
#include /**/ "ace/pre.h"

#include "orbsvcs/Trader/Trader.h"
#include "orbsvcs/Trader/Offer_Iterators.h"
#include "ace/Null_Mutex.h"

TAO_BEGIN_VERSIONED_NAMESPACE_DECL

template <class LOCK_TYPE> class TAO_Service_Offer_Iterator;

/**
 * @class TAO_Offer_Database
 *
 * The TAO_Offer_Database encapsulates the mapping of service
 * types to those offers exported with that service types. The
 * underlying structure is a map of maps. The first maps maps the
 * service type name to a map of exported offers. The second map
 * maps the identifying index for that offer within the service
 * types. So a service type name and an index uniquely identifies an
 * exported offer. In fact, when the register export interface
 * returns a CosTrading::OfferId, it's returning no more than a
 * simple string concatenation of these two values. In addition to
 * all these wonderful things, the TAO_Offer_Database has built-in
 * locking, one reader/writer-style lock for modifying the top-level
 * map and a reader/writer-style for each of the offer
 * maps. Needless to say the locks are acquired when the
 * TAO_Offer_Database performs operations on the structures they
 * guard.
 * NOTE: TAO_Offer_Database needs to be parameterized by a
 * READER/WRITER LOCK, a RECURSIVE MUTEX, or a NULL MUTEX, not a
 * simple binary mutex! Mutexes will cause deadlock when you try to
 * contruct an iterator (which acquires a read lock on the map under
 * an existing read lock). Just don't do it, ok?
 */
template <class LOCK_TYPE>
class TAO_Offer_Database
{
  friend class TAO_Service_Offer_Iterator<LOCK_TYPE>;
public:

  // Traits
  typedef TAO_Service_Offer_Iterator<LOCK_TYPE> offer_iterator;

  /// No arg constructor.
  TAO_Offer_Database (void);

  ~TAO_Offer_Database (void);

  /// Add an offer of type <type> and generate a CosTrading::OfferId
  /// for it. Returns 0 on failure.
  CosTrading::OfferId insert_offer (const char* type,
                                    CosTrading::Offer* offer);

  int remove_offer (const CosTrading::OfferId offer_id
                    ACE_ENV_ARG_DECL)
    ACE_THROW_SPEC ((CosTrading::IllegalOfferId,
                    CosTrading::UnknownOfferId));

  /// Lookup an offer whose offer_id is <offer_id>, and return
  /// it. Otherwise, throw the appropriate exception.
  CosTrading::Offer* lookup_offer (const CosTrading::OfferId offer_id
                                   ACE_ENV_ARG_DECL)
    ACE_THROW_SPEC ((CosTrading::IllegalOfferId,
                    CosTrading::UnknownOfferId));

  /**
   * Lookup an offer whose OfferId is <offer_id> and return in
   * <type_name> the type name of the object. Type name is just a
   * pointer to a location in offer_id, so DON'T DELETE IT.
   */
  CosTrading::Offer* lookup_offer (const CosTrading::OfferId offer_id,
                                   char*& type_name
                                   ACE_ENV_ARG_DECL)
    ACE_THROW_SPEC ((CosTrading::IllegalOfferId,
                    CosTrading::UnknownOfferId));

  /// Return an iterator that will traverse and return all the offer
  /// ids in the service type map.
  TAO_Offer_Id_Iterator* retrieve_all_offer_ids (void);

  struct Offer_Map_Entry
  {
    TAO_Offer_Map* offer_map_;
    CORBA::ULong counter_;
    LOCK_TYPE lock_;
  };

  typedef ACE_Hash_Map_Manager_Ex
    <
    CORBA::String_var,
    Offer_Map_Entry*,
    ACE_Hash<CORBA::String_var>,
    ACE_Equal_To<CORBA::String_var>,
    ACE_Null_Mutex
    >
    Offer_Database;

private:

  // The internal id is a pointer here, not only to avoid copying,
  // since we would only copy on insertion, and we only insert once
  // --- with an empty Offer_Map_Entry --- but also since most locks
  // have unimplemented copy constructors.

  /// Lookup an offer whose type is <type> and id, <id>. Return 0 on
  /// failure.
  CosTrading::Offer* lookup_offer (const char* type,
                                   CORBA::ULong id);

  /**
   * Remove an offers whose id is <offer_id>. Returns 0 on success, -1
   * on failure, and throws a CosTrading::IllegalOfferId if it can't
   * parse the CosTrading::OfferId.
   */
  int remove_offer (const char* type, CORBA::ULong id);

  /// Take in a service type name for the offer the current value of
  /// of the counter and generate an offer id.
  static CosTrading::OfferId generate_offer_id (const char *type_name,
                                                CORBA::ULong id);

  /// Take in a previously generated offer id and return the type
  /// and id that were used to generate the offer id.
  static void parse_offer_id (const CosTrading::OfferId offer_id,
                              char* &service_type,
                              CORBA::ULong& id
                              ACE_ENV_ARG_DECL)
    ACE_THROW_SPEC ((CosTrading::IllegalOfferId));

  // = Disallow these operations.
  ACE_UNIMPLEMENTED_FUNC (void operator= (const TAO_Offer_Database<LOCK_TYPE> &))
  ACE_UNIMPLEMENTED_FUNC (TAO_Offer_Database (const TAO_Offer_Database<LOCK_TYPE> &))

  LOCK_TYPE db_lock_;

  Offer_Database offer_db_;
  // The protected data structure.
};

/**
 * @class TAO_Service_Offer_Iterator
 *
 * @brief TAO_Service_Offer_Iterator iterates over the set of exported
 * offers for a given type. Handily, it takes care of all the
 * necessary locking, acquiring them in the constructor, and
 * releasing them in the destructor.
 */
template <class LOCK_TYPE>
class TAO_Service_Offer_Iterator
{
 public:

  typedef TAO_Offer_Database<LOCK_TYPE> Offer_Database;

  TAO_Service_Offer_Iterator (const char* type,
                              TAO_Offer_Database<LOCK_TYPE>& offer_database);

  /// Release all the locks acquired.
  ~TAO_Service_Offer_Iterator (void);

  /// Returns 1 if there are more offers, 0 otherwise.
  int has_more_offers (void);

  /// Get the id for the current offer.
  CosTrading::OfferId get_id (void);

  /// Returns the next offer in the series.
  CosTrading::Offer* get_offer (void);

  /// Advances the iterator 1.
  void next_offer (void);

 private:
  // Protected constructor.

  /// Lock the top_level map.
  TAO_Offer_Database<LOCK_TYPE>& stm_;

  /// Lock for the internal map.
  LOCK_TYPE* lock_;

  /// Iterator over the actual offer map.
  TAO_Offer_Map::iterator* offer_iter_;

  /// The name of the type. Used for constructing offer ids.
  const char* type_;
};

TAO_END_VERSIONED_NAMESPACE_DECL

#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
#include "orbsvcs/Trader/Offer_Database.cpp"
#endif  /* ACE_TEMPLATES_REQUIRE_SOURCE */

#include /**/ "ace/post.h"
#endif /* TAO_SERVICE_TYPE_MAP_H */