Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

ACE_Remote_Token_Proxy Class Reference

Proxy for acquiring, renewing, and releasing a distributed synchronization token. More...

#include <Remote_Tokens.h>

Inheritance diagram for ACE_Remote_Token_Proxy:

Inheritance graph
[legend]
Collaboration diagram for ACE_Remote_Token_Proxy:

Collaboration graph
[legend]
List of all members.

Public Methods

 ACE_Remote_Token_Proxy (void)
 Null construction. More...

virtual ~ACE_Remote_Token_Proxy (void)
 Death. More...

int open (const ACE_TCHAR *name, int ignore_deadlock=0, int debug=0)
int initiate_connection (void)
virtual int acquire (int notify=0, void(*sleep_hook)(void *)=0, ACE_Synch_Options &options=ACE_Synch_Options::synch)
virtual int tryacquire (void(*sleep_hook)(void *)=0)
virtual int renew (int requeue_position=0, ACE_Synch_Options &options=ACE_Synch_Options::synch)
virtual int release (ACE_Synch_Options &options=ACE_Synch_Options::synch)
virtual int remove (ACE_Synch_Options &options=ACE_Synch_Options::synch)
 Become interface compliant for ACE_Guard<>. This has no functionality. More...

virtual void token_acquired (ACE_TPQ_Entry *)
 Override the default to do nothing. More...

virtual const ACE_TCHARowner_id (void)
 The client id of the current token holder. More...

void dump (void) const
 Dump the state of the class. More...


Static Public Methods

void set_server_address (const ACE_INET_Addr &server_address)

Protected Methods

int request_reply (ACE_Token_Request &request, ACE_Synch_Options &options)
 Perform the request and wait for the reply. More...


Protected Attributes

int ignore_shadow_deadlock_
 If shadows report deadlock, go remote anyway. More...


Detailed Description

Proxy for acquiring, renewing, and releasing a distributed synchronization token.

The Remote_Token_Proxy class implements the mechanisms for distributed token operations. It is similar to the ACE_Token_Proxy. = BUGS Distributed sleep_hooks have not been implemented. <owner_id> is not implemented.

Definition at line 45 of file Remote_Tokens.h.


Constructor & Destructor Documentation

ACE_Remote_Token_Proxy::ACE_Remote_Token_Proxy void   
 

Null construction.

Definition at line 95 of file Remote_Tokens.cpp.

References ACE_TRACE.

00096 {
00097   ACE_TRACE ("ACE_Remote_Token_Proxy::ACE_Remote_Token_Proxy");
00098 }

ACE_Remote_Token_Proxy::~ACE_Remote_Token_Proxy void    [virtual]
 

Death.

Definition at line 100 of file Remote_Tokens.cpp.

References ACE_TRACE.

00101 {
00102   ACE_TRACE ("ACE_Remote_Token_Proxy::~ACE_Remote_Token_Proxy");
00103 }


Member Function Documentation

int ACE_Remote_Token_Proxy::acquire int    notify = 0,
void(*    sleep_hook)(void *) = 0,
ACE_Synch_Options   options = ACE_Synch_Options::synch
[virtual]
 

Acquire the distributed token. If notify is specified and the token is already held, the owner is notified. options contains the timeout value for the acquire call. The timer is kept at the token server. Asynchronous operations are not supported. Returns 0 on success, -1 on failure with <errno> == problem.

Reimplemented from ACE_Token_Proxy.

Definition at line 180 of file Remote_Tokens.cpp.

References ACE_DEBUG, ACE_ERROR_RETURN, ACE_LIB_TEXT, ACE_RETURN, ACE_TRACE, ACE_Token_Request::ACQUIRE, ACE_Token_Proxy::acquire, ACE_Synch_Options::asynch, ACE_Token_Proxy::client_id, EDEADLK, EWOULDBLOCK, LM_DEBUG, LM_ERROR, ACE_Tokens::make_owner, ACE_Token_Proxy::name, ACE_Token_Request::notify, ACE_Token_Proxy::release, request_reply, ACE_Token_Proxy::sleep_hook, ACE_Token_Proxy::token_, ACE_Token_Proxy::type, ACE_Tokens::type, and ACE_Token_Proxy::waiter_.

