1 // -*- Mode: C++; -*-
2 //                            Package   : omniORB
3 // giopRope.h                 Created on: 05/01/2001
4 //                            Author    : Sai Lai Lo (sll)
5 //
6 //    Copyright (C) 2003-2013 Apasphere Ltd
7 //    Copyright (C) 2001      AT&T Laboratories Cambridge
8 //
9 //    This file is part of the omniORB library
10 //
11 //    The omniORB library is free software; you can redistribute it and/or
12 //    modify it under the terms of the GNU Lesser General Public
13 //    License as published by the Free Software Foundation; either
14 //    version 2.1 of the License, or (at your option) any later version.
15 //
16 //    This library is distributed in the hope that it will be useful,
17 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
18 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19 //    Lesser General Public License for more details.
20 //
21 //    You should have received a copy of the GNU Lesser General Public
22 //    License along with this library. If not, see http://www.gnu.org/licenses/
23 //
24 //
25 // Description:
26 //	*** PROPRIETARY INTERFACE ***
27 //
28 
29 #ifndef __GIOPROPE_H__
30 #define __GIOPROPE_H__
31 
32 #include <omniORB4/omniTransport.h>
33 
34 #ifdef _core_attr
35 # error "A local CPP macro _core_attr has already been defined."
36 #endif
37 
38 #if defined(_OMNIORB_LIBRARY)
39 #     define _core_attr
40 #else
41 #     define _core_attr _OMNIORB_NTDLL_IMPORT
42 #endif
43 
44 class omniIOR;
45 
46 OMNI_NAMESPACE_BEGIN(omni)
47 
48 class giopStream;
49 class giopStrand;
50 
51 ////////////////////////////////////////////////////////////////////////
52 ////////////////////////////////////////////////////////////////////////
53 class giopRope : public Rope, public RopeLink {
54 public:
55 
56   static int selectRope(const giopAddressList& addrlist,
57 			omniIOR::IORInfo*      info,
58 			Rope*&                 rope,
59 			CORBA::Boolean&        is_local);
60   // Given an address list, return a rope that can be used to talk to
61   // remote objects in that address space. If the address list is in fact
62   // pointing to ourselves, set <is_local> to true.
63   // Returns true if either the addresses are local or the rope is found.
64   // Returns false if no suitable rope is found.
65   // If a rope is returned, the reference count on the rope is already
66   // incremented by 1.
67   //
68   // This is normally the entry function that causes a rope to be created
69   // in the first place.
70   //
71   // Thread Safety preconditions:
72   //    Caller must not hold omniTransportLock, it is used internally for
73   //    synchronisation.
74 
75   giopRope(const giopAddressList& addrlist, omniIOR::IORInfo* info);
76   // <addrlist> is copied.
77   // Reference count is initialised to 0.
78   // No thread safety precondition
79 
80   giopRope(giopAddress* addr);
81   // Construct with a single address. Used for server-side bidir.
82   // <addr> is consumed by this instance.
83   // No thread safety precondition
84 
85   virtual ~giopRope();
86   // No thread safety precondition
87 
88 
89   virtual IOP_C* acquireClient(const omniIOR*      ior,
90 			       const CORBA::Octet* key,
91 			       CORBA::ULong        keysize,
92 			       omniCallDescriptor* cd);
93   // Acquire a GIOP_C from this rope.
94   //
95   // Thread Safety preconditions:
96   //    Caller must not hold omniTransportLock, it is used internally for
97   //    synchronisation.
98 
99   void releaseClient(IOP_C*);
100   // Release the GIOP_C back to this rope. The GIOP_C must have been acquired
101   // previously through acquireClient from this rope. Passing in a GIOP_C
102   // from a different rope would result in undefined behaviour.
103   //
104   // Thread Safety preconditions:
105   //    Caller must not hold omniTransportLock, it is used internally for
106   //    synchronisation.
107 
108 
109   void incrRefCount();
110   // Increment the reference count by 1.
111   //
112   // Thread Safety preconditions:
113   //    Caller must not hold omniTransportLock, it is used internally for
114   //    synchronisation.
115 
116   virtual void decrRefCount();
117   // Decrement the reference count by 1. If the reference count becomes
118   // 0, the rope will be deleted at the earliest convenient time.
119   //
120   // Thread Safety preconditions:
121   //    Caller must not hold omniTransportLock, it is used internally for
122   //    synchronisation.
123 
124   void disconnect();
125   // Forcibly disconnect all strands.
126   //
127   // Thread Safety preconditions:
128   //    Caller must not hold omniTransportLock, it is used internally for
129   //    synchronisation.
130 
131   CORBA::Boolean hasAddress(const giopAddress*);
132   // Returns true if the address is in this rope's address list; false
133   // otherwise.
134   //
135   // Thread Safety preconditions:
136   //    None: the list of addresses is constant once set.
137 
138   virtual const giopAddress* notifyCommFailure(const giopAddress*,
139 					       CORBA::Boolean heldlock);
140   // Caller detects an error in sending or receiving data with this address.
141   // It calls this function to indicate to the rope that the address is bad.
142   // If the rope has other alternative addresses, it should select another
143   // address next time acquireClient is called.
144   //
145   // Returns the next address the rope will try. In the case when there is
146   // only 1 address, the return value will be the same as the argument.
147   // When there are more than 1 addresses and the caller decides to retry
148   // an invocation on all of these addresses, the caller can use the return
149   // value to decide when all the addresses have been tried. This
150   // is done by comparing the return value with the address in use when
151   // the first call is made.
152   //
153   // Thread Safety preconditions:
154   //    Internally, omniTransportLock is used for synchronisation, if
155   //    <heldlock> is true, the caller already holds the lock.
156 
157   void resetAddressOrder(CORBA::Boolean heldlock, giopStrand* strand);
158   // If the retainAddressOrder parameter is not set true, reset the
159   // address order to ensure the next connection attempt uses the
160   // highest priority address. If names were resolved to addresses,
161   // clears the resolved names so they are re-resolved next call.
162   //
163   // strand is a pointer to the strand that encountered an error
164   // leading to this call, or null in the case of an idle rope.
165   //
166   // Thread Safety preconditions:
167   //    Internally, omniTransportLock is used for synchronisation, if
168   //    <heldlock> is true, the caller already holds the lock.
169 
170 
171   static void resetIdleRopeAddresses();
172   // If the retainAddressOrder parameter is not set true, reset the
173   // address order in any idle ropes, to ensure the next connection
174   // attempt uses the highest priority address. If names were resolved
175   // to addresses, clears the resolved names so they are re-resolved
176   // next call.
177   //
178   // Thread Safety preconditions:
179   //    Caller must not hold omniTransportLock.
180 
181 
182   // Access functions to change the rope parameters. Notice that these
183   // functions does not perform any mutual exclusion internally. It is
184   // however safe to change the parameters while the rope is in use.  The
185   // new parameter value will take effect as soon as appropriate.  For
186   // instance, decrease the max. number of strand will not have any effect
187   // on these strands that have already been created.
188 
oneCallPerConnection()189   CORBA::Boolean oneCallPerConnection() {
190     // No thread safety precondition, use with extreme care
191     // return True(1) if only one call can be in progress at any time on
192     // each strand.
193     // return False(0) if the same strand can be used to carry multiple
194     // concurrent calls.
195     // The default is True.
196     return pd_oneCallPerConnection;
197   }
198 
oneCallPerConnection(CORBA::Boolean yes)199   void oneCallPerConnection(CORBA::Boolean yes) {
200     // No thread safety precondition, use with extreme care
201     pd_oneCallPerConnection = yes;
202   }
203 
maxStrands()204   CORBA::ULong maxStrands() {
205     // No thread safety precondition, use with extreme care
206     // Return the maximum no. of strands that can be opened.
207     // The default is omniORB::maxTcpConnectionPerServer.
208     return pd_maxStrands;
209   }
210 
maxStrands(CORBA::ULong max)211   void maxStrands(CORBA::ULong max) {
212     // No thread safety precondition, use with extreme care
213     if (max == 0) max = 1;
214     pd_maxStrands = max;
215   }
216 
217   friend class giopStream;
218   friend class giopStrand;
219   friend class omni_giopRope_initialiser;
220   friend class omni_giopbidir_initialiser;
221 
222  protected:
223   int                      pd_refcount;
224   giopAddressList          pd_addresses;     // Addresses of the remote server
225   size_t                   pd_ior_addr_size; // Number of addresses in IOR
226   omnivector<CORBA::ULong> pd_addresses_order;
227   size_t                   pd_address_in_use;
228   CORBA::ULong             pd_maxStrands;
229   CORBA::Boolean           pd_oneCallPerConnection;
230   int                      pd_nwaiting;
231   omni_tracedcondition     pd_cond;
232   CORBA::ULong             pd_flags;      // Selected flags in use
233   CORBA::ULong             pd_ior_flags;  // Flags requested in IOR
234   CORBA::Boolean           pd_offerBiDir; // State of orbParameters::
235                                           // offerBiDir... at time of creation.
236   CORBA::Boolean           pd_addrs_filtered;
237   CORBA::Boolean           pd_filtering;
238 
239   static _core_attr RopeLink ropes;
240   // All ropes created by selectRope are linked together by this list.
241 
242   virtual void realIncrRefCount();
243   // Really increment the reference count.
244   //
245   // Thread Safety preconditions:
246   //    Caller must hold omniTransportLock.
247 
248   virtual CORBA::Boolean match(const giopAddressList&,
249                                omniIOR::IORInfo* info) const;
250   // Return true if the address list matches EXACTLY those of this
251   // rope, and the IORInfo policies match.
252   // No thread safety precondition
253 
254   virtual void filterAndSortAddressList();
255   // Use the clientTransportRules to filter and sort the address list
256   // in pd_addresses, storing the resulting order in
257   // pd_addresses_order, and set pd_flags appropriately. Any names in
258   // pd_addresses are resolved and the resulting addresses are added
259   // to pd_addresses.
260   //
261   // Caller holds omniTransportLock.
262 
263  private:
264   giopRope();
265   giopRope(const giopRope&);
266   giopRope& operator=(const giopRope&);
267 };
268 
269 OMNI_NAMESPACE_END(omni)
270 
271 #undef _core_attr
272 
273 #endif // __GIOPROPE_H__
274