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 Member Functions

 ACE_Remote_Token_Proxy (void)
 Null construction.

virtual ~ACE_Remote_Token_Proxy (void)
 Death.

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)
virtual void token_acquired (ACE_TPQ_Entry *)
 Override the default to do nothing.

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

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


Static Public Member Functions

void set_server_address (const ACE_INET_Addr &server_address)

Protected Member Functions

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


Protected Attributes

int ignore_shadow_deadlock_
 If shadows report deadlock, go remote anyway.


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. is not implemented.

Definition at line 48 of file Remote_Tokens.h.


Constructor & Destructor Documentation

ACE_Remote_Token_Proxy::ACE_Remote_Token_Proxy void   ) 
 

Null construction.

Definition at line 102 of file Remote_Tokens.cpp.

References ACE_TRACE.

00103 {
00104   ACE_TRACE ("ACE_Remote_Token_Proxy::ACE_Remote_Token_Proxy");
00105 }

ACE_Remote_Token_Proxy::~ACE_Remote_Token_Proxy void   )  [virtual]
 

Death.

Definition at line 107 of file Remote_Tokens.cpp.

References ACE_TRACE.

00108 {
00109   ACE_TRACE ("ACE_Remote_Token_Proxy::~ACE_Remote_Token_Proxy");
00110 }


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 == problem.

Reimplemented from ACE_Token_Proxy.

Definition at line 187 of file Remote_Tokens.cpp.

References ACE_DEBUG, ACE_ERROR_RETURN, ACE_LIB_TEXT, ACE_RETURN, ACE_TRACE, ACE_Token_Proxy::acquire(), ACE_Token_Proxy::client_id(), EDEADLK, EWOULDBLOCK, ignore_shadow_deadlock_, 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::type(), and ACE_Tokens::type().

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

void ACE_Remote_Token_Proxy::dump void   )  const
 

Dump the state of the class.

Reimplemented from ACE_Token_Proxy.

Reimplemented in ACE_Remote_Mutex, ACE_Remote_RLock, and ACE_Remote_WLock.

Definition at line 393 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().

00394 {
00395 #if defined (ACE_HAS_DUMP)
00396   ACE_TRACE ("ACE_Remote_Token_Proxy::dump");
00397   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00398   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("ACE_Tokens::dump:\n")
00399               ACE_LIB_TEXT (" ignore_shadow_deadlock_ = %d\n"),
00400               ignore_shadow_deadlock_));
00401   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("base:\n")));
00402   ACE_Token_Proxy::dump ();
00403   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00404 #endif /* ACE_HAS_DUMP */
00405 }

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 130 of file Remote_Tokens.cpp.

References ACE_ERROR_RETURN, ACE_LIB_TEXT, ACE_TRACE, and LM_ERROR.

00131 {
00132   ACE_TRACE ("ACE_Remote_Token_Proxy::initiate_connection");
00133   if (token_ == 0)
00134     {
00135       errno = ENOENT;
00136       ACE_ERROR_RETURN ((LM_ERROR,
00137                          ACE_LIB_TEXT ("ACE_Remote_Token_Proxy not open.\n")), -1);
00138     }
00139 
00140   ACE_SOCK_Stream *peer = ACE_Token_Connections::instance ()->get_connection ();
00141   return peer == 0 ? 0 : 1;
00142 }

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

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

Reimplemented from ACE_Token_Proxy.

Definition at line 113 of file Remote_Tokens.cpp.

References ACE_TCHAR, ACE_TRACE, ignore_shadow_deadlock_, and ACE_Token_Proxy::open().

00116 {
00117   ACE_TRACE ("ACE_Remote_Token_Proxy::open");
00118   ignore_shadow_deadlock_ = ignore_deadlock;
00119   return ACE_Token_Proxy::open (name, 0, debug);
00120 }

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 384 of file Remote_Tokens.cpp.

References ACE_DEBUG, ACE_LIB_TEXT, ACE_TRACE, and LM_DEBUG.

00385 {
00386   ACE_TRACE ("ACE_Remote_Token_Proxy::owner_id");
00387   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("owner_id called\n")));
00388   // @@ special operation
00389   return 0;
00390 }

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 == problem.

Reimplemented from ACE_Token_Proxy.

Definition at line 342 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(), request_reply(), ACE_Token_Proxy::type(), and ACE_Tokens::type().

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

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 367 of file Remote_Tokens.cpp.

References ACE_TRACE.

00368 {
00369   ACE_TRACE ("ACE_Remote_Token_Proxy::remove");
00370   return 0;
00371 }

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 followed by , 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 292 of file Remote_Tokens.cpp.

References ACE_DEBUG, ACE_ERROR_RETURN, ACE_LIB_TEXT, ACE_TRACE, ACE_Token_Proxy::client_id(), EWOULDBLOCK, LM_DEBUG, LM_ERROR, ACE_Tokens::make_owner(), ACE_Token_Proxy::name(), ACE_Token_Proxy::release(), ACE_Token_Proxy::renew(), request_reply(), ACE_Token_Request::requeue_position(), ACE_Token_Proxy::type(), and ACE_Tokens::type().

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

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 147 of file Remote_Tokens.cpp.

References ACE_ERROR_RETURN, ACE_LIB_TEXT, ACE_TRACE, ACE_Token_Request::encode(), LM_ERROR, ACE_SOCK_IO::recv(), ACE_SOCK_Stream::send_n(), and ssize_t.

Referenced by acquire(), release(), renew(), and tryacquire().

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

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 123 of file Remote_Tokens.cpp.

References ACE_TRACE.

00124 {
00125   ACE_TRACE ("ACE_Remote_Token_Proxy::set_server_address");
00126   ACE_Token_Connections::instance ()->set_server_address (server_address);
00127 }

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 374 of file Remote_Tokens.cpp.

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

00375 {
00376   ACE_TRACE ("ACE_Remote_Token_Proxy::token_acquired");
00377   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("(%t) %s shadow token %s acquired\n"),
00378               this->client_id (),
00379               this->name ()));
00380   // ACE_Token_Proxy::token_acquired (vp);
00381 }

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 261 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::tryacquire(), ACE_Token_Proxy::type(), and ACE_Tokens::type().

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


Member Data Documentation

int ACE_Remote_Token_Proxy::ignore_shadow_deadlock_ [protected]
 

If shadows report deadlock, go remote anyway.

Definition at line 148 of file Remote_Tokens.h.

Referenced by acquire(), dump(), and open().


The documentation for this class was generated from the following files:
Generated on Thu Nov 9 11:28:16 2006 for ACE by doxygen 1.3.6