#include <Local_Tokens.h>
Inheritance diagram for ACE_Mutex_Token:


Public Methods | |
| ACE_EXPLICIT | ACE_Mutex_Token (const ACE_TCHAR *name) |
| Constructor. More... | |
| virtual | ~ACE_Mutex_Token (void) |
| Destructor. More... | |
| virtual int | acquire (ACE_TPQ_Entry *caller, int ignore_deadlock, int notify) |
| virtual int | tryacquire (ACE_TPQ_Entry *caller) |
| Same as acquire, but fails if would block. More... | |
| virtual int | renew (ACE_TPQ_Entry *caller, int requeue_position) |
| virtual int | release (ACE_TPQ_Entry *caller) |
| void | dump (void) const |
| Dump the state of the class. More... | |
| virtual int | type (void) const |
| Returns ACE_Tokens::MUTEX. More... | |
| virtual int | owners (OWNER_STACK &o, const ACE_TCHAR *id) |
| Returns a stack of the current owners. Returns -1 on error, 0 on success. If <id> is non-zero, returns 1 if id is an owner. More... | |
| virtual int | is_waiting_for (const ACE_TCHAR *id) |
| Returns 1 if <id> is waiting for this token. 0 otherwise. More... | |
| virtual int | is_owner (const ACE_TCHAR *id) |
| Returns 1 if <id> is an owner of this token. 0 otherwise. More... | |
Private Attributes | |
| ACE_TOKEN_CONST::MUTEX | lock_ |
| ACE_Mutex_Token used to lock internal data structures. More... | |
Not a public interface. This class is a more general-purpose synchronization mechanism than SunOS 5.x mutexes. For example, it implements "recursive mutex" semantics, where a thread that owns the token can reacquire it without deadlocking. In addition, threads that are blocked awaiting the token are serviced in strict FIFO order as other threads release the token (SunOS 5.x mutexes don't strictly enforce an acquisition order).
Definition at line 493 of file Local_Tokens.h.
|
|
Constructor.
Definition at line 434 of file Local_Tokens.cpp. References ACE_MAXTOKENNAMELEN, ACE_TCHAR, ACE_TRACE, ACE_Tokens::name, and ACE_OS_String::strsncpy.
00435 {
00436 ACE_TRACE ("ACE_Mutex_Token::ACE_Mutex_Token");
00437
00438 ACE_OS::strsncpy (this->token_name_,
00439 name,
00440 ACE_MAXTOKENNAMELEN);
00441 }
|
|
|
Destructor.
Definition at line 443 of file Local_Tokens.cpp. References ACE_TRACE.
00444 {
00445 ACE_TRACE ("ACE_Mutex_Token::~ACE_Mutex_Token");
00446 }
|
|
||||||||||||||||
|
Returns 0 on success, -1 on failure with <ACE_Log_Msg::errnum> as the reason. If errnum == EWOULDBLOCK, and notify == 1, <ACE_Token_Proxy::sleep_hook> has been called on the current owner of the token. If ignore_deadlock is passed as 1 and errnum == EDEADLK, then deadlock was detected via ace_token_manager. Implements ACE_Tokens. Definition at line 449 of file Local_Tokens.cpp. References ACE_GUARD_RETURN, ACE_RETURN, ACE_TRACE, ACE_TPQ_Entry::call_sleep_hook, ACE_Token_Manager::check_deadlock, ACE_TPQ_Entry::client_id, EDEADLK, ACE_Token_Proxy_Queue::enqueue, EWOULDBLOCK, ACE_Token_Manager::instance, is_owner, ACE_Null_Mutex::lock_, ACE_TOKEN_CONST::MUTEX, ACE_TPQ_Entry::nesting_level, ACE_Tokens::owner, ACE_TPQ_Entry::proxy, and ACE_Tokens::waiters_.
00452 {
00453 ACE_TRACE ("ACE_Mutex_Token::acquire");
00454 // We need to acquire two locks. This one to ensure that only one
00455 // thread uses this token at a time.
00456 ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon1, this->lock_, -1);
00457 // This one to ensure an atomic transaction across all tokens. Note
00458 // that this order is crucial too. It's resource coloring for other
00459 // threads which may be calling this same token.
00460 ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon2, ACE_Token_Manager::instance ()->mutex (), -1);
00461
00462 // Does _anyone_ own the token?
00463 if (this->owner () == 0)
00464 {
00465 // there are no waiters, so queue as the first waiter (the owner.)
00466 this->waiters_.enqueue (caller, -1);
00467 return 0; // success
00468 }
00469
00470 // Does the caller already own it?
00471 if (this->is_owner (caller->client_id ()))
00472 {
00473 // Recursive acquisition.
00474 caller->nesting_level (1);
00475 return 0; // success
00476 }
00477
00478 // Check for deadlock.
00479 if (!ignore_deadlock
00480 && ACE_Token_Manager::instance ()->check_deadlock (caller->proxy ()) == 1)
00481 {
00482 errno = EDEADLK;
00483 ACE_RETURN (-1);
00484 }
00485
00486 // Someone owns it. Sorry, you're getting queued up at the end of
00487 // the waiter queue.
00488 this->waiters_.enqueue (caller, -1);
00489
00490 if (notify)
00491 this->owner ()->call_sleep_hook ();
00492
00493 errno = EWOULDBLOCK;
00494 ACE_RETURN (-1);
00495
00496 ACE_NOTREACHED (return -1);
00497 }
|
|
|
Dump the state of the class.
Reimplemented from ACE_Tokens. Definition at line 421 of file Local_Tokens.cpp. References ACE_BEGIN_DUMP, ACE_DEBUG, ACE_END_DUMP, ACE_LIB_TEXT, ACE_TRACE, ACE_Tokens::dump, LM_DEBUG, and lock_.
00422 {
00423 ACE_TRACE ("ACE_Mutex_Token::dump");
00424 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00425 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("ACE_Mutex_Token::dump:\n")));
00426 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("lock_\n")));
00427 lock_.dump ();
00428 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("base:\n")));
00429 ACE_Tokens::dump ();
00430 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("ACE_Mutex_Token::dump end.\n")));
00431 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00432 }
|
|
|
Returns 1 if <id> is an owner of this token. 0 otherwise.
Implements ACE_Tokens. Definition at line 646 of file Local_Tokens.cpp. References ACE_TCHAR, ACE_TRACE, ACE_TPQ_Entry::equal_client_id, and ACE_Tokens::owner. Referenced by acquire, is_waiting_for, release, renew, and tryacquire.
00647 {
00648 ACE_TRACE ("ACE_Mutex_Token::is_owner");
00649 // If there is an owner, return whether it is <id>.
00650 if ((this->owner () != 0) &&
00651 this->owner ()->equal_client_id (id))
00652 return 1;
00653 else
00654 return 0;
00655 }
|
|
|
Returns 1 if <id> is waiting for this token. 0 otherwise.
Implements ACE_Tokens. Definition at line 624 of file Local_Tokens.cpp. References ACE_TCHAR, ACE_TRACE, ACE_TPQ_Iterator::advance, ACE_TPQ_Entry::equal_client_id, is_owner, ACE_TPQ_Iterator::next, ACE_Tokens::owner, and ACE_Tokens::waiters_.
00625 {
00626 ACE_TRACE ("ACE_Mutex_Token::is_waiting_for");
00627 // If there is no owner, or <id> is the owner, return false.
00628 if ((this->owner () == 0) || this->is_owner (id))
00629 return 0;
00630
00631 // Step through each waiter looking for <id>.
00632 ACE_TPQ_Iterator iterator (waiters_);
00633 iterator.advance ();
00634 for (ACE_TPQ_Entry *temp = 0;
00635 iterator.next (temp) != 0;
00636 iterator.advance ())
00637 {
00638 if (temp->equal_client_id (id))
00639 return 1;
00640 }
00641
00642 return 0;
00643 }
|
|
||||||||||||
|
Returns a stack of the current owners. Returns -1 on error, 0 on success. If <id> is non-zero, returns 1 if id is an owner.
Implements ACE_Tokens. Definition at line 607 of file Local_Tokens.cpp. References ACE_TCHAR, ACE_TRACE, ACE_TPQ_Entry::equal_client_id, and ACE_Tokens::owner.
00609 {
00610 ACE_TRACE ("ACE_Mutex_Token::owners");
00611 if (this->owner () != 0)
00612 {
00613 stack.push (this->owner ());
00614 // If an <id> is specified, return whether it is the owner being
00615 // returned.
00616 if (id != 0)
00617 return this->owner ()->equal_client_id (id);
00618 }
00619
00620 return 0;
00621 }
|
|
|
Relinquish the token. If there are any waiters then the next one in line gets it. If the caller is not the owner, caller is removed from the waiter list. Implements ACE_Tokens. Definition at line 574 of file Local_Tokens.cpp. References ACE_GUARD_RETURN, ACE_RETURN, ACE_TRACE, ACE_TPQ_Entry::client_id, ACE_Token_Proxy_Queue::dequeue, is_owner, ACE_Null_Mutex::lock_, ACE_TOKEN_CONST::MUTEX, ACE_TPQ_Entry::nesting_level, ACE_Tokens::owner, ACE_TPQ_Entry::proxy, ACE_Tokens::remove, ACE_Token_Proxy::token_acquired, and ACE_Tokens::waiters_.
00575 {
00576 ACE_TRACE ("ACE_Mutex_Token::release");
00577 ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_, -1);
00578
00579 // Does anyone own the token?
00580 if (this->owner () == 0)
00581 {
00582 errno = EACCES;
00583 ACE_RETURN (-1);
00584 }
00585
00586 // Is the caller the owner.
00587 if (this->is_owner (caller->client_id ()))
00588 {
00589 // Check the nesting level.
00590 if (caller->nesting_level () > 0)
00591 caller->nesting_level (-1);
00592 else
00593 {
00594 this->waiters_.dequeue ();
00595 // Notify new owner.
00596 if (this->owner () != 0)
00597 this->owner ()->proxy ()->token_acquired (this->owner ());
00598 }
00599 }
00600 else
00601 this->remove (caller);
00602
00603 return 0;
00604 }
|
|
||||||||||||
|
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 <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> > -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"). 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... Returns 0 on success, -1 on failure with <ACE_Log_Msg::errnum> as the reason. If errnum == EWOULDBLOCK, and notify == 1, <ACE_Token_Proxy::sleep_hook> has been called on the current owner of the token. Implements ACE_Tokens. Definition at line 535 of file Local_Tokens.cpp. References ACE_GUARD_RETURN, ACE_RETURN, ACE_TRACE, ACE_TPQ_Entry::client_id, ACE_Token_Proxy_Queue::dequeue, ACE_Token_Proxy_Queue::enqueue, EWOULDBLOCK, is_owner, ACE_Null_Mutex::lock_, ACE_TOKEN_CONST::MUTEX, ACE_Tokens::owner, ACE_TPQ_Entry::proxy, ACE_Token_Proxy_Queue::size, ACE_Token_Proxy::token_acquired, and ACE_Tokens::waiters_.
00537 {
00538 ACE_TRACE ("ACE_Mutex_Token::renew");
00539 ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_, -1);
00540
00541 // Verify that the caller is the owner.
00542 if (this->is_owner (caller->client_id ()) == 0)
00543 {
00544 errno = EACCES;
00545 ACE_RETURN (-1);
00546 }
00547
00548 // The caller is the owner, so check to see if there are any
00549 // waiters. If not, we just keep the token. == 1 means that there
00550 // is only the owner.
00551 if (this->waiters_.size () == 1 || requeue_position == 0)
00552 return 0;
00553
00554 // Requeue the caller.
00555 this->waiters_.dequeue ();
00556
00557 this->waiters_.enqueue (caller, requeue_position);
00558
00559 // Notify new owner.
00560 if (this->owner () != 0)
00561 this->owner ()->proxy ()->token_acquired (this->owner ());
00562
00563 // Tell the caller that the operation would block.
00564 errno = EWOULDBLOCK;
00565 ACE_RETURN (-1);
00566
00567 ACE_NOTREACHED (return -1);
00568 }
|
|
|
Same as acquire, but fails if would block.
Implements ACE_Tokens. Definition at line 500 of file Local_Tokens.cpp. References ACE_GUARD_RETURN, ACE_RETURN, ACE_TRACE, ACE_TPQ_Entry::client_id, ACE_Token_Proxy_Queue::enqueue, EWOULDBLOCK, ACE_Token_Manager::instance, is_owner, ACE_Null_Mutex::lock_, ACE_TOKEN_CONST::MUTEX, ACE_TPQ_Entry::nesting_level, ACE_Tokens::owner, and ACE_Tokens::waiters_.
00501 {
00502 ACE_TRACE ("ACE_Mutex_Token::tryacquire");
00503 // We need to acquire two locks. This one to ensure that only one
00504 // thread uses this token at a time.
00505 ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon1, this->lock_, -1);
00506 // This one to ensure an atomic transaction across all tokens. Note
00507 // that this order is crucial too. It's resource coloring for other
00508 // threads which may be calling this same token.
00509 ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon2, ACE_Token_Manager::instance ()->mutex (), -1);
00510
00511 // Does _anyone_ own the token?
00512 if (this->owner () == 0)
00513 {
00514 this->waiters_.enqueue (caller, -1);
00515 return 0; // success
00516 }
00517 // Does the caller already own it?
00518 if (this->is_owner (caller->client_id ()))
00519 {
00520 // recursive acquisition
00521 caller->nesting_level (1);
00522 return 0; // success
00523 }
00524 else
00525 // Someone owns it. Fail.
00526 {
00527 errno = EWOULDBLOCK;
00528 ACE_RETURN (-1);
00529 }
00530
00531 ACE_NOTREACHED (return -1);
00532 }
|
|
|
Returns ACE_Tokens::MUTEX.
Implements ACE_Tokens. |
|
|
ACE_Mutex_Token used to lock internal data structures.
Definition at line 569 of file Local_Tokens.h. Referenced by dump. |
1.2.14 written by Dimitri van Heesch,
© 1997-2002