summaryrefslogtreecommitdiff
path: root/TAO/tao/Invocation_Endpoint_Selectors.cpp
blob: 18b5ed2dc75cbd81653b152e7ba8ee1b8364117d (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
// -*- C++ -*-

#include "tao/Invocation_Endpoint_Selectors.h"

#if !defined (__ACE_INLINE__)
#include "tao/Invocation_Endpoint_Selectors.i"
#endif /* __ACE_INLINE__ */

#include "tao/Invocation.h"
#include "tao/Stub.h"
#include "tao/Profile.h"
//$Id$
#include "Endpoint.h"
#include "Base_Transport_Property.h"
#include "Profile_Transport_Resolver.h"

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

TAO_Invocation_Endpoint_Selector::TAO_Invocation_Endpoint_Selector (void)
{
}

TAO_Invocation_Endpoint_Selector::~TAO_Invocation_Endpoint_Selector (void)
{
}

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

TAO_Default_Endpoint_Selector::TAO_Default_Endpoint_Selector (void)
{
}

TAO_Default_Endpoint_Selector::~TAO_Default_Endpoint_Selector (void)
{
}

void
TAO_Default_Endpoint_Selector::select_endpoint (
  TAO_GIOP_Invocation *invocation
  ACE_ENV_ARG_DECL)
{
  do
    {
      invocation->profile (invocation->stub ()->profile_in_use ());
      invocation->endpoint (invocation->profile ()->endpoint ());

      int status =
        this->endpoint_from_profile (invocation ACE_ENV_ARG_PARAMETER);
      ACE_CHECK;

      if (status == 1)
        return;
    }
  while (invocation->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));
}

void
TAO_Default_Endpoint_Selector::select_endpoint (
    TAO::Profile_Transport_Resolver *r,
    ACE_Time_Value *max_wait_time
    ACE_ENV_ARG_DECL)
{
  do
    {
      r->profile (r->stub ()->profile_in_use ());

      size_t endpoint_count =
        r->profile ()->endpoint_count();

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

      for (size_t i = 0; i < endpoint_count; ++i)
        {
          bool retval =
            r->try_connect (ep,
                            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));
}

void
TAO_Default_Endpoint_Selector::forward (TAO_GIOP_Invocation *invocation,
                                        const TAO_MProfile &mprofile
                                        ACE_ENV_ARG_DECL)
{
  invocation->stub ()->add_forward_profiles (mprofile);
  // This has to be and is thread safe.
  // TAO_Stub::add_forward_profiles() already makes a copy of the
  // MProfile, so do not make a copy here.


  // We may not need to do this since TAO_GIOP_Invocations
  // get created on a per-call basis. For now we'll play it safe.
  if (invocation->stub ()->next_profile () == 0)
    ACE_THROW (CORBA::TRANSIENT (
      CORBA::SystemException::_tao_minor_code (
        TAO_INVOCATION_LOCATION_FORWARD_MINOR_CODE,
        errno),
      CORBA::COMPLETED_NO));
}

void
TAO_Default_Endpoint_Selector::success (TAO_GIOP_Invocation *invocation)
{
  invocation->stub ()->set_valid_profile ();
}

void
TAO_Default_Endpoint_Selector::close_connection (TAO_GIOP_Invocation *invocation)
{
  // Get rid of any forwarding profiles and reset
  // the profile list to point to the first profile!
  // FRED For now we will not deal with recursive forwards!
  invocation->stub ()->reset_profiles ();
}


int
TAO_Default_Endpoint_Selector::endpoint_from_profile (
    TAO_GIOP_Invocation *invocation
    ACE_ENV_ARG_DECL)
{
  size_t endpoint_count =
    invocation->profile ()->endpoint_count();

  for (size_t i = 0; i < endpoint_count; ++i)
    {
      // If known endpoint, select it.
      if (invocation->endpoint () != 0)
        {
          TAO_Base_Transport_Property desc (invocation->endpoint ());

          int status =
            invocation->perform_call (desc ACE_ENV_ARG_PARAMETER);
          ACE_CHECK_RETURN (-1);

          // Check if the invocation has completed.
          if (status == 1)
            return 1;

          // Go to the next endpoint in this profile.
          invocation->endpoint (invocation->endpoint()->next());
        }
    }

  return 0;
}