summaryrefslogtreecommitdiff
path: root/TAO/tao/Strategies/Optimized_Connection_Endpoint_Selector.cpp
blob: dae584e81525036a15bd7cc4a85fac213e8eb2d0 (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
// -*- C++ -*-

#include "tao/Strategies/Optimized_Connection_Endpoint_Selector.h"

#include "tao/debug.h"
#include "tao/Stub.h"
#include "tao/Profile.h"
#include "tao/Endpoint.h"
#include "tao/Base_Transport_Property.h"
#include "tao/ORB_Core.h"
#include "tao/Transport.h"
#include "tao/Profile_Transport_Resolver.h"

ACE_RCSID (tao,
           Invocation_Endpoint_Selectors,
           "$Id$")

TAO_BEGIN_VERSIONED_NAMESPACE_DECL

// ****************************************************************

ACE_Time_Value TAO_Optimized_Connection_Endpoint_Selector::timeout_;

TAO_Optimized_Connection_Endpoint_Selector::TAO_Optimized_Connection_Endpoint_Selector (const ACE_Time_Value &tv)
{
  TAO_Optimized_Connection_Endpoint_Selector::timeout_ = tv;
  if (TAO_debug_level)
    {
      ACE_DEBUG ((LM_DEBUG,
                  ACE_TEXT ("TAO(%P|%t) Optimized Connection Enpoint Selector:")
                  ACE_TEXT ("Initializing timeout hook tv = %d sec, %d usec\n"),
              tv.sec(), tv.usec()));
    }
  if (tv > ACE_Time_Value::zero)
    {
      TAO_ORB_Core::connection_timeout_hook
        (TAO_Optimized_Connection_Endpoint_Selector::hook);
    }
}

TAO_Optimized_Connection_Endpoint_Selector::~TAO_Optimized_Connection_Endpoint_Selector (void)
{
}


void
TAO_Optimized_Connection_Endpoint_Selector::hook (TAO_ORB_Core *,
                                                  TAO_Stub *,
                                                  bool &has_timeout,
                                                  ACE_Time_Value &tv)
{
  has_timeout =
    TAO_Optimized_Connection_Endpoint_Selector::
    timeout_ > ACE_Time_Value::zero;
  if (has_timeout)
    tv = TAO_Optimized_Connection_Endpoint_Selector::timeout_;
}

int
TAO_Optimized_Connection_Endpoint_Selector::check_profile (TAO_Profile *p,
                                                           TAO::Profile_Transport_Resolver *r)
{
  TAO_Endpoint *effective_endpoint = 0;

  r->profile(p);
  effective_endpoint = p->endpoint ();
  size_t endpoint_count = p->endpoint_count();
  for (size_t i = 0; i < endpoint_count; ++i)
    {
      TAO_Base_Transport_Property desc (effective_endpoint);
      if (r->find_transport(&desc))
        return 1;
      // Go to the next endpoint in this profile
      effective_endpoint = effective_endpoint->next();
    }
  return 0;
}

void
TAO_Optimized_Connection_Endpoint_Selector::select_endpoint
  ( TAO::Profile_Transport_Resolver *r,
    ACE_Time_Value *max_wait_time
    ACE_ENV_ARG_DECL)
{
  TAO_Stub *stub = r->stub();
  TAO_Profile *p = stub->profile_in_use();

  // first, look for the endpoints for the current profile in use.
  // if that is available then go for it.

  if (this->check_profile (p, r) != 0)
    return;

  // next, look for any other profiles. If the stub has any forward profiles,
  // use those, otherwise look at the base profiles. This separation is
  // necessary to avoid re-using a corbaloc or other previously forwarded
  // profile.

  const TAO_MProfile *profiles = stub->forward_profiles();
  if (profiles != 0)
    {
      for (CORBA::ULong count = 0; count <  profiles->profile_count(); count++)
        {
          p = const_cast<TAO_Profile *>(profiles->get_profile(count));
          if (this->check_profile (p, r) != 0)
            {
              if (stub->profile_in_use() != p)
                {
                  // thread-safe way to coerse stub to this profile.
                  stub->reset_profiles();
                  while (stub->profile_in_use() != p)
                    if (stub->next_profile_retry() == 0)
                      break;
                }
              return;
            }
        }
    }
  else
    {
      do
        {
          p = stub->profile_in_use();
          if (this->check_profile(p, r) != 0)
            return;
        }
      while (stub->next_profile_retry () != 0);
    }



  // at this point, we do not have an existing transport, so we must
  // reset the profile list and try establishing connections via the
  // connector(s).

  do
    {
      r->profile (r->stub ()->profile_in_use ());

      // Check whether we need to do a blocked wait or we have a
      // non-blocked wait and we support that.  If this is not the
      // case we can't use this profile so try the next.
      if (r->blocked_connect () ||
         (!r->blocked_connect () && r->profile ()->supports_non_blocking_oneways ()))
        {
          const size_t endpoint_count =
            r->profile ()->endpoint_count ();

          TAO_Endpoint *ep =
            r->profile ()->endpoint ();

          for (size_t i = 0; i < endpoint_count; ++i)
            {
              TAO_Base_Transport_Property desc (ep);
              const bool retval =
                r->try_connect (&desc,
                                max_wait_time
                                ACE_ENV_ARG_PARAMETER);
              ACE_CHECK;

              // Check if the connect has completed.
              if (retval)
                return;

              // Go to the next endpoint in this profile.
              ep = ep->next ();
            }
        }
    }
  while (r->stub ()->next_profile_retry () != 0);

  // If we get here, we completely failed to find an endpoint selector
  // that we know how to use, so throw an exception.
  ACE_THROW (CORBA::TRANSIENT (CORBA::OMGVMCID | 2,
                               CORBA::COMPLETED_NO));
}

TAO_END_VERSIONED_NAMESPACE_DECL