#include <Leader_Follower.h>
Public Member Functions | |
TAO_Leader_Follower (TAO_ORB_Core *orb_core, TAO_New_Leader_Generator *new_leader_generator=0) | |
Constructor. | |
~TAO_Leader_Follower (void) | |
Destructor. | |
int | set_event_loop_thread (ACE_Time_Value *max_wait_time) |
void | reset_event_loop_thread (void) |
void | set_upcall_thread (void) |
int | leader_available (void) const |
Is there any thread running as a leader? | |
void | set_client_thread (void) |
A server thread is making a request. | |
void | reset_client_thread (void) |
A server thread has finished is making a request. | |
int | wait_for_event (TAO_LF_Event *event, TAO_Transport *transport, ACE_Time_Value *max_wait_time) |
Wait on the Leader/Followers loop until one event happens. | |
void | set_client_leader_thread (void) |
void | reset_client_leader_thread (void) |
void | set_client_leader_thread (ACE_thread_t thread_ID) |
int | is_client_leader_thread (void) const |
checks if we are a leader thread | |
int | elect_new_leader (void) |
TAO_SYNCH_MUTEX & | lock (void) |
Get a reference to the underlying mutex. | |
ACE_Reverse_Lock < TAO_SYNCH_MUTEX > & | reverse_lock (void) |
int | has_clients (void) const |
Check if there are any client threads running. | |
ACE_Reactor * | reactor (void) |
Accesor to the reactor. | |
void | no_leaders_available (void) |
Called when we are out of leaders. | |
void | set_new_leader_generator (TAO_New_Leader_Generator *new_leader_generator) |
Set the new leader generator. | |
Follower creation/destructions | |
The Leader/Followers set acts as a factory for the Follower objects. Followers are used to represent a thread blocked waiting in the Follower set. The Leader/Followers abstraction keeps a list of the waiting followers, so it can wake up one when the leader thread stops handling events. For performance reasons the Leader/Followers set uses a pool (or free-list) to keep Follower objects unattached to any thread. It could be tempting to use TSS to keep such followers, after all a thread can only need one such Follower object, however, that does not work with multiple Leader/Followers sets, consult this bug report for more details: | |
TAO_LF_Follower * | allocate_follower (void) |
Allocate a new follower to the caller. | |
void | release_follower (TAO_LF_Follower *) |
The caller has finished using a follower. | |
Private Types | |
typedef ACE_Intrusive_List < TAO_LF_Follower > | Follower_Set |
Implement the Leader/Followers set using an intrusive list. | |
Private Member Functions | |
TAO_ORB_Core_TSS_Resources * | get_tss_resources (void) const |
Shortcut to obtain the TSS resources of the orb core. | |
int | wait_for_client_leader_to_complete (ACE_Time_Value *max_wait_time) |
Wait for the client leader to complete. | |
void | reset_event_loop_thread_i (TAO_ORB_Core_TSS_Resources *tss) |
Private Attributes | |
TAO_ORB_Core * | orb_core_ |
The orb core. | |
TAO_SYNCH_MUTEX | lock_ |
To synchronize access to the members. | |
ACE_Reverse_Lock< TAO_SYNCH_MUTEX > | reverse_lock_ |
Do protect the access to the following three members. | |
Follower_Set | follower_set_ |
Follower_Set | follower_free_list_ |
Use a free list to allocate and release Follower objects. | |
int | leaders_ |
int | clients_ |
ACE_Reactor * | reactor_ |
The reactor. | |
int | client_thread_is_leader_ |
Is a client thread the current leader? | |
int | event_loop_threads_waiting_ |
Are server threads waiting for the client leader to complete? | |
TAO_SYNCH_CONDITION | event_loop_threads_condition_ |
TAO_New_Leader_Generator * | new_leader_generator_ |
Follower Set Operations | |
| |
void | add_follower (TAO_LF_Follower *follower) |
Add a new follower to the set. | |
void | remove_follower (TAO_LF_Follower *follower) |
Removes a follower from the leader-follower set. | |
int | follower_available (void) const |
Checks if there are any followers available. | |
int | elect_new_leader_i (void) |
Definition at line 49 of file Leader_Follower.h.
typedef ACE_Intrusive_List<TAO_LF_Follower> TAO_Leader_Follower::Follower_Set [private] |
Implement the Leader/Followers set using an intrusive list.
Definition at line 230 of file Leader_Follower.h.
TAO_Leader_Follower::TAO_Leader_Follower | ( | TAO_ORB_Core * | orb_core, | |
TAO_New_Leader_Generator * | new_leader_generator = 0 | |||
) |
Constructor.
Definition at line 13 of file Leader_Follower.inl.
: orb_core_ (orb_core), reverse_lock_ (lock_), leaders_ (0), clients_ (0), reactor_ (0), client_thread_is_leader_ (0), event_loop_threads_waiting_ (0), event_loop_threads_condition_ (lock_), new_leader_generator_ (new_leader_generator) { }
TAO_Leader_Follower::~TAO_Leader_Follower | ( | void | ) |
Destructor.
Definition at line 27 of file Leader_Follower.cpp.
{ while (!this->follower_free_list_.empty ()) { TAO_LF_Follower *follower = this->follower_free_list_.pop_front (); delete follower; } // Hand the reactor back to the resource factory. // use GUI reactor factory if available if ( this->orb_core_->gui_resource_factory () ) this->orb_core_->gui_resource_factory ()->reclaim_reactor (this->reactor_); else this->orb_core_->resource_factory ()->reclaim_reactor (this->reactor_); this->reactor_ = 0; }
void TAO_Leader_Follower::add_follower | ( | TAO_LF_Follower * | follower | ) |
Add a new follower to the set.
Definition at line 176 of file Leader_Follower.inl.
{ this->follower_set_.push_back (follower); }
TAO_LF_Follower * TAO_Leader_Follower::allocate_follower | ( | void | ) |
Allocate a new follower to the caller.
Definition at line 45 of file Leader_Follower.cpp.
{ if (!this->follower_free_list_.empty ()) return this->follower_free_list_.pop_front (); TAO_LF_Follower* ptr = 0; ACE_NEW_RETURN (ptr, TAO_LF_Follower (*this), 0); return ptr; }
int TAO_Leader_Follower::elect_new_leader | ( | void | ) |
A leader thread is relinquishing its role, unless there are more leader threads running pick up a follower (if there is any) to play the leader role.
Definition at line 47 of file Leader_Follower.inl.
{ if (this->leaders_ == 0) { if (this->event_loop_threads_waiting_) { return this->event_loop_threads_condition_.broadcast (); } else if (this->follower_available ()) { return this->elect_new_leader_i (); } else { this->no_leaders_available (); } } return 0; }
int TAO_Leader_Follower::elect_new_leader_i | ( | void | ) | [private] |
Remote a follower from the Followers set and promote it to the leader role. This is a helper routine for elect_new_leader(), after verifying that all the pre-conditions are satisfied the Follower set is changed and the promoted Follower is signaled.
Definition at line 64 of file Leader_Follower.cpp.
{ TAO_LF_Follower* const follower = this->follower_set_.head (); #if defined (TAO_DEBUG_LEADER_FOLLOWER) ACE_DEBUG ((LM_DEBUG, "TAO (%P|%t) LF::elect_new_leader_i - " "follower is %x\n", follower)); #endif /* TAO_DEBUG_LEADER_FOLLOWER */ return follower->signal (); }
int TAO_Leader_Follower::follower_available | ( | void | ) | const |
Checks if there are any followers available.
Definition at line 34 of file Leader_Follower.inl.
{ return !this->follower_set_.empty (); }
TAO_ORB_Core_TSS_Resources * TAO_Leader_Follower::get_tss_resources | ( | void | ) | const [private] |
Shortcut to obtain the TSS resources of the orb core.
Definition at line 28 of file Leader_Follower.inl.
{ return this->orb_core_->get_tss_resources (); }
int TAO_Leader_Follower::has_clients | ( | void | ) | const |
Check if there are any client threads running.
Definition at line 194 of file Leader_Follower.inl.
{ return this->clients_; }
int TAO_Leader_Follower::is_client_leader_thread | ( | void | ) | const |
checks if we are a leader thread
Definition at line 169 of file Leader_Follower.inl.
{ TAO_ORB_Core_TSS_Resources *tss = this->get_tss_resources (); return tss->client_leader_thread_ != 0; }
int TAO_Leader_Follower::leader_available | ( | void | ) | const |
Is there any thread running as a leader?
Definition at line 145 of file Leader_Follower.inl.
{ return this->leaders_ != 0; }
TAO_SYNCH_MUTEX & TAO_Leader_Follower::lock | ( | void | ) |
Get a reference to the underlying mutex.
Definition at line 125 of file Leader_Follower.inl.
{ return this->lock_; }
void TAO_Leader_Follower::no_leaders_available | ( | void | ) |
Called when we are out of leaders.
Definition at line 40 of file Leader_Follower.inl.
{ if (this->new_leader_generator_) this->new_leader_generator_->no_leaders_available (); }
ACE_Reactor * TAO_Leader_Follower::reactor | ( | void | ) |
Accesor to the reactor.
Definition at line 126 of file Leader_Follower.cpp.
{ if (this->reactor_ == 0) { ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->lock (), 0); if (this->reactor_ == 0) { // use GUI reactor factory if available if ( this->orb_core_->gui_resource_factory () ) this->reactor_ = this->orb_core_->gui_resource_factory ()->get_reactor (); else this->reactor_ = this->orb_core_->resource_factory ()->get_reactor (); } } return this->reactor_; }
void TAO_Leader_Follower::release_follower | ( | TAO_LF_Follower * | follower | ) |
The caller has finished using a follower.
Definition at line 58 of file Leader_Follower.cpp.
{ this->follower_free_list_.push_front (follower); }
void TAO_Leader_Follower::remove_follower | ( | TAO_LF_Follower * | follower | ) |
Removes a follower from the leader-follower set.
Definition at line 182 of file Leader_Follower.inl.
{ this->follower_set_.remove (follower); }
void TAO_Leader_Follower::reset_client_leader_thread | ( | void | ) |
The current thread is no longer the leader thread in the client side leader-follower set.
Definition at line 160 of file Leader_Follower.inl.
{ TAO_ORB_Core_TSS_Resources *tss = this->get_tss_resources (); --tss->client_leader_thread_; --this->leaders_; --this->client_thread_is_leader_; }
void TAO_Leader_Follower::reset_client_thread | ( | void | ) |
A server thread has finished is making a request.
Definition at line 170 of file Leader_Follower.cpp.
{ // If we were a leader thread or an event loop thread, take back // leadership. TAO_ORB_Core_TSS_Resources *tss = this->get_tss_resources (); if (tss->event_loop_thread_ || tss->client_leader_thread_) { ++this->leaders_; } --this->clients_; if (this->clients_ == 0 && this->orb_core_->has_shutdown ()) { // The ORB has shutdown and we are the last client thread, we // must stop the reactor to ensure that any server threads go // away. this->orb_core_->reactor ()->end_reactor_event_loop (); } }
void TAO_Leader_Follower::reset_event_loop_thread | ( | void | ) |
The current thread is not a server thread anymore, reset any flags and counters.
Definition at line 117 of file Leader_Follower.inl.
{ TAO_ORB_Core_TSS_Resources *tss = this->get_tss_resources (); if (tss->event_loop_thread_ > 0) this->reset_event_loop_thread_i (tss); }
void TAO_Leader_Follower::reset_event_loop_thread_i | ( | TAO_ORB_Core_TSS_Resources * | tss | ) | [private] |
Implement the reset_event_loop_thread() method, once the TSS resources have been acquired. Also used in the set_upcall_thread.
Definition at line 101 of file Leader_Follower.inl.
{ // Always decrement <event_loop_thread_>. If <event_loop_thread_> // reaches 0 and we are not a client leader, we are done with our // duties of running the event loop. Therefore, decrement the // leaders. Otherwise, we just got done with a nested call to the // event loop or a call to the event loop when we were the client // leader. --tss->event_loop_thread_; if (tss->event_loop_thread_ == 0 && tss->client_leader_thread_ == 0) --this->leaders_; }
ACE_Reverse_Lock< TAO_SYNCH_MUTEX > & TAO_Leader_Follower::reverse_lock | ( | void | ) |
Provide a pre-initialized reverse lock for the Leader/Followers set. The Leader/Followers set mutex must be release during some long running operations. This helper class simplifies the process of releasing and reacquiring said mutex.
Definition at line 188 of file Leader_Follower.inl.
{ return this->reverse_lock_; }
void TAO_Leader_Follower::set_client_leader_thread | ( | void | ) |
The current thread has become the leader thread in the client side leader-follower set.
Definition at line 151 of file Leader_Follower.inl.
{ TAO_ORB_Core_TSS_Resources *tss = this->get_tss_resources (); ++this->leaders_; ++this->client_thread_is_leader_; ++tss->client_leader_thread_; }
void TAO_Leader_Follower::set_client_leader_thread | ( | ACE_thread_t | thread_ID | ) |
sets the thread ID of the leader thread in the leader-follower model
void TAO_Leader_Follower::set_client_thread | ( | void | ) |
A server thread is making a request.
Definition at line 146 of file Leader_Follower.cpp.
{ // If we were a leader thread or an event loop thread, give up // leadership. TAO_ORB_Core_TSS_Resources *tss = this->get_tss_resources (); if (tss->event_loop_thread_ || tss->client_leader_thread_) { --this->leaders_; } if (this->clients_ == 0 && this->orb_core_->has_shutdown () && !this->orb_core_->resource_factory ()->drop_replies_during_shutdown ()) { // The ORB has shutdown and we are the first client after // that. This means that the reactor is disabled, we must // re-enable it if we want to receive any replys... this->orb_core_->reactor ()->reset_reactor_event_loop (); } ++this->clients_; }
int TAO_Leader_Follower::set_event_loop_thread | ( | ACE_Time_Value * | max_wait_time | ) |
The current thread has become a server thread (i.e. called ORB::run), update any flags and counters.
Definition at line 68 of file Leader_Follower.inl.
{ TAO_ORB_Core_TSS_Resources *tss = this->get_tss_resources (); // Make sure that there is no other client thread run the show. If // we are the client thread running the show, then it is ok. if (this->client_thread_is_leader_ && tss->client_leader_thread_ == 0) { int result = this->wait_for_client_leader_to_complete (max_wait_time); if (result != 0) return result; } // If <event_loop_thread_> == 0 and <client_leader_thread_> == 0, we // are running the event loop for the first time. Therefore, // increment the leaders. Otherwise, simply increment // <event_loop_thread_> since either (a) if <event_loop_thread_> != // 0 this is a nested call to the event loop, or (b) // <client_leader_thread_> != 0 this is a call to the event loop // while we are a client leader. if (tss->event_loop_thread_ == 0 && tss->client_leader_thread_ == 0) ++this->leaders_; ++tss->event_loop_thread_; return 0; }
void TAO_Leader_Follower::set_new_leader_generator | ( | TAO_New_Leader_Generator * | new_leader_generator | ) |
Set the new leader generator.
Definition at line 200 of file Leader_Follower.inl.
{ this->new_leader_generator_ = new_leader_generator; }
void TAO_Leader_Follower::set_upcall_thread | ( | void | ) |
This thread is going to perform an upcall, it will no longer be an event loop thread.
Definition at line 131 of file Leader_Follower.inl.
{ TAO_ORB_Core_TSS_Resources *tss = this->get_tss_resources (); if (tss->event_loop_thread_ > 0) { ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->lock ()); this->reset_event_loop_thread_i (tss); this->elect_new_leader (); } }
int TAO_Leader_Follower::wait_for_client_leader_to_complete | ( | ACE_Time_Value * | max_wait_time | ) | [private] |
Wait for the client leader to complete.
Definition at line 79 of file Leader_Follower.cpp.
{ int result = 0; ACE_Countdown_Time countdown (max_wait_time); // Note that we are waiting. ++this->event_loop_threads_waiting_; while (this->client_thread_is_leader_ && result != -1) { if (max_wait_time == 0) { if (this->event_loop_threads_condition_.wait () == -1) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("TAO (%P|%t): TAO_Leader_Follower::") ACE_TEXT ("wait_for_client_leader_to_complete - ") ACE_TEXT ("Condition variable wait failed\n"))); result = -1; } } else { countdown.update (); ACE_Time_Value tv = ACE_OS::gettimeofday (); tv += *max_wait_time; if (this->event_loop_threads_condition_.wait (&tv) == -1) { if (errno != ETIME) ACE_ERROR ((LM_ERROR, ACE_TEXT ("TAO (%P|%t): TAO_Leader_Follower::") ACE_TEXT ("wait_for_client_leader_to_complete - ") ACE_TEXT ("Condition variable wait failed\n"))); result = -1; } } } // Reset waiting state. --this->event_loop_threads_waiting_; return result; }
int TAO_Leader_Follower::wait_for_event | ( | TAO_LF_Event * | event, | |
TAO_Transport * | transport, | |||
ACE_Time_Value * | max_wait_time | |||
) |
Wait on the Leader/Followers loop until one event happens.
event | The event we wait for, the loop iterates until the event is sucessful, or it fails due to timeout, and error or a connection closed. | |
transport | The transport attached to the event | |
max_wait_time | Limit the time spent on the loop |
There should be no reason to reset the value of result here. If there was an error in handle_events () that the leader saw, I (Bala) beleave it should be propogated to the clients. result = 0;
Definition at line 193 of file Leader_Follower.cpp.
{ // Obtain the lock. ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->lock (), -1); ACE_Countdown_Time countdown (max_wait_time); // Optmize the first iteration [no access to errno] int result = 1; // For some cases the transport may dissappear like when waiting for // connection to be initiated or closed. So cache the id. // @@ NOTE: This is not completely safe either. We will be fine for // cases that dont access the id ie. when debug level is off but // with debugging level on we are on a sticky wicket. Hopefully none // of our users should run TAO with debugging enabled like they did // in PathFinder size_t t_id = 0; if (TAO_debug_level && transport != 0) { t_id = transport->id (); } { // Calls this->set_client_thread () on construction and // this->reset_client_thread () on destruction. TAO_LF_Client_Thread_Helper client_thread_helper (*this); ACE_UNUSED_ARG (client_thread_helper); // Check if there is a leader. Note that it cannot be us since we // gave up our leadership when we became a client. if (this->leader_available ()) { // = Wait as a follower. // Grab a follower: TAO_LF_Follower_Auto_Ptr follower (*this); if (follower.get () == 0) return -1; if (TAO_debug_level >= 5) ACE_DEBUG ((LM_DEBUG, "TAO (%P|%t) - Leader_Follower[%d]::wait_for_event," " (follower), cond <%x>\n", t_id, follower.get ())); // Bound the follower and the LF_Event, this is important to // get a signal when the event terminates TAO_LF_Event_Binder event_binder (event, follower.get ()); while (event->keep_waiting () && this->leader_available ()) { // Add ourselves to the list, do it everytime we wake up // from the CV loop. Because: // // - The leader thread could have elected us as the new // leader. // - Before we can assume the role another thread becomes // the leader // - But our condition variable could have been removed // already, if we don't add it again we will never wake // up. // // Notice that we can have spurious wake ups, in that case // adding the leader results in an error, that must be // ignored. // You may be thinking of not removing the condition // variable in the code that sends the signal, but // removing it here, that does not work either, in that // case the condition variable may be used twice: // // - Wake up because its reply arrived // - Wake up because it must become the leader // // but only the first one has any effect, so the leader is // lost. // TAO_LF_Follower_Auto_Adder auto_adder (*this, follower); if (max_wait_time == 0) { if (follower->wait (max_wait_time) == -1) { if (TAO_debug_level >= 5) ACE_DEBUG ((LM_DEBUG, "TAO (%P|%t) - Leader_Follower[%d]::wait_for_event, " " (follower) [no timer, cond failed]\n", t_id)); // @@ Michael: What is our error handling in this case? // We could be elected as leader and // no leader would come in? return -1; } } else { countdown.update (); ACE_Time_Value tv = ACE_OS::gettimeofday (); tv += *max_wait_time; if (follower->wait (&tv) == -1) { if (TAO_debug_level >= 5) ACE_DEBUG ((LM_DEBUG, "TAO (%P|%t) - Leader_Follower[%d]::wait, " "(follower) [has timer, follower failed]\n", t_id )); // If we have timedout set the state in the // LF_Event. We call the non-locking, // no-signalling method on LF_Event. if (errno == ETIME) // We have timedout event->set_state (TAO_LF_Event::LFS_TIMEOUT); if (!event->successful ()) { // Remove follower can fail because either // 1) the condition was satisfied (i.e. reply // received or queue drained), or // 2) somebody elected us as leader, or // 3) the connection got closed. // // Therefore: // If remove_follower fails and the condition // was not satisfied, we know that we got // elected as a leader. // But we got a timeout, so we cannot become // the leader, therefore, we have to select a // new leader. // if (this->elect_new_leader () == -1 && TAO_debug_level > 0) { ACE_ERROR ((LM_ERROR, "TAO (%P|%t) - Leader_Follower[%d]::wait_for_event, " "elect_new_leader failed\n", t_id )); } } return -1; } } } countdown.update (); // @@ Michael: This is an old comment why we do not want to // remove the follower here. // We should not remove the follower here, we *must* remove it when // we signal it so the same condition is not signalled for // both wake up as a follower and as the next leader. if (TAO_debug_level >= 5) ACE_DEBUG ((LM_DEBUG, "TAO (%P|%t) - Leader_Follower[%d]::wait_for_event," " done (follower), successful %d\n", t_id, event->successful ())); // Now somebody woke us up to become a leader or to handle our // input. We are already removed from the follower queue. if (event->successful ()) return 0; if (event->error_detected ()) return -1; // FALLTHROUGH // We only get here if we woke up but the reply is not // complete yet, time to assume the leader role.... // i.e. ACE_ASSERT (event->successful () == 0); } // = Leader Code. // The only way to reach this point is if we must become the // leader, because there is no leader or we have to update to a // leader or we are doing nested upcalls in this case we do // increase the refcount on the leader in TAO_ORB_Core. // Calls this->set_client_leader_thread () on // construction and this->reset_client_leader_thread () // on destruction. Note that this may increase the refcount of // the leader. TAO_LF_Client_Leader_Thread_Helper client_leader_thread_helper (*this); ACE_UNUSED_ARG (client_leader_thread_helper); { ACE_GUARD_RETURN (ACE_Reverse_Lock<TAO_SYNCH_MUTEX>, rev_mon, this->reverse_lock (), -1); // Become owner of the reactor. ACE_Reactor *reactor = this->reactor_; reactor->owner (ACE_Thread::self ()); // Run the reactor event loop. if (TAO_debug_level >= 5) ACE_DEBUG ((LM_DEBUG, "TAO (%P|%t) - Leader_Follower[%d]::wait_for_event," " (leader) enter reactor event loop\n", t_id)); // If we got our event, no need to run the event loop any // further. while (event->keep_waiting ()) { // Run the event loop. result = reactor->handle_events (max_wait_time); // Did we timeout? If so, stop running the loop. if (result == 0 && max_wait_time != 0 && *max_wait_time == ACE_Time_Value::zero) break; // Other errors? If so, stop running the loop. if (result == -1) break; // Otherwise, keep going... } if (TAO_debug_level >= 5) ACE_DEBUG ((LM_DEBUG, "TAO (%P|%t) - Leader_Follower[%d]::wait_for_event," " (leader) exit reactor event loop\n", t_id)); } } // // End artificial scope for auto_ptr like helpers calling: // this->reset_client_thread () and (maybe) // this->reset_client_leader_thread (). // // Wake up the next leader, we cannot do that in handle_input, // because the woken up thread would try to get into handle_events, // which is at the time in handle_input still occupied. But do it // before checking the error in <result>, even if there is an error // in our input we should continue running the loop in another // thread. if (this->elect_new_leader () == -1) ACE_ERROR_RETURN ((LM_ERROR, "TAO (%P|%t) - Leader_Follower[%d]::wait_for_event," " failed to elect new leader\n", t_id), -1); if (result == -1 && !this->reactor_->reactor_event_loop_done ()) ACE_ERROR_RETURN ((LM_ERROR, "TAO (%P|%t) - Leader_Follower[%d]::wait_for_event," " handle_events failed\n", t_id), -1); // Return an error if there was a problem receiving the reply... if (max_wait_time != 0) { if (!event->successful () && *max_wait_time == ACE_Time_Value::zero) { result = -1; errno = ETIME; } else if (event->error_detected ()) { // If the time did not expire yet, but we get a failure, // e.g. the connections closed, we should still return an error. result = -1; } } else { /** * There should be no reason to reset the value of result * here. If there was an error in handle_events () that the * leader saw, I (Bala) beleave it should be propogated to the * clients. * result = 0; */ if (event->error_detected ()) { result = -1; } } return result; }
int TAO_Leader_Follower::client_thread_is_leader_ [private] |
Is a client thread the current leader?
Definition at line 252 of file Leader_Follower.h.
int TAO_Leader_Follower::clients_ [private] |
Count the number of active clients, this is useful to know when to deactivate the reactor
Definition at line 246 of file Leader_Follower.h.
TAO_SYNCH_CONDITION TAO_Leader_Follower::event_loop_threads_condition_ [private] |
Condition variable for server threads waiting for the client leader to complete.
Definition at line 259 of file Leader_Follower.h.
int TAO_Leader_Follower::event_loop_threads_waiting_ [private] |
Are server threads waiting for the client leader to complete?
Definition at line 255 of file Leader_Follower.h.
Use a free list to allocate and release Follower objects.
Definition at line 234 of file Leader_Follower.h.
Definition at line 231 of file Leader_Follower.h.
int TAO_Leader_Follower::leaders_ [private] |
Count the number of active leaders. There could be many leaders in the thread pool (i.e. calling ORB::run), and the same leader could show up multiple times as it receives nested upcalls and sends more requests.
Definition at line 242 of file Leader_Follower.h.
TAO_SYNCH_MUTEX TAO_Leader_Follower::lock_ [private] |
To synchronize access to the members.
Definition at line 224 of file Leader_Follower.h.
Leader/Follower class uses this method to notify the system that we are out of leaders.
Definition at line 263 of file Leader_Follower.h.
TAO_ORB_Core* TAO_Leader_Follower::orb_core_ [private] |
The orb core.
Definition at line 221 of file Leader_Follower.h.
ACE_Reactor* TAO_Leader_Follower::reactor_ [private] |
The reactor.
Definition at line 249 of file Leader_Follower.h.
ACE_Reverse_Lock<TAO_SYNCH_MUTEX> TAO_Leader_Follower::reverse_lock_ [private] |
Do protect the access to the following three members.
Definition at line 227 of file Leader_Follower.h.