00183 {
00184   ACE_TRACE ("ACE_Remote_Token_Proxy::acquire");
00185 
00186   // First grab the local shadow mutex.
00187   if (ACE_Token_Proxy::acquire (notify,
00188                                 sleep_hook,
00189                                 ACE_Synch_Options::asynch) == -1)
00190     {
00191       // Acquire failed, deal with it...
00192       switch (errno)
00193         {
00194         case EWOULDBLOCK :
00195           // Whoah, we detected wouldblock via the shadow mutex!
00196           if (debug_)
00197             ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("(%t) shadow: acquire will block, owner is %s\n"),
00198                         this->token_->owner_id ()));
00199           // No error, but would block,
00200           break;
00201 
00202         case EDEADLK :
00203           if (debug_)
00204             ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("(%t) shadow: deadlock detected\n")));
00205 
00206           if (ignore_shadow_deadlock_)
00207             break;
00208           else
00209             {
00210               errno = EDEADLK;
00211               ACE_RETURN (-1);
00212             }
00213 
00214         default :
00215           ACE_ERROR_RETURN ((LM_ERROR,
00216                              ACE_LIB_TEXT ("(%t) %p shadow acquire failed\n"),
00217                              ACE_LIB_TEXT ("ACE_Remote_Token_Proxy")),
00218                             -1);
00219         }
00220     }
00221 
00222   ACE_Token_Request request (token_->type (),
00223                              this->type (),
00224                              ACE_Token_Request::ACQUIRE,
00225                              this->name (),
00226                              this->client_id (),
00227                              options);
00228 
00229   request.notify (notify);
00230 
00231   int result = this->request_reply (request, options);
00232 
00233   if (result == -1)
00234     {
00235       // Update the local shadow copy.
00236       ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("error on remote acquire, releasing shadow mutex.\n")));
00237       ACE_Token_Proxy::release ();
00238     }
00239   else
00240     {
00241       ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("(%t) acquired %s remotely.\n"), this->name ()));
00242       // Our shadow call may have failed.  However, it's still a race
00243       // to the remote server.  If we beat the client which holds the
00244       // local token, we need to fix things locally to reflect the
00245       // actual ownership.  All that should happen is that our waiter
00246       // is moved to the front of the waiter list.
00247       token_->make_owner (waiter_);
00248     }
00249 
00250   return result;
00251 }

void ACE_Remote_Token_Proxy::dump void    const
 

Dump the state of the class.

Reimplemented from ACE_Token_Proxy.

Reimplemented in ACE_Remote_Mutex.

Definition at line 386 of file Remote_Tokens.cpp.

References ACE_BEGIN_DUMP, ACE_DEBUG, ACE_END_DUMP, ACE_LIB_TEXT, ACE_TRACE, ACE_Token_Proxy::dump, ignore_shadow_deadlock_, and LM_DEBUG.

Referenced by ACE_Remote_WLock::dump, ACE_Remote_RLock::dump, and ACE_Remote_Mutex::dump.

00387 {
00388   ACE_TRACE ("ACE_Remote_Token_Proxy::dump");
00389   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00390   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("ACE_Tokens::dump:\n")
00391               ACE_LIB_TEXT (" ignore_shadow_deadlock_ = %d\n"),
00392               ignore_shadow_deadlock_));
00393   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("base:\n")));
00394   ACE_Token_Proxy::dump ();
00395   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00396 }

int ACE_Remote_Token_Proxy::initiate_connection void   
 

Open a connection with the token server. This only need be used when the user wishes to explicitly open a connection to check if the server exists. Connections are stored in the ACE_Token_Connections singleton as thread-specific data. That is, every thread has only one connection that is used for all remote tokens.

Definition at line 123 of file Remote_Tokens.cpp.

References ACE_ERROR_RETURN, ACE_LIB_TEXT, ACE_TRACE, ACE_Singleton::instance, LM_ERROR, and ACE_Token_Proxy::token_.

00124 {
00125   ACE_TRACE ("ACE_Remote_Token_Proxy::initiate_connection");
00126   if (token_ == 0)
00127     {
00128       errno = ENOENT;
00129       ACE_ERROR_RETURN ((LM_ERROR,
00130                          ACE_LIB_TEXT ("ACE_Remote_Token_Proxy not open.\n")), -1);
00131     }
00132 
00133   ACE_SOCK_Stream *peer = ACE_Token_Connections::instance ()->get_connection ();
00134   return peer == 0 ? 0 : 1;
00135 }

