Remote_Tokens.cpp

Go to the documentation of this file.
00001 // Remote_Tokens.cpp,v 4.26 2006/05/24 17:43:50 schmidt Exp
00002 
00003 #include "ace/Remote_Tokens.h"
00004 
00005 #if defined (ACE_HAS_TOKENS_LIBRARY)
00006 
00007 #include "ace/Singleton.h"
00008 
00009 #if !defined (__ACE_INLINE__)
00010 #include "ace/Remote_Tokens.inl"
00011 #endif /* __ACE_INLINE__ */
00012 
00013 
00014 ACE_RCSID (ace,
00015            Remote_Tokens,
00016            "Remote_Tokens.cpp,v 4.26 2006/05/24 17:43:50 schmidt Exp")
00017 
00018 
00019 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00020 #define ACE_TSS_CONNECTION_MUTEX ACE_Thread_Mutex
00021 #else
00022 #define ACE_TSS_CONNECTION_MUTEX ACE_Null_Mutex
00023 #endif /* ACE_MT_SAFE */
00024 
00025 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00026 
00027 // Make a typedef to simplify access to the Singleton below.
00028 typedef ACE_Singleton<ACE_TSS_Connection, ACE_TSS_CONNECTION_MUTEX> ACE_Token_Connections;
00029 
00030 // Initialize the statics from ACE_TSS_Connection;
00031 ACE_INET_Addr ACE_TSS_Connection::server_address_;
00032 
00033 // ************************************************************
00034 
00035 void
00036 ACE_TSS_Connection::set_server_address (const ACE_INET_Addr &server_address)
00037 {
00038   ACE_TRACE ("ACE_TSS_Connection::set_server_address");
00039   server_address_ = server_address;
00040 }
00041 
00042 // Necessary to make some compilers work...
00043 ACE_TSS_Connection::ACE_TSS_Connection (void)
00044 {
00045   ACE_TRACE ("ACE_TSS_Connection::ACE_TSS_Connection");
00046 }
00047 
00048 ACE_TSS_Connection::~ACE_TSS_Connection (void)
00049 {
00050   ACE_TRACE ("ACE_TSS_Connection::~ACE_TSS_Connection");
00051 }
00052 
00053 ACE_SOCK_Stream *
00054 ACE_TSS_Connection::get_connection (void)
00055 {
00056   return ACE_TSS<ACE_SOCK_Stream>::operator-> ();
00057 }
00058 
00059 ACE_SOCK_Stream *
00060 ACE_TSS_Connection::make_TSS_TYPE (void) const
00061 {
00062   ACE_TRACE ("ACE_TSS_Connection::make_TSS_TYPE");
00063 
00064   ACE_SOCK_Connector connector;
00065   ACE_SOCK_Stream *stream = 0;
00066 
00067   ACE_NEW_RETURN (stream,
00068                   ACE_SOCK_Stream,
00069                   0);
00070 
00071   if (connector.connect (*stream, server_address_) == -1)
00072     {
00073       delete stream;
00074       errno = ECONNREFUSED;
00075       return 0;
00076     }
00077 
00078   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("ACE_TSS_Connection new connection\n")));
00079   return stream;
00080 }
00081 
00082 ACE_TSS_Connection::operator ACE_SOCK_Stream *(void)
00083 {
00084   return this->get_connection ();
00085 }
00086 
00087 void
00088 ACE_TSS_Connection::dump (void) const
00089 {
00090 #if defined (ACE_HAS_DUMP)
00091   ACE_TRACE ("ACE_TSS_Connection::dump");
00092   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00093   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("ACE_TSS_Connection::dump:\n")));
00094   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("server_address_\n")));
00095   server_address_.dump ();
00096   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("base:\n")));
00097   ACE_TSS<ACE_SOCK_Stream>::dump ();
00098   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00099 #endif /* ACE_HAS_DUMP */
00100 }
00101 
00102 ACE_Remote_Token_Proxy::ACE_Remote_Token_Proxy (void)
00103 {
00104   ACE_TRACE ("ACE_Remote_Token_Proxy::ACE_Remote_Token_Proxy");
00105 }
00106 
00107 ACE_Remote_Token_Proxy::~ACE_Remote_Token_Proxy (void)
00108 {
00109   ACE_TRACE ("ACE_Remote_Token_Proxy::~ACE_Remote_Token_Proxy");
00110 }
00111 
00112 int
00113 ACE_Remote_Token_Proxy::open (const ACE_TCHAR *name,
00114                               int ignore_deadlock,
00115                               int debug)
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 }
00121 
00122 void
00123 ACE_Remote_Token_Proxy::set_server_address (const ACE_INET_Addr &server_address)
00124 {
00125   ACE_TRACE ("ACE_Remote_Token_Proxy::set_server_address");
00126   ACE_Token_Connections::instance ()->set_server_address (server_address);
00127 }
00128 
00129 int
00130 ACE_Remote_Token_Proxy::initiate_connection (void)
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 }
00143 
00144 // Do the work of sending a request and getting a reply.
00145 
00146 int
00147 ACE_Remote_Token_Proxy::request_reply (ACE_Token_Request &request,
00148                                        ACE_Synch_Options &)
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 }
00185 
00186 int
00187 ACE_Remote_Token_Proxy::acquire (int notify,
00188                                  void (*sleep_hook)(void *),
00189                                  ACE_Synch_Options &options)
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 }
00259 
00260 int
00261 ACE_Remote_Token_Proxy::tryacquire (void (*sleep_hook)(void *))
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 }
00290 
00291 int
00292 ACE_Remote_Token_Proxy::renew (int requeue_position,
00293                                ACE_Synch_Options &options)
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 }
00340 
00341 int
00342 ACE_Remote_Token_Proxy::release (ACE_Synch_Options &options)
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 }
00365 
00366 int
00367 ACE_Remote_Token_Proxy::remove (ACE_Synch_Options &)
00368 {
00369   ACE_TRACE ("ACE_Remote_Token_Proxy::remove");
00370   return 0;
00371 }
00372 
00373 void
00374 ACE_Remote_Token_Proxy::token_acquired (ACE_TPQ_Entry *)
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 }
00382 
00383 const ACE_TCHAR*
00384 ACE_Remote_Token_Proxy::owner_id (void)
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 }
00391 
00392 void
00393 ACE_Remote_Token_Proxy::dump (void) const
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 }
00406 
00407 ACE_Token_Proxy *
00408 ACE_Remote_Mutex::clone (void) const
00409 {
00410   ACE_Token_Proxy *temp;
00411   ACE_NEW_RETURN (temp,
00412                   ACE_Remote_Mutex (this->name (),
00413                                                       ignore_deadlock_,
00414                                                       debug_),
00415                   0);
00416   return temp;
00417 }
00418 
00419 ACE_Tokens *
00420 ACE_Remote_Mutex::create_token (const ACE_TCHAR *name)
00421 {
00422   ACE_Tokens *temp;
00423   ACE_NEW_RETURN (temp,
00424                   ACE_Mutex_Token (name),
00425                   0);
00426   return temp;
00427 }
00428 
00429 void
00430 ACE_Remote_Mutex::dump (void) const
00431 {
00432 #if defined (ACE_HAS_DUMP)
00433   ACE_TRACE ("ACE_Remote_Mutex::dump");
00434   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00435   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("ACE_Remote_Mutex::dump:\n")));
00436   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("base:\n")));
00437   ACE_Remote_Token_Proxy::dump ();
00438   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00439 #endif /* ACE_HAS_DUMP */
00440 }
00441 
00442 ACE_Tokens *
00443 ACE_Remote_RLock::create_token (const ACE_TCHAR *name)
00444 {
00445   ACE_Tokens *temp = 0;
00446   ACE_NEW_RETURN (temp,
00447                   ACE_RW_Token (name),
00448                   0);
00449   return temp;
00450 }
00451 
00452 int
00453 ACE_Remote_RLock::type (void) const
00454 {
00455   return ACE_RW_Token::READER;
00456 }
00457 
00458 ACE_Token_Proxy *
00459 ACE_Remote_RLock::clone (void) const
00460 {
00461   ACE_Token_Proxy *temp = 0;
00462   ACE_NEW_RETURN (temp,
00463                   ACE_Remote_RLock (this->name (),
00464                                     ignore_deadlock_,
00465                                     debug_),
00466                   0);
00467   return temp;
00468 }
00469 
00470 void
00471 ACE_Remote_RLock::dump (void) const
00472 {
00473 #if defined (ACE_HAS_DUMP)
00474   ACE_TRACE ("ACE_Remote_RLock::dump");
00475   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00476   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("ACE_Remote_RLock::dump:\n")));
00477   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("base:\n")));
00478   ACE_Remote_Token_Proxy::dump ();
00479   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00480 #endif /* ACE_HAS_DUMP */
00481 }
00482 
00483 
00484 ACE_Tokens *
00485 ACE_Remote_WLock::create_token (const ACE_TCHAR *name)
00486 {
00487   ACE_Tokens *temp = 0;
00488   ACE_NEW_RETURN (temp,
00489                   ACE_RW_Token (name),
00490                   0);
00491   return temp;
00492 }
00493 
00494 int
00495 ACE_Remote_WLock::type (void) const
00496 {
00497   return ACE_RW_Token::WRITER;
00498 }
00499 
00500 ACE_Token_Proxy *
00501 ACE_Remote_WLock::clone (void) const
00502 {
00503   ACE_Token_Proxy *temp = 0;
00504   ACE_NEW_RETURN (temp,
00505                   ACE_Remote_WLock (this->name (),
00506                                     ignore_deadlock_,
00507                                     debug_),
00508                   0);
00509   return temp;
00510 }
00511 
00512 void
00513 ACE_Remote_WLock::dump (void) const
00514 {
00515 #if defined (ACE_HAS_DUMP)
00516   ACE_TRACE ("ACE_Remote_WLock::dump");
00517   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00518   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("ACE_Remote_WLock::dump:\n")));
00519   ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("base:\n")));
00520   ACE_Remote_Token_Proxy::dump ();
00521   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00522 #endif /* ACE_HAS_DUMP */
00523 }
00524 
00525 ACE_END_VERSIONED_NAMESPACE_DECL
00526 
00527 #endif /* ACE_HAS_TOKENS_LIBRARY */

Generated on Thu Nov 9 09:42:01 2006 for ACE by doxygen 1.3.6