#include <Remote_Tokens.h>
Inheritance diagram for ACE_Remote_Token_Proxy:


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_TCHAR * | owner_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... | |
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.
|
|
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 }
|
|
|
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 }
|
|
||||||||||||||||
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
||||||||||||||||
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
||||||||||||
|
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 }
|
|
||||||||||||
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
If shadows report deadlock, go remote anyway.
Definition at line 145 of file Remote_Tokens.h. |
1.2.14 written by Dimitri van Heesch,
© 1997-2002