Document return values
[ACE_TAO.git] / ACE / ace / Remote_Tokens.cpp
blob315b464f0bf9b8b7eccde620286feccac80f77e4
1 #include "ace/Remote_Tokens.h"
3 #if defined (ACE_HAS_TOKENS_LIBRARY)
5 #include "ace/Singleton.h"
7 #if !defined (__ACE_INLINE__)
8 #include "ace/Remote_Tokens.inl"
9 #endif /* __ACE_INLINE__ */
11 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
12 #define ACE_TSS_CONNECTION_MUTEX ACE_Thread_Mutex
13 #else
14 #define ACE_TSS_CONNECTION_MUTEX ACE_Null_Mutex
15 #endif /* ACE_MT_SAFE */
17 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
19 // Make a typedef to simplify access to the Singleton below.
20 typedef ACE_Singleton<ACE_TSS_Connection, ACE_TSS_CONNECTION_MUTEX> ACE_Token_Connections;
22 // Initialize the statics from ACE_TSS_Connection;
23 ACE_INET_Addr ACE_TSS_Connection::server_address_;
25 // ************************************************************
27 void
28 ACE_TSS_Connection::set_server_address (const ACE_INET_Addr &server_address)
30 ACE_TRACE ("ACE_TSS_Connection::set_server_address");
31 server_address_ = server_address;
34 // Necessary to make some compilers work...
35 ACE_TSS_Connection::ACE_TSS_Connection ()
37 ACE_TRACE ("ACE_TSS_Connection::ACE_TSS_Connection");
40 ACE_TSS_Connection::~ACE_TSS_Connection ()
42 ACE_TRACE ("ACE_TSS_Connection::~ACE_TSS_Connection");
45 ACE_SOCK_Stream *
46 ACE_TSS_Connection::get_connection ()
48 return ACE_TSS<ACE_SOCK_Stream>::operator-> ();
51 ACE_SOCK_Stream *
52 ACE_TSS_Connection::make_TSS_TYPE () const
54 ACE_TRACE ("ACE_TSS_Connection::make_TSS_TYPE");
56 ACE_SOCK_Connector connector;
57 ACE_SOCK_Stream *stream = 0;
59 ACE_NEW_RETURN (stream,
60 ACE_SOCK_Stream,
61 0);
63 if (connector.connect (*stream, server_address_) == -1)
65 delete stream;
66 errno = ECONNREFUSED;
67 return 0;
70 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_TSS_Connection new connection\n")));
71 return stream;
74 ACE_TSS_Connection::operator ACE_SOCK_Stream *()
76 return this->get_connection ();
79 void
80 ACE_TSS_Connection::dump () const
82 #if defined (ACE_HAS_DUMP)
83 ACE_TRACE ("ACE_TSS_Connection::dump");
84 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
85 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_TSS_Connection::dump:\n")));
86 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("server_address_\n")));
87 server_address_.dump ();
88 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("base:\n")));
89 ACE_TSS<ACE_SOCK_Stream>::dump ();
90 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
91 #endif /* ACE_HAS_DUMP */
94 ACE_Remote_Token_Proxy::ACE_Remote_Token_Proxy ()
96 ACE_TRACE ("ACE_Remote_Token_Proxy::ACE_Remote_Token_Proxy");
99 ACE_Remote_Token_Proxy::~ACE_Remote_Token_Proxy ()
101 ACE_TRACE ("ACE_Remote_Token_Proxy::~ACE_Remote_Token_Proxy");
105 ACE_Remote_Token_Proxy::open (const ACE_TCHAR *name,
106 int ignore_deadlock,
107 int debug)
109 ACE_TRACE ("ACE_Remote_Token_Proxy::open");
110 ignore_shadow_deadlock_ = ignore_deadlock;
111 return ACE_Token_Proxy::open (name, 0, debug);
114 void
115 ACE_Remote_Token_Proxy::set_server_address (const ACE_INET_Addr &server_address)
117 ACE_TRACE ("ACE_Remote_Token_Proxy::set_server_address");
118 ACE_Token_Connections::instance ()->set_server_address (server_address);
122 ACE_Remote_Token_Proxy::initiate_connection ()
124 ACE_TRACE ("ACE_Remote_Token_Proxy::initiate_connection");
125 if (token_ == 0)
127 errno = ENOENT;
128 ACELIB_ERROR_RETURN ((LM_ERROR,
129 ACE_TEXT ("ACE_Remote_Token_Proxy not open.\n")), -1);
132 ACE_SOCK_Stream *peer = ACE_Token_Connections::instance ()->get_connection ();
133 return peer == 0 ? 0 : 1;
136 // Do the work of sending a request and getting a reply.
139 ACE_Remote_Token_Proxy::request_reply (ACE_Token_Request &request,
140 ACE_Synch_Options &)
142 ACE_TRACE ("ACE_Remote_Token_Proxy::request_reply");
143 void *buffer;
144 ssize_t length;
146 if ((length = request.encode (buffer)) == -1)
147 ACELIB_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("encode failed")), -1);
149 ACE_SOCK_Stream *peer = ACE_Token_Connections::instance ()->get_connection ();
151 if (peer == 0)
152 ACELIB_ERROR_RETURN ((LM_ERROR,
153 ACE_TEXT("(%P|%t) %p\n"),
154 ACE_TEXT("BIG PROBLEMS with get_connection")), -1);
156 // Transmit request via a blocking send.
158 if (peer->send_n (buffer, length) != length)
159 ACELIB_ERROR_RETURN ((LM_ERROR,
160 ACE_TEXT ("%p\n"),
161 ACE_TEXT ("send_n failed")), -1);
162 else
164 ACE_Token_Reply reply;
166 // Receive reply via blocking read.
168 if (peer->recv (&reply, sizeof reply) != sizeof reply)
169 ACELIB_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("recv failed")), -1);
171 if (reply.decode () == -1)
172 ACELIB_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("decode failed")), -1);
174 errno = int (reply.errnum ());
175 if (errno != 0)
176 return -1;
177 else
178 return 0;
183 ACE_Remote_Token_Proxy::acquire (int notify,
184 void (*sleep_hook)(void *),
185 ACE_Synch_Options &options)
187 ACE_TRACE ("ACE_Remote_Token_Proxy::acquire");
189 // First grab the local shadow mutex.
190 if (ACE_Token_Proxy::acquire (notify,
191 sleep_hook,
192 ACE_Synch_Options::asynch) == -1)
194 // Acquire failed, deal with it...
195 switch (errno)
197 case EWOULDBLOCK :
198 // Whoah, we detected wouldblock via the shadow mutex!
199 if (debug_)
200 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) shadow: acquire will block, owner is %s\n"),
201 this->token_->owner_id ()));
202 // No error, but would block,
203 break;
205 case EDEADLK :
206 if (debug_)
207 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) shadow: deadlock detected\n")));
209 if (ignore_shadow_deadlock_)
210 break;
211 else
213 errno = EDEADLK;
214 ACE_RETURN (-1);
217 default :
218 ACELIB_ERROR_RETURN ((LM_ERROR,
219 ACE_TEXT ("(%t) %p shadow acquire failed\n"),
220 ACE_TEXT ("ACE_Remote_Token_Proxy")),
221 -1);
225 ACE_Token_Request request (token_->type (),
226 this->type (),
227 ACE_Token_Request::ACQUIRE,
228 this->name (),
229 this->client_id (),
230 options);
232 request.notify (notify);
234 int result = this->request_reply (request, options);
236 if (result == -1)
238 // Update the local shadow copy.
239 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("error on remote acquire, releasing shadow mutex.\n")));
240 ACE_Token_Proxy::release ();
242 else
244 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) acquired %s remotely.\n"), this->name ()));
245 // Our shadow call may have failed. However, it's still a race
246 // to the remote server. If we beat the client which holds the
247 // local token, we need to fix things locally to reflect the
248 // actual ownership. All that should happen is that our waiter
249 // is moved to the front of the waiter list.
250 token_->make_owner (waiter_);
253 return result;
257 ACE_Remote_Token_Proxy::tryacquire (void (*sleep_hook)(void *))
259 ACE_TRACE ("ACE_Remote_Token_Proxy::tryacquire");
261 // If we can detect locally that the tryacquire will fail, there is
262 // no need to go remote.
263 if (ACE_Token_Proxy::tryacquire (sleep_hook) == -1)
265 if (debug_)
267 // Save/restore errno.
268 ACE_Errno_Guard error (errno);
269 ACELIB_DEBUG ((LM_DEBUG,
270 ACE_TEXT ("shadow try acquire failed\n")));
273 return -1;
276 ACE_Token_Request request (token_->type (),
277 this->type (),
278 ACE_Token_Request::TRY_ACQUIRE,
279 this->name (),
280 this->client_id (),
281 ACE_Synch_Options::synch);
283 return this->request_reply (request,
284 ACE_Synch_Options::synch);
288 ACE_Remote_Token_Proxy::renew (int requeue_position,
289 ACE_Synch_Options &options)
291 ACE_TRACE ("ACE_Remote_Token_Proxy::renew");
293 if (ACE_Token_Proxy::renew (requeue_position,
294 ACE_Synch_Options::asynch) == -1)
296 // Check for error.
297 if (errno != EWOULDBLOCK)
298 return -1;
299 else if (debug_)
300 ACELIB_DEBUG ((LM_DEBUG,
301 ACE_TEXT ("(%t) shadow: renew would block. owner %s.\n"),
302 this->token_->owner_id ()));
305 ACE_Token_Request request (token_->type (),
306 this->type (),
307 ACE_Token_Request::RENEW,
308 this->name (),
309 this->client_id (),
310 options);
312 request.requeue_position (requeue_position);
314 int result = this->request_reply (request, options);
316 if (result == -1)
319 // Save/restore errno.
320 ACE_Errno_Guard error (errno);
321 ACE_Token_Proxy::release ();
323 ACELIB_ERROR_RETURN ((LM_ERROR,
324 ACE_TEXT ("%p error on remote renew, releasing shadow mutex.\n"),
325 ACE_TEXT ("ACE_Remote_Token_Proxy")), -1);
327 else
329 if (debug_)
330 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) renewed %s remotely.\n"), this->name ()));
331 // Make sure that the local shadow reflects our new ownership.
332 token_->make_owner (waiter_);
333 return result;
338 ACE_Remote_Token_Proxy::release (ACE_Synch_Options &options)
340 ACE_TRACE ("ACE_Remote_Token_Proxy::release");
342 ACE_Token_Request request (token_->type (),
343 this->type (),
344 ACE_Token_Request::RELEASE,
345 this->name (),
346 this->client_id (),
347 options);
349 int result = this->request_reply (request, options);
350 if (result == 0)
351 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) released %s remotely.\n"), this->name ()));
353 // whether success or failure, we're going to release the shadow.
354 // If race conditions exist such that we are no longer the owner,
355 // this release will perform a remove.
356 if (ACE_Token_Proxy::release () == -1)
357 ACELIB_ERROR ((LM_ERROR, ACE_TEXT ("(%t) shadow: release failed\n")));
359 return result;
363 ACE_Remote_Token_Proxy::remove (ACE_Synch_Options &)
365 ACE_TRACE ("ACE_Remote_Token_Proxy::remove");
366 return 0;
369 void
370 ACE_Remote_Token_Proxy::token_acquired (ACE_TPQ_Entry *)
372 ACE_TRACE ("ACE_Remote_Token_Proxy::token_acquired");
373 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) %s shadow token %s acquired\n"),
374 this->client_id (),
375 this->name ()));
376 // ACE_Token_Proxy::token_acquired (vp);
379 const ACE_TCHAR*
380 ACE_Remote_Token_Proxy::owner_id ()
382 ACE_TRACE ("ACE_Remote_Token_Proxy::owner_id");
383 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("owner_id called\n")));
384 // @@ special operation
385 return 0;
388 void
389 ACE_Remote_Token_Proxy::dump () const
391 #if defined (ACE_HAS_DUMP)
392 ACE_TRACE ("ACE_Remote_Token_Proxy::dump");
393 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
394 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_Tokens::dump:\n")
395 ACE_TEXT (" ignore_shadow_deadlock_ = %d\n"),
396 ignore_shadow_deadlock_));
397 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("base:\n")));
398 ACE_Token_Proxy::dump ();
399 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
400 #endif /* ACE_HAS_DUMP */
403 ACE_Token_Proxy *
404 ACE_Remote_Mutex::clone () const
406 ACE_Token_Proxy *temp;
407 ACE_NEW_RETURN (temp,
408 ACE_Remote_Mutex (this->name (),
409 ignore_deadlock_,
410 debug_),
412 return temp;
415 ACE_Tokens *
416 ACE_Remote_Mutex::create_token (const ACE_TCHAR *name)
418 ACE_Tokens *temp;
419 ACE_NEW_RETURN (temp,
420 ACE_Mutex_Token (name),
422 return temp;
425 void
426 ACE_Remote_Mutex::dump () const
428 #if defined (ACE_HAS_DUMP)
429 ACE_TRACE ("ACE_Remote_Mutex::dump");
430 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
431 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_Remote_Mutex::dump:\n")));
432 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("base:\n")));
433 ACE_Remote_Token_Proxy::dump ();
434 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
435 #endif /* ACE_HAS_DUMP */
438 ACE_Tokens *
439 ACE_Remote_RLock::create_token (const ACE_TCHAR *name)
441 ACE_Tokens *temp = 0;
442 ACE_NEW_RETURN (temp,
443 ACE_RW_Token (name),
445 return temp;
449 ACE_Remote_RLock::type () const
451 return ACE_RW_Token::READER;
454 ACE_Token_Proxy *
455 ACE_Remote_RLock::clone () const
457 ACE_Token_Proxy *temp = 0;
458 ACE_NEW_RETURN (temp,
459 ACE_Remote_RLock (this->name (),
460 ignore_deadlock_,
461 debug_),
463 return temp;
466 void
467 ACE_Remote_RLock::dump () const
469 #if defined (ACE_HAS_DUMP)
470 ACE_TRACE ("ACE_Remote_RLock::dump");
471 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
472 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_Remote_RLock::dump:\n")));
473 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("base:\n")));
474 ACE_Remote_Token_Proxy::dump ();
475 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
476 #endif /* ACE_HAS_DUMP */
480 ACE_Tokens *
481 ACE_Remote_WLock::create_token (const ACE_TCHAR *name)
483 ACE_Tokens *temp = 0;
484 ACE_NEW_RETURN (temp,
485 ACE_RW_Token (name),
487 return temp;
491 ACE_Remote_WLock::type () const
493 return ACE_RW_Token::WRITER;
496 ACE_Token_Proxy *
497 ACE_Remote_WLock::clone () const
499 ACE_Token_Proxy *temp = 0;
500 ACE_NEW_RETURN (temp,
501 ACE_Remote_WLock (this->name (),
502 ignore_deadlock_,
503 debug_),
505 return temp;
508 void
509 ACE_Remote_WLock::dump () const
511 #if defined (ACE_HAS_DUMP)
512 ACE_TRACE ("ACE_Remote_WLock::dump");
513 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
514 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_Remote_WLock::dump:\n")));
515 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("base:\n")));
516 ACE_Remote_Token_Proxy::dump ();
517 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
518 #endif /* ACE_HAS_DUMP */
521 ACE_END_VERSIONED_NAMESPACE_DECL
523 #endif /* ACE_HAS_TOKENS_LIBRARY */