int ACE_Remote_Token_Proxy::open const ACE_TCHAR   name,
int    ignore_deadlock = 0,
int    debug = 0
[virtual]
 

Same as Token_Proxy. <name> is the string uniquely identifying the token. <ignore_deadlock> can be 1 to disable deadlock notifications. <debug> prints debug messages.

Reimplemented from ACE_Token_Proxy.

Definition at line 106 of file Remote_Tokens.cpp.

References ACE_TCHAR, ACE_TRACE, ignore_shadow_deadlock_, ACE_Token_Proxy::name, and ACE_Token_Proxy::open.

00109 {
00110   ACE_TRACE ("ACE_Remote_Token_Proxy::open");
00111   ignore_shadow_deadlock_ = ignore_deadlock;
00112   return ACE_Token_Proxy::open (name, 0, debug);
00113 }

const ACE_TCHAR * ACE_Remote_Token_Proxy::owner_id void    [virtual]
 

The client id of the current token holder.

Reimplemented from ACE_Token_Proxy.

Definition at line 377 of file Remote_Tokens.cpp.

References ACE_DEBUG, ACE_LIB_TEXT, ACE_TRACE, and LM_DEBUG.

00378 {
00379   ACE_TRACE ("ACE_Remote_Token_Proxy::owner_id");
00380   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("owner_id called\n")));
00381   // @@ special operation
00382   return 0;
00383 }

int ACE_Remote_Token_Proxy::release ACE_Synch_Options   options = ACE_Synch_Options::synch [virtual]
 

Release the distributed token. Similar to ACE_Local_Mutex, if the caller is not the owner, it is removed from the waiter list (if applicable.) Returns 0 on success, -1 on failure with <errno> == problem.

Reimplemented from ACE_Token_Proxy.

Definition at line 335 of file Remote_Tokens.cpp.

References ACE_DEBUG, ACE_ERROR, ACE_LIB_TEXT, ACE_TRACE, ACE_Token_Proxy::client_id, LM_DEBUG, LM_ERROR, ACE_Token_Proxy::name, ACE_Token_Proxy::release, ACE_Token_Request::RELEASE, request_reply, ACE_Token_Proxy::token_, ACE_Token_Proxy::type, and ACE_Tokens::type.

00336 {
00337   ACE_TRACE ("ACE_Remote_Token_Proxy::release");
00338 
00339   ACE_Token_Request request (token_->type (),
00340                              this->type (),
00341                              ACE_Token_Request::RELEASE,
00342                              this->name (),
00343                              this->client_id (),
00344                              options);
00345 
00346   int result = this->request_reply (request, options);
00347   if (result == 0)
00348     ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("(%t) released %s remotely.\n"), this->name ()));
00349 
00350   // whether success or failure, we're going to release the shadow.
00351   // If race conditions exist such that we are no longer the owner,
00352   // this release will perform a remove.
00353   if (ACE_Token_Proxy::release () == -1)
00354     ACE_ERROR ((LM_ERROR, ACE_LIB_TEXT ("(%t) shadow: release failed\n")));
00355 
00356   return result;
00357 }

int ACE_Remote_Token_Proxy::remove ACE_Synch_Options   options = ACE_Synch_Options::synch [virtual]
 

Become interface compliant for ACE_Guard<>. This has no functionality.

Reimplemented from ACE_Token_Proxy.

Definition at line 360 of file Remote_Tokens.cpp.

References ACE_TRACE.

00361 {
00362   ACE_TRACE ("ACE_Remote_Token_Proxy::remove");
00363   return 0;
00364 }

int ACE_Remote_Token_Proxy::renew int    requeue_position = 0,
ACE_Synch_Options   options = ACE_Synch_Options::synch
[virtual]
 

Renew the token by offering to release it if there are any other waiters, otherwise get the token back immediately. This renew has the same semantics as ACE_Local_Mutex release. It is semantically equivalent to <release> followed by <acquire>, but it is faster. options contains the timeout value used if renew blocks. As with acquire, the timer is maintained at the token server. If there are waiters and requeue_position == -1, the caller is queued at the rear of the waiter list. Otherwise, requeue_position specifies the number of waiters to "let by" before reacquiring the token (effectively, the position in the waiter list.)

Reimplemented from ACE_Token_Proxy.

Definition at line 285 of file Remote_Tokens.cpp.

References ACE_DEBUG, ACE_ERROR_RETURN, ACE_LIB_TEXT, ACE_TRACE, ACE_Synch_Options::asynch, ACE_Token_Proxy::client_id, EWOULDBLOCK, LM_DEBUG, LM_ERROR, ACE_Tokens::make_owner, ACE_Token_Proxy::name, ACE_Token_Proxy::release, ACE_Token_Request::RENEW, ACE_Token_Proxy::renew, request_reply, ACE_Token_Request::requeue_position, ACE_Token_Proxy::token_, ACE_Token_Proxy::type, ACE_Tokens::type, and ACE_Token_Proxy::waiter_.

00287 {
00288   ACE_TRACE ("ACE_Remote_Token_Proxy::renew");
00289 
00290   if (ACE_Token_Proxy::renew (requeue_position,
00291                               ACE_Synch_Options::asynch) == -1)
00292     {
00293       // Check for error.
00294       if (errno != EWOULDBLOCK)
00295         return -1;
00296       else if (debug_)
00297         ACE_DEBUG ((LM_DEBUG,
00298                     ACE_LIB_TEXT ("(%t) shadow: renew would block. owner %s.\n"),
00299                     this->token_->owner_id ()));
00300     }
00301 
00302   ACE_Token_Request request (token_->type (),
00303                              this->type (),
00304                              ACE_Token_Request::RENEW,
00305                              this->name (),
00306                              this->client_id (),
00307                              options);
00308 
00309   request.requeue_position (requeue_position);
00310 
00311   int result = this->request_reply (request, options);
00312 
00313   if (result == -1)
00314     {
00315       {
00316         // Save/restore errno.
00317         ACE_Errno_Guard error (errno);
00318         ACE_Token_Proxy::release ();
00319       }
00320       ACE_ERROR_RETURN ((LM_ERROR,
00321                          ACE_LIB_TEXT ("%p error on remote renew, releasing shadow mutex.\n"),
00322                          ACE_LIB_TEXT ("ACE_Remote_Token_Proxy")), -1);
00323     }
00324   else
00325     {
00326       if (debug_)
00327         ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("(%t) renewed %s remotely.\n"), this->name ()));
00328       // Make sure that the local shadow reflects our new ownership.
00329       token_->make_owner (waiter_);
00330       return result;
00331     }
00332 }

int ACE_Remote_Token_Proxy::request_reply ACE_Token_Request   request,
ACE_Synch_Options   options
[protected]
 

Perform the request and wait for the reply.

Definition at line 140 of file Remote_Tokens.cpp.

References ACE_ERROR_RETURN, ACE_LIB_TEXT, ACE_RETURN, ACE_TRACE, ACE_Token_Reply::decode, ACE_Token_Request::encode, ACE_Token_Reply::errnum, ACE_Singleton::instance, LM_ERROR, ACE_SOCK_IO::recv, ACE_SOCK_Stream::send_n, and ssize_t.

Referenced by acquire, release, renew, and tryacquire.

00142 {
00143   ACE_TRACE ("ACE_Remote_Token_Proxy::request_reply");
00144   void *buffer;
00145   ssize_t length;
00146 
00147   if ((length = request.encode (buffer)) == -1)
00148     ACE_ERROR_RETURN ((LM_ERROR,  ACE_LIB_TEXT ("%p\n"),  ACE_LIB_TEXT ("encode failed")), -1);
00149 
00150   ACE_SOCK_Stream *peer = ACE_Token_Connections::instance ()->get_connection ();
00151 
00152   if (peer == 0)
00153     return -1;
00154 
00155   // Transmit request via a blocking send.
00156 
00157   if (peer->send_n (buffer, length) != length)
00158     ACE_ERROR_RETURN ((LM_ERROR,  ACE_LIB_TEXT ("%p\n"),  ACE_LIB_TEXT ("send_n failed")), -1);
00159   else
00160     {
00161       ACE_Token_Reply reply;
00162 
00163       // Receive reply via blocking read.
00164 
00165       if (peer->recv (&reply, sizeof reply) != sizeof reply)
00166         ACE_ERROR_RETURN ((LM_ERROR,  ACE_LIB_TEXT ("%p\n"),  ACE_LIB_TEXT ("recv failed")), -1);
00167 
00168       if (reply.decode () == -1)
00169         ACE_ERROR_RETURN ((LM_ERROR,  ACE_LIB_TEXT ("%p\n"),  ACE_LIB_TEXT ("decode failed")), -1);
00170 
00171       errno = int (reply.errnum ());
00172       if (errno != 0)
00173         ACE_RETURN (-1);
00174       else
00175         return 0;
00176     }
00177 }

