summaryrefslogtreecommitdiff
path: root/protocols/ace/RMCast/RMCast_Membership.cpp
blob: 6ee2690a41fd86e1c4e936e9ffe312b8e95ebda9 (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
//
// $Id$
//

#include "RMCast_Membership.h"
#include "RMCast_Proxy.h"

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

ACE_RCSID(ace, RMCast_Membership, "$Id$")

ACE_RMCast_Membership::~ACE_RMCast_Membership (void)
{
}

int
ACE_RMCast_Membership::ack (ACE_RMCast::Ack &ack)
{
  //  ACE_DEBUG ((LM_DEBUG, "ACE_RMCast_Membership::ack\n"));
  Proxy_Iterator end = this->proxies_.end ();
  Proxy_Iterator i = this->proxies_.begin ();
  if (i == end)
    return 0;

  // ACE_DEBUG ((LM_DEBUG, "ACE_RMCast_Membership::ack[2]\n"));
  ACE_RMCast::Ack next_ack;
  {
    ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1);
    if (ack.highest_in_sequence < this->highest_in_sequence_)
      {
        // @@ This violates an invariant of the class, shouldn't
        // happen...
        // ACE_DEBUG ((LM_DEBUG, "ACE_RMCast_Membership::ack[3]\n"));
        return -1;
      }
    else if (ack.highest_in_sequence == this->highest_in_sequence_)
      {
        // Nothing new, just continue....
        // ACE_DEBUG ((LM_DEBUG, "ACE_RMCast_Membership::ack[4]\n"));
        return 0;
      }
    // Possible update, re-evaluate the story...

    ACE_UINT32 highest_in_sequence = (*i)->highest_in_sequence ();
    ACE_UINT32 highest_received = (*i)->highest_received ();
    ++i;

    for (; i != end; ++i)
      {
        ACE_UINT32 s = (*i)->highest_in_sequence ();
        if (s < highest_in_sequence)
          highest_in_sequence = s;
        ACE_UINT32 r = (*i)->highest_received ();
        if (r > highest_received)
          highest_received = r;
      }
#if 0
    if (this->highest_in_sequence_ >= highest_in_sequence
        || this->highest_received_ >= highest_received)
      {
        // No change....
        // ACE_DEBUG ((LM_DEBUG, "ACE_RMCast_Membership::ack[5]\n"));
        return 0;
      }
#endif /* 0 */
    this->highest_in_sequence_ = highest_in_sequence;
    this->highest_received_ = highest_received;
    if (this->next () == 0)
      return 0;
    next_ack.source = ack.source;
    next_ack.highest_in_sequence = this->highest_in_sequence_;
    next_ack.highest_received = this->highest_received_;
  }
  // @@ This looks like a race condition, next() is checked inside the
  // lock and used outside, but it is not: the application is only
  // supposed to change next() at construction time.
  return this->next ()->ack (next_ack);
}

int
ACE_RMCast_Membership::join (ACE_RMCast::Join &join)
{
  if (join.source == 0)
    return 0;

  {
    ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1);
    if (this->proxies_.insert (join.source) == -1)
      return -1;
  }

  return this->ACE_RMCast_Module::join (join);
}

int
ACE_RMCast_Membership::leave (ACE_RMCast::Leave &leave)
{
  if (leave.source == 0)
    return 0;

  {
    ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->mutex_, -1);
    (void) this->proxies_.remove (leave.source);
  }

  return this->ACE_RMCast_Module::leave (leave);
}

#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)

template class ACE_Unbounded_Set<ACE_RMCast_Proxy*>;
template class ACE_Unbounded_Set_Iterator<ACE_RMCast_Proxy*>;
template class ACE_Node<ACE_RMCast_Proxy*>;

#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */