summaryrefslogtreecommitdiff
path: root/ace
diff options
context:
space:
mode:
authordhinton <dhinton@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2002-02-25 13:44:52 +0000
committerdhinton <dhinton@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2002-02-25 13:44:52 +0000
commit42e6e61137dccbb442d7bb299e679ab62e48e3ca (patch)
tree7879c1277bfd55983f998fb50a8bf721b242ed3c /ace
parent471eef9411a5d6969c2216c46ec5d86bc4b93aab (diff)
downloadATCD-42e6e61137dccbb442d7bb299e679ab62e48e3ca.tar.gz
ChangeLogTag:Mon Feb 25 13:50:43 2002 UTC Don Hinton <dhinton@ieee.org>
Diffstat (limited to 'ace')
-rw-r--r--ace/Select_Reactor_T.cpp27
-rw-r--r--ace/Select_Reactor_T.h12
-rw-r--r--ace/Synch.h13
-rw-r--r--ace/Synch.i11
-rw-r--r--ace/TP_Reactor.cpp10
-rw-r--r--ace/TP_Reactor.h6
-rw-r--r--ace/Token.cpp10
-rw-r--r--ace/Token.h35
-rw-r--r--ace/Token.i12
9 files changed, 112 insertions, 24 deletions
diff --git a/ace/Select_Reactor_T.cpp b/ace/Select_Reactor_T.cpp
index 4f9575dc083..3790c37e474 100644
--- a/ace/Select_Reactor_T.cpp
+++ b/ace/Select_Reactor_T.cpp
@@ -196,17 +196,30 @@ ACE_Select_Reactor_Token_T<ACE_SELECT_REACTOR_MUTEX>::dump (void) const
template <class ACE_SELECT_REACTOR_MUTEX>
ACE_Select_Reactor_Token_T<ACE_SELECT_REACTOR_MUTEX>::ACE_Select_Reactor_Token_T
- (ACE_Select_Reactor_Impl &r)
+ (ACE_Select_Reactor_Impl &r,
+ int s_queue)
: select_reactor_ (&r)
{
ACE_TRACE ("ACE_Select_Reactor_Token_T::ACE_Select_Reactor_Token");
+
+#if defined (ACE_SELECT_REACTOR_HAS_DEADLOCK_DETECTION)
+ ACE_UNUSED_ARG (s_queue);
+#else
+ this->queueing_strategy (s_queue);
+#endif
}
template <class ACE_SELECT_REACTOR_MUTEX>
-ACE_Select_Reactor_Token_T<ACE_SELECT_REACTOR_MUTEX>::ACE_Select_Reactor_Token_T (void)
+ACE_Select_Reactor_Token_T<ACE_SELECT_REACTOR_MUTEX>::ACE_Select_Reactor_Token_T (int s_queue)
: select_reactor_ (0)
{
ACE_TRACE ("ACE_Select_Reactor_Token_T::ACE_Select_Reactor_Token");
+
+#if defined (ACE_SELECT_REACTOR_HAS_DEADLOCK_DETECTION)
+ ACE_UNUSED_ARG (s_queue);
+#else
+ this->queueing_strategy (s_queue);
+#endif
}
template <class ACE_SELECT_REACTOR_MUTEX>
@@ -515,8 +528,9 @@ ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::ACE_Select_Reactor_T
ACE_Timer_Queue *tq,
int disable_notify_pipe,
ACE_Reactor_Notify *notify,
- int mask_signals)
- : token_ (*this),
+ int mask_signals,
+ int s_queue)
+ : token_ (*this, s_queue),
lock_adapter_ (token_),
deactivated_ (0),
mask_signals_ (mask_signals)
@@ -566,8 +580,9 @@ ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::ACE_Select_Reactor_T
ACE_Timer_Queue *tq,
int disable_notify_pipe,
ACE_Reactor_Notify *notify,
- int mask_signals)
- : token_ (*this),
+ int mask_signals,
+ int s_queue)
+ : token_ (*this, s_queue),
lock_adapter_ (token_),
deactivated_ (0),
mask_signals_ (mask_signals)
diff --git a/ace/Select_Reactor_T.h b/ace/Select_Reactor_T.h
index 66db768828e..27c1d2f2910 100644
--- a/ace/Select_Reactor_T.h
+++ b/ace/Select_Reactor_T.h
@@ -70,8 +70,10 @@ template <class ACE_SELECT_REACTOR_MUTEX>
class ACE_Select_Reactor_Token_T : public ACE_SELECT_REACTOR_MUTEX
{
public:
- ACE_Select_Reactor_Token_T (ACE_Select_Reactor_Impl &r);
- ACE_Select_Reactor_Token_T (void);
+
+ ACE_Select_Reactor_Token_T (ACE_Select_Reactor_Impl &r,
+ int s_queue = ACE_SELECT_REACTOR_MUTEX::FIFO);
+ ACE_Select_Reactor_Token_T (int s_queue = ACE_SELECT_REACTOR_MUTEX::FIFO);
virtual ~ACE_Select_Reactor_Token_T (void);
/// Called just before the ACE_Event_Handler goes to sleep.
@@ -122,7 +124,8 @@ public:
ACE_Timer_Queue * = 0,
int disable_notify_pipe = 0,
ACE_Reactor_Notify *notify = 0,
- int mask_signals = 1);
+ int mask_signals = 1,
+ int s_queue = ACE_SELECT_REACTOR_TOKEN::FIFO);
/// Initialize @c ACE_Select_Reactor with size @arg size.
/// If @arg disable_notify_pipe is non-0 then the reactor will
@@ -146,7 +149,8 @@ public:
ACE_Timer_Queue * = 0,
int disable_notify_pipe = 0,
ACE_Reactor_Notify *notify = 0,
- int mask_signals = 1);
+ int mask_signals = 1,
+ int s_queue = ACE_SELECT_REACTOR_TOKEN::FIFO);
/**
* Initialize the @c ACE_Select_Reactor to manage
diff --git a/ace/Synch.h b/ace/Synch.h
index f46053bef2b..c3099776f4d 100644
--- a/ace/Synch.h
+++ b/ace/Synch.h
@@ -687,6 +687,19 @@ public:
class ACE_Export ACE_Noop_Token : public ACE_Null_Mutex
{
public:
+ /// Queueing strategy
+ enum QUEUEING_STRATEGY
+ {
+ FIFO = -1,
+ LIFO = 0
+ };
+
+ /// Get queueing strategy.
+ int queueing_strategy (void);
+
+ /// Set queueing strategy.
+ void queueing_strategy (int queueing_strategy);
+
int renew (int = 0, ACE_Time_Value * =0);
/// Dump the state of an object.
diff --git a/ace/Synch.i b/ace/Synch.i
index 4bb95145df5..6c0e1de93c0 100644
--- a/ace/Synch.i
+++ b/ace/Synch.i
@@ -817,6 +817,17 @@ ACE_Null_Mutex::dump (void) const
}
ACE_INLINE int
+ACE_Noop_Token::queueing_strategy (void)
+{
+ return -1;
+}
+
+ACE_INLINE void
+ACE_Noop_Token::queueing_strategy (int queueing_strategy)
+{
+}
+
+ACE_INLINE int
ACE_Noop_Token::renew (int, ACE_Time_Value *)
{
return 0;
diff --git a/ace/TP_Reactor.cpp b/ace/TP_Reactor.cpp
index e6b0d189f89..2669e47d287 100644
--- a/ace/TP_Reactor.cpp
+++ b/ace/TP_Reactor.cpp
@@ -99,8 +99,9 @@ ACE_TP_Token_Guard::acquire_token (ACE_Time_Value *max_wait_time)
ACE_TP_Reactor::ACE_TP_Reactor (ACE_Sig_Handler *sh,
ACE_Timer_Queue *tq,
- int mask_signals)
- : ACE_Select_Reactor (sh, tq, 0, 0, mask_signals)
+ int mask_signals,
+ int s_queue)
+ : ACE_Select_Reactor (sh, tq, 0, 0, mask_signals, s_queue)
{
ACE_TRACE ("ACE_TP_Reactor::ACE_TP_Reactor");
this->supress_notify_renew (1);
@@ -110,8 +111,9 @@ ACE_TP_Reactor::ACE_TP_Reactor (size_t size,
int rs,
ACE_Sig_Handler *sh,
ACE_Timer_Queue *tq,
- int mask_signals)
- : ACE_Select_Reactor (size, rs, sh, tq, 0, 0, mask_signals)
+ int mask_signals,
+ int s_queue)
+ : ACE_Select_Reactor (size, rs, sh, tq, 0, 0, mask_signals, s_queue)
{
ACE_TRACE ("ACE_TP_Reactor::ACE_TP_Reactor");
this->supress_notify_renew (1);
diff --git a/ace/TP_Reactor.h b/ace/TP_Reactor.h
index e51abd99db9..8c51ceff58b 100644
--- a/ace/TP_Reactor.h
+++ b/ace/TP_Reactor.h
@@ -170,7 +170,8 @@ public:
/// Initialize <ACE_TP_Reactor> with the default size.
ACE_TP_Reactor (ACE_Sig_Handler * = 0,
ACE_Timer_Queue * = 0,
- int mask_signals = 1);
+ int mask_signals = 1,
+ int s_queue = ACE_Select_Reactor_Token::FIFO);
/**
* Initialize the <ACE_TP_Reactor> to manage
@@ -184,7 +185,8 @@ public:
int restart = 0,
ACE_Sig_Handler * = 0,
ACE_Timer_Queue * = 0,
- int mask_signals = 1);
+ int mask_signals = 1,
+ int s_queue = ACE_Select_Reactor_Token::FIFO);
// = Event loop drivers.
diff --git a/ace/Token.cpp b/ace/Token.cpp
index cb2b2d2c618..f15de7d1fe4 100644
--- a/ace/Token.cpp
+++ b/ace/Token.cpp
@@ -165,7 +165,8 @@ ACE_Token::ACE_Token (const ACE_TCHAR *name, void *any)
in_use_ (0),
waiters_ (0),
nesting_level_ (0),
- attributes_ (USYNC_THREAD)
+ attributes_ (USYNC_THREAD),
+ queueing_strategy_ (FIFO)
{
// ACE_TRACE ("ACE_Token::ACE_Token");
}
@@ -231,7 +232,7 @@ ACE_Token::shared_acquire (void (*sleep_hook_func)(void *),
ACE_Token::ACE_Token_Queue_Entry my_entry (this->lock_,
thr_id,
this->attributes_);
- queue->insert_entry (my_entry);
+ queue->insert_entry (my_entry, this->queueing_strategy_);
this->waiters_++;
// Execute appropriate <sleep_hook> callback. (@@ should these
@@ -383,7 +384,10 @@ ACE_Token::renew (int requeue_position,
this->owner_);
this_threads_queue->insert_entry (my_entry,
- requeue_position);
+ // if requeue_position == 0 then we want to go next,
+ // otherwise use the queueing strategy, which might also
+ // happen to be 0.
+ requeue_position == 0 ? 0 : this->queueing_strategy_);
this->waiters_++;
// Remember nesting level...
diff --git a/ace/Token.h b/ace/Token.h
index 8d9cc641059..45bb41826aa 100644
--- a/ace/Token.h
+++ b/ace/Token.h
@@ -34,7 +34,7 @@
* @class ACE_Token
*
* @brief Class that acquires, renews, and releases a synchronization
- * token that is serviced in strict FIFO ordering and that also
+ * token that is serviced in strict FIFO/LIFO ordering and that also
* supports (1) recursion and (2) readers/writer semantics.
*
* This class is a more general-purpose synchronization mechanism
@@ -44,9 +44,9 @@
* <acquire> multiple times, however, it must call <release> an
* equal number of times before the token is actually released.
* Threads that are blocked awaiting the token are serviced in
- * strict FIFO order as other threads release the token (Solaris
+ * strict FIFO/LIFO order as other threads release the token (Solaris
* and Pthread mutexes don't strictly enforce an acquisition
- * order). There are two FIFO lists within the class. Write
+ * order). There are two lists within the class. Write
* acquires always have higher priority over read acquires. Which
* means, if you use both write/read operations, care must be
* taken to avoid starvation on the readers. Notice that the
@@ -62,11 +62,31 @@
class ACE_Export ACE_Token
{
public:
+
+ /**
+ * Available queueing strategies.
+ */
+ enum QUEUEING_STRATEGY
+ {
+ /// FIFO, First In, First Out.
+ FIFO = -1,
+ /// LIFO, Last In, First Out
+ LIFO = 0
+ };
+
// = Initialization and termination.
ACE_Token (const ACE_TCHAR *name = 0, void * = 0);
virtual ~ACE_Token (void);
+ // = Strategies
+
+ /// Retrieve the current queueing strategy.
+ int queueing_strategy (void);
+
+ /// Set the queueing strategy.
+ void queueing_strategy (int queueing_strategy);
+
// = Synchronization operations.
/**
@@ -107,7 +127,7 @@ public:
* you don't want to degrade the quality of service if there are
* other threads waiting to get the token. If <requeue_position> ==
* -1 and there are other threads waiting to obtain the token we are
- * queued at the end of the list of waiters. If <requeue_position>
+ * queued according to the queueing strategy. If <requeue_position>
* > -1 then it indicates how many entries to skip over before
* inserting our thread into the list of waiters (e.g.,
* <requeue_position> == 0 means "insert at front of the queue").
@@ -174,7 +194,7 @@ public:
/// Declare the dynamic allocation hooks.
ACE_ALLOC_HOOK_DECLARE;
- // = The following structure implements a ACE_FIFO of waiter threads
+ // = The following structure implements a LIFO/FIFO queue of waiter threads
// that are asleep waiting to obtain the token.
struct ACE_Token_Queue_Entry
@@ -270,6 +290,9 @@ private:
/// The attributes for the condition variables, optimizes lock time.
ACE_Condition_Attributes attributes_;
+
+ /// Queueing strategy, LIFO/FIFO.
+ int queueing_strategy_;
};
#if defined (__ACE_INLINE__)
@@ -280,6 +303,8 @@ private:
class ACE_Export ACE_Token
{
public:
+ int queueing_strategy (void) { ACE_NOTSUP_RETURN (-1); }
+ void queueing_strategy (int queueing_strategy) { }
int acquire (ACE_Time_Value * = 0) { ACE_NOTSUP_RETURN (-1); }
int tryacquire (void) { ACE_NOTSUP_RETURN (-1); }
int remove (void) { ACE_NOTSUP_RETURN (-1); }
diff --git a/ace/Token.i b/ace/Token.i
index e5b7aaf94a9..c7c0f2d9285 100644
--- a/ace/Token.i
+++ b/ace/Token.i
@@ -4,6 +4,18 @@
// Token.i
ACE_INLINE int
+ACE_Token::queueing_strategy (void)
+{
+ return this->queueing_strategy_;
+}
+
+ACE_INLINE void
+ACE_Token::queueing_strategy (int queueing_strategy)
+{
+ this->queueing_strategy_ = queueing_strategy == -1 ? -1 : 0;
+}
+
+ACE_INLINE int
ACE_Token::remove (void)
{
ACE_TRACE ("ACE_Token::remove");