Revert "Minor modernization of DynamicAny code"
[ACE_TAO.git] / TAO / tao / Leader_Follower.inl
blob104bd0a5fa032c1355f4d398963af258be9cc158
1 // -*- C++ -*-
2 // ****************************************************************
4 #include "tao/ORB_Core_TSS_Resources.h"
5 #include "tao/ORB_Core.h"
7 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
9 ACE_INLINE
10 TAO_Leader_Follower::TAO_Leader_Follower (TAO_ORB_Core* orb_core,
11                                           TAO_New_Leader_Generator *new_leader_generator)
12   : orb_core_ (orb_core),
13     reverse_lock_ (lock_),
14     leaders_ (0),
15     clients_ (0),
16     reactor_ (0),
17     avoid_client_leader_ (false),
18     client_thread_is_leader_ (0),
19     event_loop_threads_waiting_ (0),
20     event_loop_threads_condition_ (lock_),
21     new_leader_generator_ (new_leader_generator)
25 ACE_INLINE TAO_ORB_Core_TSS_Resources *
26 TAO_Leader_Follower::get_tss_resources () const
28   return this->orb_core_->get_tss_resources ();
31 ACE_INLINE void
32 TAO_Leader_Follower::set_avoid_client_leader ()
34   this->avoid_client_leader_ = true;
37 ACE_INLINE bool
38 TAO_Leader_Follower::follower_available () const
40   return !this->follower_set_.is_empty ();
43 ACE_INLINE bool
44 TAO_Leader_Follower::no_leaders_available ()
46   if (this->new_leader_generator_)
47     return this->new_leader_generator_->no_leaders_available ();
48   return false;
51 ACE_INLINE int
52 TAO_Leader_Follower::elect_new_leader ()
54   if (this->leaders_ == 0)
55     {
56       if (this->event_loop_threads_waiting_)
57         {
58           return this->event_loop_threads_condition_.broadcast ();
59         }
60       else if (this->follower_available ())
61         {
62           return this->elect_new_leader_i ();
63         }
64       else
65         {
66           this->no_leaders_available ();
67         }
68     }
69   return 0;
72 ACE_INLINE int
73 TAO_Leader_Follower::set_event_loop_thread (ACE_Time_Value *max_wait_time)
75   TAO_ORB_Core_TSS_Resources *tss = this->get_tss_resources ();
77   // Make sure that there is no other client thread run the show.  If
78   // we are the client thread running the show, then it is ok.
79   if (this->client_thread_is_leader_ &&
80       tss->client_leader_thread_ == 0)
81     {
82       int const result =
83         this->wait_for_client_leader_to_complete (max_wait_time);
85       if (result != 0)
86         return result;
87     }
89   // If <event_loop_thread_> == 0 and <client_leader_thread_> == 0, we
90   // are running the event loop for the first time.  Therefore,
91   // increment the leaders.  Otherwise, simply increment
92   // <event_loop_thread_> since either (a) if <event_loop_thread_> !=
93   // 0 this is a nested call to the event loop, or (b)
94   // <client_leader_thread_> != 0 this is a call to the event loop
95   // while we are a client leader.
96   if (tss->event_loop_thread_ == 0 &&
97       tss->client_leader_thread_ == 0)
98     ++this->leaders_;
100   ++tss->event_loop_thread_;
102   return 0;
105 ACE_INLINE void
106 TAO_Leader_Follower::reset_event_loop_thread_i (TAO_ORB_Core_TSS_Resources *tss)
108   // Always decrement <event_loop_thread_>. If <event_loop_thread_>
109   // reaches 0 and we are not a client leader, we are done with our
110   // duties of running the event loop. Therefore, decrement the
111   // leaders.  Otherwise, we just got done with a nested call to the
112   // event loop or a call to the event loop when we were the client
113   // leader.
114   --tss->event_loop_thread_;
116   if (tss->event_loop_thread_ == 0 &&
117       tss->client_leader_thread_ == 0)
118     --this->leaders_;
121 ACE_INLINE void
122 TAO_Leader_Follower::reset_event_loop_thread ()
124   TAO_ORB_Core_TSS_Resources *tss = this->get_tss_resources ();
125   if (tss->event_loop_thread_ > 0)
126     this->reset_event_loop_thread_i (tss);
129 ACE_INLINE TAO_SYNCH_MUTEX &
130 TAO_Leader_Follower::lock ()
132   return this->lock_;
135 ACE_INLINE void
136 TAO_Leader_Follower::set_upcall_thread ()
138   TAO_ORB_Core_TSS_Resources *tss = this->get_tss_resources ();
140   if (tss->event_loop_thread_ > 0)
141     {
142       ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->lock ());
143       this->reset_event_loop_thread_i (tss);
145       this->elect_new_leader ();
146     }
147   else if (tss->client_leader_thread_ == 1)
148     { // We are client leader thread going to handle upcall.
149       // When we're only leading one level (which should
150       // now always be the case since we implement leadership
151       // abdication here) we can now give up leadership to allow a
152       // waiting event thread to take over leaderpship
153       ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->lock ());
154       this->reset_client_leader_thread ();
156       this->elect_new_leader ();
157     }
160 ACE_INLINE bool
161 TAO_Leader_Follower::leader_available () const
163   return this->leaders_ != 0;
166 ACE_INLINE void
167 TAO_Leader_Follower::set_client_leader_thread ()
169   TAO_ORB_Core_TSS_Resources *tss = this->get_tss_resources ();
170   ++this->leaders_;
171   ++this->client_thread_is_leader_;
172   ++tss->client_leader_thread_;
175 ACE_INLINE void
176 TAO_Leader_Follower::reset_client_leader_thread ()
178   TAO_ORB_Core_TSS_Resources *tss = this->get_tss_resources ();
179   // We may be called twice when we gave up leadership from
180   // set_upcall_thread () if so tss->client_leader_thread_ may
181   // already have been decremented to 0
182   if (tss->client_leader_thread_ > 0)
183   {
184     --tss->client_leader_thread_;
185     --this->leaders_;
186     --this->client_thread_is_leader_;
187   }
190 ACE_INLINE bool
191 TAO_Leader_Follower::is_client_leader_thread () const
193   TAO_ORB_Core_TSS_Resources *tss = this->get_tss_resources ();
194   return tss->client_leader_thread_ != 0;
197 ACE_INLINE void
198 TAO_Leader_Follower::add_follower (TAO_LF_Follower *follower)
200   this->follower_set_.push_back (follower);
203 ACE_INLINE void
204 TAO_Leader_Follower::remove_follower (TAO_LF_Follower *follower)
206   this->follower_set_.remove (follower);
209 ACE_INLINE ACE_Reverse_Lock<TAO_SYNCH_MUTEX> &
210 TAO_Leader_Follower::reverse_lock ()
212   return this->reverse_lock_;
215 ACE_INLINE bool
216 TAO_Leader_Follower::has_clients () const
218   return this->clients_;
221 ACE_INLINE void
222 TAO_Leader_Follower::set_new_leader_generator(TAO_New_Leader_Generator *new_leader_generator)
224   this->new_leader_generator_ = new_leader_generator;
227 // ****************************************************************
229 ACE_INLINE
230 TAO_LF_Client_Thread_Helper::TAO_LF_Client_Thread_Helper (TAO_Leader_Follower &leader_follower)
231   : leader_follower_ (leader_follower)
233   this->leader_follower_.set_client_thread ();
236 ACE_INLINE
237 TAO_LF_Client_Thread_Helper::~TAO_LF_Client_Thread_Helper ()
239   this->leader_follower_.reset_client_thread ();
242 ACE_INLINE
243 TAO_LF_Client_Leader_Thread_Helper::TAO_LF_Client_Leader_Thread_Helper (TAO_Leader_Follower &leader_follower)
244   : leader_follower_ (leader_follower)
246   this->leader_follower_.set_client_leader_thread ();
249 ACE_INLINE
250 TAO_LF_Client_Leader_Thread_Helper::~TAO_LF_Client_Leader_Thread_Helper ()
252   this->leader_follower_.reset_client_leader_thread ();
255 TAO_END_VERSIONED_NAMESPACE_DECL