#include <Token.h>
Collaboration diagram for ACE_Token:
Public Types | |
enum | QUEUEING_STRATEGY { FIFO = -1, LIFO = 0 } |
Public Member Functions | |
ACE_Token (const ACE_TCHAR *name=0, void *=0) | |
Constructor. | |
virtual | ~ACE_Token (void) |
Destructor. | |
int | queueing_strategy (void) |
Retrieve the current queueing strategy. | |
void | queueing_strategy (int queueing_strategy) |
Set the queueing strategy. | |
int | acquire (void(*sleep_hook)(void *), void *arg=0, ACE_Time_Value *timeout=0) |
int | acquire (ACE_Time_Value *timeout=0) |
virtual void | sleep_hook (void) |
int | renew (int requeue_position=0, ACE_Time_Value *timeout=0) |
int | tryacquire (void) |
int | remove (void) |
Shuts down the ACE_Token instance. | |
int | release (void) |
int | acquire_read (void) |
int | acquire_read (void(*sleep_hook)(void *), void *arg=0, ACE_Time_Value *timeout=0) |
int | acquire_write (void) |
Calls acquire(). | |
int | acquire_write (void(*sleep_hook)(void *), void *arg=0, ACE_Time_Value *timeout=0) |
Calls acquire(). | |
int | tryacquire_read (void) |
Lower priority try_acquire(). | |
int | tryacquire_write (void) |
Just calls . | |
int | tryacquire_write_upgrade (void) |
Assumes the caller has acquired the token and returns 0. | |
int | waiters (void) |
ACE_thread_t | current_owner (void) |
Return the id of the current thread that owns the token. | |
void | dump (void) const |
Dump the state of an object. | |
Public Attributes | |
ACE_ALLOC_HOOK_DECLARE | |
Declare the dynamic allocation hooks. | |
Private Types | |
enum | ACE_Token_Op_Type { READ_TOKEN = 1, WRITE_TOKEN } |
Private Member Functions | |
int | shared_acquire (void(*sleep_hook_func)(void *), void *arg, ACE_Time_Value *timeout, ACE_Token_Op_Type op_type) |
Implements the and methods above. | |
void | wakeup_next_waiter (void) |
Wake next in line for ownership. | |
Private Attributes | |
ACE_Token_Queue | writers_ |
A queue of writer threads. | |
ACE_Token_Queue | readers_ |
A queue of reader threads. | |
ACE_Thread_Mutex | lock_ |
ACE_Thread_Mutex used to lock internal data structures. | |
ACE_thread_t | owner_ |
Current owner of the token. | |
int | in_use_ |
int | waiters_ |
Number of waiters. | |
int | nesting_level_ |
Current nesting level. | |
ACE_Condition_Attributes | attributes_ |
The attributes for the condition variables, optimizes lock time. | |
int | queueing_strategy_ |
Queueing strategy, LIFO/FIFO. |
This class is a more general-purpose synchronization mechanism than many native OS mutexes. For example, it implements "recursive mutex" semantics, where a thread that owns the token can reacquire it without deadlocking. If the same thread calls multiple times, however, it must call an equal number of times before the token is actually released. Threads that are blocked awaiting the token are serviced in strict FIFO/LIFO order as other threads release the token (Solaris and Pthread mutexes don't strictly enforce an acquisition 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 read/write acquire operations do not have the usual semantic of reader/writer locks. Only one reader can acquire the token at a time (which is different from the usual reader/writer locks where several readers can acquire a lock at the same time as long as there is no writer waiting for the lock). We choose the names to (1) borrow the semantic to give writers higher priority and (2) support a common interface for all locking classes in ACE.
Definition at line 76 of file Token.h.
|
Definition at line 257 of file Token.h.
00258 { 00259 READ_TOKEN = 1, 00260 WRITE_TOKEN 00261 }; |
|
Available queueing strategies. Definition at line 83 of file Token.h.
|
|
Constructor.
Definition at line 166 of file Token.cpp. References ACE_TCHAR, FIFO, and queueing_strategy_.
00167 : lock_ (name, (ACE_mutexattr_t *) any), 00168 owner_ (ACE_OS::NULL_thread), 00169 in_use_ (0), 00170 waiters_ (0), 00171 nesting_level_ (0), 00172 attributes_ (USYNC_THREAD), 00173 queueing_strategy_ (FIFO) 00174 { 00175 // ACE_TRACE ("ACE_Token::ACE_Token"); 00176 } |
|
Destructor.
Definition at line 178 of file Token.cpp. References ACE_TRACE.
00179 { 00180 ACE_TRACE ("ACE_Token::~ACE_Token"); 00181 } |
|
This behaves just like the previous method, except that it invokes the virtual function called that can be overridden by a subclass of ACE_Token. Definition at line 338 of file Token.cpp. References ACE_TRACE, shared_acquire(), and WRITE_TOKEN.
00339 { 00340 ACE_TRACE ("ACE_Token::acquire"); 00341 return this->shared_acquire (0, 0, timeout, ACE_Token::WRITE_TOKEN); 00342 } |
|
Acquire the token, sleeping until it is obtained or until the expiration of , which is treated as "absolute" time. If some other thread currently holds the token then is called before our thread goes to sleep. This can be used by the requesting thread to unblock a token-holder that is sleeping, e.g., by means of writing to a pipe (the ACE ACE_Reactor uses this functionality). Return values: 0 if acquires without calling 1 if is called. 2 if the token is signaled. -1 if failure or timeout occurs (if timeout occurs errno == ETIME) If == <&ACE_Time_Value::zero> then acquire has polling semantics (and does *not* call ). Definition at line 348 of file Token.cpp. References ACE_TRACE, shared_acquire(), and WRITE_TOKEN.
00351 { 00352 ACE_TRACE ("ACE_Token::acquire"); 00353 return this->shared_acquire (sleep_hook_func, arg, timeout, ACE_Token::WRITE_TOKEN); 00354 } |
|
Behaves like acquire() but at a lower priority. It should probably be called acquire_yield() since the semantics aren't really what's commonly expected for readers/writer locks. See the class documentation above for more details. Definition at line 86 of file Token.inl. References ACE_TRACE, READ_TOKEN, and shared_acquire().
00089 { 00090 ACE_TRACE ("ACE_Token::acquire_read"); 00091 return this->shared_acquire (sleep_hook_func, arg, timeout, ACE_Token::READ_TOKEN); 00092 } |
|
Behaves like acquire() but at a lower priority. It should probably be called acquire_yield() since the semantics aren't really what's commonly expected for readers/writer locks. See the class documentation above for more details. Definition at line 62 of file Token.inl. References ACE_TRACE, READ_TOKEN, and shared_acquire().
00063 { 00064 ACE_TRACE ("ACE_Token::acquire_read"); 00065 return this->shared_acquire 00066 (0, 0, 0, ACE_Token::READ_TOKEN); 00067 } |
|
Calls acquire().
Definition at line 110 of file Token.inl. References ACE_TRACE, shared_acquire(), and WRITE_TOKEN.
00113 { 00114 ACE_TRACE ("ACE_Token::acquire_write"); 00115 return this->shared_acquire (sleep_hook_func, arg, timeout, ACE_Token::WRITE_TOKEN); 00116 } |
|
Calls acquire().
Definition at line 70 of file Token.inl. References ACE_TRACE, shared_acquire(), and WRITE_TOKEN.
00071 { 00072 ACE_TRACE ("ACE_Token::acquire_write"); 00073 return this->shared_acquire 00074 (0, 0, 0, ACE_Token::WRITE_TOKEN); 00075 } |
|
Return the id of the current thread that owns the token.
Definition at line 53 of file Token.inl. References ACE_GUARD_RETURN, and ACE_TRACE.
00054 { 00055 ACE_TRACE ("ACE_Token::current_owner"); 00056 ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, this->owner_); 00057 00058 return this->owner_; 00059 } |
|
Dump the state of an object.
Definition at line 26 of file Token.cpp. References ACE_BEGIN_DUMP, ACE_DEBUG, ACE_END_DUMP, ACE_LIB_TEXT, ACE_TRACE, and LM_DEBUG. Referenced by release(), renew(), and shared_acquire().
00027 { 00028 #if defined (ACE_HAS_DUMP) 00029 ACE_TRACE ("ACE_Token::dump"); 00030 00031 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); 00032 00033 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nthread = %d"), ACE_Thread::self ())); 00034 // @@ Is there a portable way to do this? 00035 // ACE_DEBUG ((LM_DEBUG, "\nowner_ = %d", (long) this->owner_)); 00036 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nowner_ addr = %x"), &this->owner_)); 00037 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nwaiters_ = %d"), this->waiters_)); 00038 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nin_use_ = %d"), this->in_use_)); 00039 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nnesting level = %d"), this->nesting_level_)); 00040 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); 00041 #endif /* ACE_HAS_DUMP */ 00042 } |
|
Set the queueing strategy.
Definition at line 21 of file Token.inl. References queueing_strategy_.
00022 { 00023 this->queueing_strategy_ = queueing_strategy == -1 ? -1 : 0; 00024 } |
|
Retrieve the current queueing strategy.
Definition at line 15 of file Token.inl. References queueing_strategy_.
00016 { 00017 return this->queueing_strategy_; 00018 } |
|
Relinquish the token. If there are any waiters then the next one in line gets it. Definition at line 483 of file Token.cpp. References ACE_GUARD_RETURN, ACE_TRACE, dump(), and wakeup_next_waiter().
00484 { 00485 ACE_TRACE ("ACE_Token::release"); 00486 ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); 00487 00488 // ACE_ASSERT (ACE_OS::thr_equal (ACE_Thread::self (), this->owner_)); 00489 00490 #if defined (DEBUGGING) 00491 this->dump (); 00492 #endif /* DEBUGGING */ 00493 00494 // Nested release... 00495 if (this->nesting_level_ > 0) 00496 --this->nesting_level_; 00497 else 00498 { 00499 // 00500 // Regular release... 00501 // 00502 00503 // Wakeup waiter. 00504 this->wakeup_next_waiter (); 00505 } 00506 00507 return 0; 00508 } |
|
Shuts down the ACE_Token instance.
Definition at line 27 of file Token.inl. References ACE_NOTSUP_RETURN, and ACE_TRACE.
00028 { 00029 ACE_TRACE ("ACE_Token::remove"); 00030 // Don't have an implementation for this yet... 00031 ACE_NOTSUP_RETURN (-1); 00032 } |
|
An optimized method that efficiently reacquires the token if no other threads are waiting. This is useful for situations where you don't want to degrade the quality of service if there are other threads waiting to get the token. If == -1 and there are other threads waiting to obtain the token we are queued according to the queueing strategy. If > -1 then it indicates how many entries to skip over before inserting our thread into the list of waiters (e.g., == 0 means "insert at front of the queue"). Renew has the rather odd semantics such that if there are other waiting threads it will give up the token even if the nesting_level_ > 1. I'm not sure if this is really the right thing to do (since it makes it possible for shared data to be changed unexpectedly) so use with caution... This method maintians the original token priority. As in , the value is an absolute time. Definition at line 359 of file Token.cpp. References ACE_ASSERT, ACE_GUARD_RETURN, ACE_TRACE, dump(), ETIME, ACE_Token::ACE_Token_Queue::head_, ACE_Token::ACE_Token_Queue::insert_entry(), READ_TOKEN, readers_, ACE_Token::ACE_Token_Queue::remove_entry(), ACE_Token::ACE_Token_Queue_Entry::runable_, ACE_Thread::self(), ACE_OS::thr_equal(), ACE_Token::ACE_Token_Queue_Entry::thread_id_, ACE_Token::ACE_Token_Queue_Entry::wait(), wakeup_next_waiter(), WRITE_TOKEN, and writers_.
00361 { 00362 ACE_TRACE ("ACE_Token::renew"); 00363 ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); 00364 00365 #if defined (DEBUGGING) 00366 this->dump (); 00367 #endif /* DEBUGGING */ 00368 // ACE_ASSERT (ACE_OS::thr_equal (ACE_Thread::self (), this->owner_)); 00369 00370 // Check to see if there are any waiters worth giving up the lock 00371 // for. 00372 00373 // If no writers and either we are a writer or there are no readers. 00374 if (this->writers_.head_ == 0 && 00375 (this->in_use_ == ACE_Token::WRITE_TOKEN || 00376 this->readers_.head_ == 0)) 00377 // Immediate return. 00378 return 0; 00379 00380 // We've got to sleep until we get the token again. 00381 00382 // Determine which queue should this thread go to. 00383 ACE_Token::ACE_Token_Queue *this_threads_queue = 00384 this->in_use_ == ACE_Token::READ_TOKEN ? 00385 &this->readers_ : &this->writers_; 00386 00387 ACE_Token::ACE_Token_Queue_Entry my_entry (this->lock_, 00388 this->owner_); 00389 00390 this_threads_queue->insert_entry (my_entry, 00391 // if requeue_position == 0 then we want to go next, 00392 // otherwise use the queueing strategy, which might also 00393 // happen to be 0. 00394 requeue_position == 0 ? 0 : this->queueing_strategy_); 00395 ++this->waiters_; 00396 00397 // Remember nesting level... 00398 int const save_nesting_level_ = this->nesting_level_; 00399 00400 // Reset state for new owner. 00401 this->nesting_level_ = 0; 00402 00403 // Wakeup waiter. 00404 this->wakeup_next_waiter (); 00405 00406 int timed_out = 0; 00407 int error = 0; 00408 00409 // Sleep until we've got the token (ignore signals). 00410 do 00411 { 00412 int result = my_entry.wait (timeout, 00413 this->lock_); 00414 00415 if (result == -1) 00416 { 00417 // Note, this should obey whatever thread-specific interrupt 00418 // policy is currently in place... 00419 if (errno == EINTR) 00420 continue; 00421 00422 #if defined (DEBUGGING) 00423 cerr << '(' << ACE_Thread::self () << ')' 00424 << " renew: " 00425 << (errno == ETIME ? "timed out" : "error occurred") 00426 << endl; 00427 #endif /* DEBUGGING */ 00428 00429 // We come here if a timeout occurs or some serious 00430 // ACE_Condition object error. 00431 if (errno == ETIME) 00432 timed_out = 1; 00433 else 00434 error = 1; 00435 00436 // Stop the loop. 00437 break; 00438 } 00439 } 00440 while (!ACE_OS::thr_equal (my_entry.thread_id_, this->owner_)); 00441 00442 // Do this always and irrespective of the result of wait(). 00443 --this->waiters_; 00444 this_threads_queue->remove_entry (&my_entry); 00445 00446 #if defined (DEBUGGING) 00447 cerr << '(' << ACE_Thread::self () << ')' 00448 << " acquire (UNBLOCKED)" << endl; 00449 #endif /* DEBUGGING */ 00450 00451 // If timeout occured 00452 if (timed_out) 00453 { 00454 // This thread was still selected to own the token. 00455 if (my_entry.runable_) 00456 { 00457 // Wakeup next waiter since this thread timed out. 00458 this->wakeup_next_waiter (); 00459 } 00460 00461 // Return error. 00462 return -1; 00463 } 00464 else if (error) 00465 { 00466 // Return error. 00467 return -1; 00468 } 00469 00470 // If this is a normal wakeup, this thread should be runnable. 00471 ACE_ASSERT (my_entry.runable_); 00472 00473 // Reinstate nesting level. 00474 this->nesting_level_ = save_nesting_level_; 00475 00476 return 0; 00477 } |
|
Implements the and methods above.
Definition at line 184 of file Token.cpp. References ACE_ASSERT, ACE_GUARD_RETURN, ACE_thread_t, ACE_TRACE, dump(), ETIME, ACE_Token::ACE_Token_Queue::insert_entry(), READ_TOKEN, readers_, ACE_Token::ACE_Token_Queue::remove_entry(), ACE_Token::ACE_Token_Queue_Entry::runable_, ACE_Time_Value::sec(), ACE_Thread::self(), sleep_hook(), ACE_OS::thr_equal(), ACE_Time_Value::usec(), ACE_Token::ACE_Token_Queue_Entry::wait(), wakeup_next_waiter(), and writers_. Referenced by acquire(), acquire_read(), acquire_write(), tryacquire(), tryacquire_read(), and tryacquire_write().
00188 { 00189 ACE_TRACE ("ACE_Token::shared_acquire"); 00190 ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); 00191 00192 #if defined (DEBUGGING) 00193 this->dump (); 00194 #endif /* DEBUGGING */ 00195 00196 ACE_thread_t thr_id = ACE_Thread::self (); 00197 00198 // Nobody holds the token. 00199 if (!this->in_use_) 00200 { 00201 // Its mine! 00202 this->in_use_ = op_type; 00203 this->owner_ = thr_id; 00204 return 0; 00205 } 00206 00207 // 00208 // Someone already holds the token. 00209 // 00210 00211 // Check if it is us. 00212 if (ACE_OS::thr_equal (thr_id, this->owner_)) 00213 { 00214 ++this->nesting_level_; 00215 return 0; 00216 } 00217 00218 // Do a quick check for "polling" behavior. 00219 if (timeout != 0 && timeout->sec () == 0 && timeout->usec () == 0) 00220 { 00221 errno = ETIME; 00222 return -1; 00223 } 00224 00225 // 00226 // We've got to sleep until we get the token. 00227 // 00228 00229 // Which queue we should end up in... 00230 ACE_Token_Queue *queue = (op_type == ACE_Token::READ_TOKEN 00231 ? &this->readers_ 00232 : &this->writers_); 00233 00234 // Allocate queue entry on stack. This works since we don't exit 00235 // this method's activation record until we've got the token. 00236 ACE_Token::ACE_Token_Queue_Entry my_entry (this->lock_, 00237 thr_id, 00238 this->attributes_); 00239 queue->insert_entry (my_entry, this->queueing_strategy_); 00240 ++this->waiters_; 00241 00242 // Execute appropriate <sleep_hook> callback. (@@ should these 00243 // methods return a success/failure status, and if so, what should 00244 // we do with it?) 00245 int ret = 0; 00246 if (sleep_hook_func) 00247 { 00248 (*sleep_hook_func) (arg); 00249 ++ret; 00250 } 00251 else 00252 { 00253 // Execute virtual method. 00254 this->sleep_hook (); 00255 ++ret; 00256 } 00257 00258 int timed_out = 0; 00259 int error = 0; 00260 00261 // Sleep until we've got the token (ignore signals). 00262 do 00263 { 00264 int result = my_entry.wait (timeout, 00265 this->lock_); 00266 00267 if (result == -1) 00268 { 00269 // Note, this should obey whatever thread-specific interrupt 00270 // policy is currently in place... 00271 if (errno == EINTR) 00272 continue; 00273 00274 #if defined (DEBUGGING) 00275 cerr << '(' << ACE_Thread::self () << ')' 00276 << " acquire: " 00277 << (errno == ETIME ? "timed out" : "error occurred") 00278 << endl; 00279 #endif /* DEBUGGING */ 00280 00281 // We come here if a timeout occurs or some serious 00282 // ACE_Condition object error. 00283 if (errno == ETIME) 00284 timed_out = 1; 00285 else 00286 error = 1; 00287 00288 // Stop the loop. 00289 break; 00290 } 00291 } 00292 while (!ACE_OS::thr_equal (thr_id, this->owner_)); 00293 00294 // Do this always and irrespective of the result of wait(). 00295 --this->waiters_; 00296 queue->remove_entry (&my_entry); 00297 00298 #if defined (DEBUGGING) 00299 cerr << '(' << ACE_Thread::self () << ')' 00300 << " acquire (UNBLOCKED)" << endl; 00301 #endif /* DEBUGGING */ 00302 00303 // If timeout occured 00304 if (timed_out) 00305 { 00306 // This thread was still selected to own the token. 00307 if (my_entry.runable_) 00308 { 00309 // Wakeup next waiter since this thread timed out. 00310 this->wakeup_next_waiter (); 00311 } 00312 00313 // Return error. 00314 return -1; 00315 } 00316 else if (error) 00317 { 00318 // Return error. 00319 return -1; 00320 } 00321 00322 // If this is a normal wakeup, this thread should be runnable. 00323 ACE_ASSERT (my_entry.runable_); 00324 00325 return ret; 00326 } |
|
This should be overridden by a subclass to define the appropriate behavior before goes to sleep. By default, this is a no-op... Definition at line 332 of file Token.cpp. References ACE_TRACE. Referenced by shared_acquire().
00333 { 00334 ACE_TRACE ("ACE_Token::sleep_hook"); 00335 } |
|
Become interface-compliant with other lock mechanisms (implements a non-blocking ). Definition at line 35 of file Token.inl. References ACE_TRACE, shared_acquire(), and WRITE_TOKEN.
00036 { 00037 ACE_TRACE ("ACE_Token::tryacquire"); 00038 return this->shared_acquire 00039 (0, 0, (ACE_Time_Value *) &ACE_Time_Value::zero, ACE_Token::WRITE_TOKEN); 00040 } |
|
Lower priority try_acquire().
Definition at line 78 of file Token.inl. References ACE_TRACE, READ_TOKEN, and shared_acquire().
00079 { 00080 ACE_TRACE ("ACE_Token::tryacquire_read"); 00081 return this->shared_acquire 00082 (0, 0, (ACE_Time_Value *) &ACE_Time_Value::zero, ACE_Token::READ_TOKEN); 00083 } |
|
Just calls .
Definition at line 95 of file Token.inl. References ACE_TRACE, shared_acquire(), and WRITE_TOKEN.
00096 { 00097 ACE_TRACE ("ACE_Token::tryacquire_write"); 00098 return this->shared_acquire 00099 (0, 0, (ACE_Time_Value *) &ACE_Time_Value::zero, ACE_Token::WRITE_TOKEN); 00100 } |
|
Assumes the caller has acquired the token and returns 0.
Definition at line 103 of file Token.inl. References ACE_TRACE.
00104 { 00105 ACE_TRACE ("ACE_Token::tryacquire_write_upgrade"); 00106 return 0; 00107 } |
|
Return the number of threads that are currently waiting to get the token. Definition at line 43 of file Token.inl. References ACE_GUARD_RETURN, and ACE_TRACE.
00044 { 00045 ACE_TRACE ("ACE_Token::waiters"); 00046 ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1); 00047 00048 int const ret = this->waiters_; 00049 return ret; 00050 } |
|
Wake next in line for ownership.
Definition at line 511 of file Token.cpp. References ACE_TRACE, ACE_Token::ACE_Token_Queue::head_, READ_TOKEN, readers_, ACE_Token::ACE_Token_Queue_Entry::runable_, ACE_Token::ACE_Token_Queue_Entry::signal(), ACE_Token::ACE_Token_Queue_Entry::thread_id_, WRITE_TOKEN, and writers_. Referenced by release(), renew(), and shared_acquire().
00512 { 00513 ACE_TRACE ("ACE_Token::wakeup_next_waiter"); 00514 00515 // Reset state for new owner. 00516 this->owner_ = ACE_OS::NULL_thread; 00517 this->in_use_ = 0; 00518 00519 // Any waiters... 00520 if (this->writers_.head_ == 0 && 00521 this->readers_.head_ == 0) 00522 { 00523 // No more waiters... 00524 return; 00525 } 00526 00527 // Wakeup next waiter. 00528 ACE_Token_Queue *queue = 0; 00529 00530 // Writer threads get priority to run first. 00531 if (this->writers_.head_ != 0) 00532 { 00533 this->in_use_ = ACE_Token::WRITE_TOKEN; 00534 queue = &this->writers_; 00535 } 00536 else 00537 { 00538 this->in_use_ = ACE_Token::READ_TOKEN; 00539 queue = &this->readers_; 00540 } 00541 00542 // Wake up waiter and make it runable. 00543 queue->head_->runable_ = 1; 00544 queue->head_->signal (); 00545 00546 this->owner_ = queue->head_->thread_id_; 00547 } |
|
Declare the dynamic allocation hooks.
|
|
The attributes for the condition variables, optimizes lock time.
|
|
Some thread (i.e., ) is using the token. We need this extra variable to deal with POSIX pthreads madness... |
|
ACE_Thread_Mutex used to lock internal data structures.
|
|
Current nesting level.
|
|
Current owner of the token.
|
|
Queueing strategy, LIFO/FIFO.
Definition at line 317 of file Token.h. Referenced by ACE_Token(), and queueing_strategy(). |
|
A queue of reader threads.
Definition at line 295 of file Token.h. Referenced by renew(), shared_acquire(), and wakeup_next_waiter(). |
|
Number of waiters.
|
|
A queue of writer threads.
Definition at line 292 of file Token.h. Referenced by renew(), shared_acquire(), and wakeup_next_waiter(). |