void ACE_Remote_Token_Proxy::set_server_address const ACE_INET_Addr   server_address [static]
 

Sets the server address for all instances of ACE_Remote_Token_Proxy If this isn't called, the environment variable TOKEN_SERVER is checked for the server address. If that is not specified, all ACE_Remote_** operations will fail.

Definition at line 116 of file Remote_Tokens.cpp.

References ACE_TRACE, and ACE_Singleton::instance.

00117 {
00118   ACE_TRACE ("ACE_Remote_Token_Proxy::set_server_address");
00119   ACE_Token_Connections::instance ()->set_server_address (server_address);
00120 }

void ACE_Remote_Token_Proxy::token_acquired ACE_TPQ_Entry   [virtual]
 

Override the default to do nothing.

Reimplemented from ACE_Token_Proxy.

Definition at line 367 of file Remote_Tokens.cpp.

References ACE_DEBUG, ACE_LIB_TEXT, ACE_TRACE, LM_DEBUG, and ACE_Token_Proxy::name.

00368 {
00369   ACE_TRACE ("ACE_Remote_Token_Proxy::token_acquired");
00370   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("(%t) shadow token %s acquired\n"),
00371               this->client_id (),
00372               this->name ()));
00373   // ACE_Token_Proxy::token_acquired (vp);
00374 }

int ACE_Remote_Token_Proxy::tryacquire void(*    sleep_hook)(void *) = 0 [virtual]
 

Try to acquire the distributed token. If the token is already held, the call returns without queueing the caller as a waiter. Returns 0 on success (the token was acquired), and -1 with EWOULDBLOCK if the token was already held.

Reimplemented from ACE_Token_Proxy.

Definition at line 254 of file Remote_Tokens.cpp.

References ACE_DEBUG, ACE_LIB_TEXT, ACE_TRACE, ACE_Token_Proxy::client_id, LM_DEBUG, ACE_Token_Proxy::name, request_reply, ACE_Token_Proxy::sleep_hook, ACE_Synch_Options::synch, ACE_Token_Proxy::token_, ACE_Token_Request::TRY_ACQUIRE, ACE_Token_Proxy::tryacquire, ACE_Token_Proxy::type, and ACE_Tokens::type.

00255 {
00256   ACE_TRACE ("ACE_Remote_Token_Proxy::tryacquire");
00257 
00258   // If we can detect locally that the tryacquire will fail, there is
00259   // no need to go remote.
00260   if (ACE_Token_Proxy::tryacquire (sleep_hook) == -1)
00261     {
00262       if (debug_)
00263         {
00264           // Save/restore errno.
00265           ACE_Errno_Guard error (errno);
00266           ACE_DEBUG ((LM_DEBUG,
00267                       ACE_LIB_TEXT ("shadow try acquire failed\n")));
00268         }
00269 
00270       return -1;
00271     }
00272 
00273   ACE_Token_Request request (token_->type (),
00274                              this->type (),
00275                              ACE_Token_Request::TRY_ACQUIRE,
00276                              this->name (),
00277                              this->client_id (),
00278                              ACE_Synch_Options::synch);
00279 
00280   return this->request_reply (request,
00281                               ACE_Synch_Options::synch);
00282 }


Member Data Documentation

int ACE_Remote_Token_Proxy::ignore_shadow_deadlock_ [protected]
 

If shadows report deadlock, go remote anyway.

Definition at line 145 of file Remote_Tokens.h.

Referenced by dump, and open.


The documentation for this class was generated from the following files:
Generated on Mon Jun 16 12:55:21 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002