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

Remote_Tokens.cpp

Go to the documentation of this file.
00001 #include "ace_pch.h"
00002 // Remote_Tokens.cpp
00003 // $Id: Remote_Tokens.cpp,v 1.1.1.3.40.1 2003/03/13 19:44:22 chad Exp $
00004 
00005 #include "ace/Remote_Tokens.h"
00006 #include "ace/Singleton.h"
00007 
00008 #if !defined (__ACE_INLINE__)
00009 #include "ace/Remote_Tokens.i"
00010 #endif /* __ACE_INLINE__ */
00011 
00012 #if defined (ACE_HAS_TOKENS_LIBRARY)
00013 
00014 ACE_RCSID(ace, Remote_Tokens, "$Id: Remote_Tokens.cpp,v 1.1.1.3.40.1 2003/03/13 19:44:22 chad Exp $")
00015 
00016 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00017 #define ACE_TSS_CONNECTION_MUTEX ACE_Thread_Mutex
00018 #else
00019 #define ACE_TSS_CONNECTION_MUTEX ACE_Null_Mutex
00020 #endif /* ACE_MT_SAFE */
00021 
00022 // Make a typedef to simplify access to the Singleton below.
00023 typedef ACE_Singleton<ACE_TSS_Connection, ACE_TSS_CONNECTION_MUTEX> ACE_Token_Connections;
00024 
00025 // Initialize the statics from ACE_TSS_Connection;
00026 ACE_INET_Addr ACE_TSS_Connection::server_address_;
00027 
00028 // ************************************************************
00029 
00030 void
00031 ACE_TSS_Connection::set_server_address (const ACE_INET_Addr &server_address)
00032 {
00033   ACE_TRACE ("ACE_TSS_Connection::set_server_address");
00034   server_address_ = server_address;
00035 }
00036 
00037 // Necessary to make some compilers work...
00038 ACE_TSS_Connection::ACE_TSS_Connection (void)
00039 {
00040   ACE_TRACE ("ACE_TSS_Connection::ACE_TSS_Connection");
00041 }
00042 
00043 ACE_TSS_Connection::~ACE_TSS_Connection (void)
00044 {
00045   ACE_TRACE ("ACE_TSS_Connection::~ACE_TSS_Connection");
00046 }
00047 
00048 ACE_SOCK_Stream *
00049 ACE_TSS_Connection::get_connection (void)
00050 {
00051   return ACE_TSS<ACE_SOCK_Stream>::operator-> ();
00052 }
00053 
00054 ACE_SOCK_Stream *
00055 ACE_TSS_Connection::make_TSS_TYPE (void) const
00056 {
00057   ACE_TRACE ("ACE_TSS_Connection::make_TSS_TYPE");
00058 
00059   ACE_SOCK_Connector connector;
00060   ACE_SOCK_Stream *stream = 0;
00061 
00062   ACE_NEW_RETURN (stream,
00063                   ACE_SOCK_Stream,
00064                   0);
00065 
00066   if (connector.connect (*stream, server_address_) == -1)
00067     {
00068       delete stream;
00069       errno = ECONNREFUSED;
00070       return 0;
00071     }
00072 
00073   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("ACE_TSS_Connection new connection\n")));
00074   return stream;
00075 }
00076 
00077 ACE_TSS_Connection::operator ACE_SOCK_Stream *(void)
00078 {
00079   return this->get_connection ();
00080 }
00081 
00082 void
00083 ACE_TSS_Connection::dump (void) const
00084 {
00085   ACE_TRACE ("ACE_TSS_Connection::dump");
00086   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00087   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("ACE_TSS_Connection::dump:\n")));
00088   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("server_address_\n")));
00089   server_address_.dump ();
00090   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("base:\n")));
00091   ACE_TSS<ACE_SOCK_Stream>::dump ();
00092   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00093 }
00094 
00095 ACE_Remote_Token_Proxy::ACE_Remote_Token_Proxy (void)
00096 {
00097   ACE_TRACE ("ACE_Remote_Token_Proxy::ACE_Remote_Token_Proxy");
00098 }
00099 
00100 ACE_Remote_Token_Proxy::~ACE_Remote_Token_Proxy (void)
00101 {
00102   ACE_TRACE ("ACE_Remote_Token_Proxy::~ACE_Remote_Token_Proxy");
00103 }
00104 
00105 int
00106 ACE_Remote_Token_Proxy::open (const ACE_TCHAR *name,
00107                               int ignore_deadlock,
00108                               int debug)
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 }
00114 
00115 void
00116 ACE_Remote_Token_Proxy::set_server_address (const ACE_INET_Addr &server_address)
00117 {
00118   ACE_TRACE ("ACE_Remote_Token_Proxy::set_server_address");
00119   ACE_Token_Connections::instance ()->set_server_address (server_address);
00120 }
00121 
00122 int
00123 ACE_Remote_Token_Proxy::initiate_connection (void)
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 }
00136 
00137 // Do the work of sending a request and getting a reply.
00138 
00139 int
00140 ACE_Remote_Token_Proxy::request_reply (ACE_Token_Request &request,
00141                                        ACE_Synch_Options &)
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 }
00178 
00179 int
00180 ACE_Remote_Token_Proxy::acquire (int notify,
00181                                  void (*sleep_hook)(void *),
00182                                  ACE_Synch_Options &options)
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 }
00252 
00253 int
00254 ACE_Remote_Token_Proxy::tryacquire (void (*sleep_hook)(void *))
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 }
00283 
00284 int
00285 ACE_Remote_Token_Proxy::renew (int requeue_position,
00286                                ACE_Synch_Options &options)
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 }
00333 
00334 int
00335 ACE_Remote_Token_Proxy::release (ACE_Synch_Options &options)
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 }
00358 
00359 int
00360 ACE_Remote_Token_Proxy::remove (ACE_Synch_Options &)
00361 {
00362   ACE_TRACE ("ACE_Remote_Token_Proxy::remove");
00363   return 0;
00364 }
00365 
00366 void
00367 ACE_Remote_Token_Proxy::token_acquired (ACE_TPQ_Entry *)
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 }
00375 
00376 const ACE_TCHAR*
00377 ACE_Remote_Token_Proxy::owner_id (void)
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 }
00384 
00385 void
00386 ACE_Remote_Token_Proxy::dump (void) const
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 }
00397 
00398 void
00399 ACE_Remote_Mutex::dump (void) const
00400 {
00401   ACE_TRACE ("ACE_Remote_Mutex::dump");
00402   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00403   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("ACE_Remote_Mutex::dump:\n")));
00404   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("base:\n")));
00405   ACE_Remote_Token_Proxy::dump ();
00406   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00407 }
00408 
00409 void
00410 ACE_Remote_RLock::dump (void) const
00411 {
00412   ACE_TRACE ("ACE_Remote_RLock::dump");
00413   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00414   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("ACE_Remote_RLock::dump:\n")));
00415   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("base:\n")));
00416   ACE_Remote_Token_Proxy::dump ();
00417   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00418 }
00419 
00420 void
00421 ACE_Remote_WLock::dump (void) const
00422 {
00423   ACE_TRACE ("ACE_Remote_WLock::dump");
00424   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00425   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("ACE_Remote_WLock::dump:\n")));
00426   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("base:\n")));
00427   ACE_Remote_Token_Proxy::dump ();
00428   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00429 }
00430 
00431 #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
00432 template class ACE_TSS <ACE_SOCK_Stream>;
00433 template class ACE_Singleton <ACE_TSS_Connection, ACE_TSS_CONNECTION_MUTEX>;
00434 #elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
00435 #pragma instantiate ACE_TSS <ACE_SOCK_Stream>
00436 #pragma instantiate ACE_Singleton <ACE_TSS_Connection, ACE_TSS_CONNECTION_MUTEX>
00437 #endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
00438 
00439 #endif /* ACE_HAS_TOKENS_LIBRARY */

Generated on Mon Jun 16 11:21:05 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002