1 // $Id: Remote_Tokens.cpp 80826 2008-03-04 14:51:23Z wotte $
3 #include "ace/Remote_Tokens.h"
5 #if defined (ACE_HAS_TOKENS_LIBRARY)
7 #include "ace/Singleton.h"
9 #if !defined (__ACE_INLINE__)
10 #include "ace/Remote_Tokens.inl"
11 #endif /* __ACE_INLINE__ */
16 "$Id: Remote_Tokens.cpp 80826 2008-03-04 14:51:23Z wotte $")
19 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
20 #define ACE_TSS_CONNECTION_MUTEX ACE_Thread_Mutex
22 #define ACE_TSS_CONNECTION_MUTEX ACE_Null_Mutex
23 #endif /* ACE_MT_SAFE */
25 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
27 // Make a typedef to simplify access to the Singleton below.
28 typedef ACE_Singleton
<ACE_TSS_Connection
, ACE_TSS_CONNECTION_MUTEX
> ACE_Token_Connections
;
30 // Initialize the statics from ACE_TSS_Connection;
31 ACE_INET_Addr
ACE_TSS_Connection::server_address_
;
33 // ************************************************************
36 ACE_TSS_Connection::set_server_address (const ACE_INET_Addr
&server_address
)
38 ACE_TRACE ("ACE_TSS_Connection::set_server_address");
39 server_address_
= server_address
;
42 // Necessary to make some compilers work...
43 ACE_TSS_Connection::ACE_TSS_Connection (void)
45 ACE_TRACE ("ACE_TSS_Connection::ACE_TSS_Connection");
48 ACE_TSS_Connection::~ACE_TSS_Connection (void)
50 ACE_TRACE ("ACE_TSS_Connection::~ACE_TSS_Connection");
54 ACE_TSS_Connection::get_connection (void)
56 return ACE_TSS
<ACE_SOCK_Stream
>::operator-> ();
60 ACE_TSS_Connection::make_TSS_TYPE (void) const
62 ACE_TRACE ("ACE_TSS_Connection::make_TSS_TYPE");
64 ACE_SOCK_Connector connector
;
65 ACE_SOCK_Stream
*stream
= 0;
67 ACE_NEW_RETURN (stream
,
71 if (connector
.connect (*stream
, server_address_
) == -1)
78 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("ACE_TSS_Connection new connection\n")));
82 ACE_TSS_Connection::operator ACE_SOCK_Stream
*(void)
84 return this->get_connection ();
88 ACE_TSS_Connection::dump (void) const
90 #if defined (ACE_HAS_DUMP)
91 ACE_TRACE ("ACE_TSS_Connection::dump");
92 ACE_DEBUG ((LM_DEBUG
, ACE_BEGIN_DUMP
, this));
93 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("ACE_TSS_Connection::dump:\n")));
94 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("server_address_\n")));
95 server_address_
.dump ();
96 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("base:\n")));
97 ACE_TSS
<ACE_SOCK_Stream
>::dump ();
98 ACE_DEBUG ((LM_DEBUG
, ACE_END_DUMP
));
99 #endif /* ACE_HAS_DUMP */
102 ACE_Remote_Token_Proxy::ACE_Remote_Token_Proxy (void)
104 ACE_TRACE ("ACE_Remote_Token_Proxy::ACE_Remote_Token_Proxy");
107 ACE_Remote_Token_Proxy::~ACE_Remote_Token_Proxy (void)
109 ACE_TRACE ("ACE_Remote_Token_Proxy::~ACE_Remote_Token_Proxy");
113 ACE_Remote_Token_Proxy::open (const ACE_TCHAR
*name
,
117 ACE_TRACE ("ACE_Remote_Token_Proxy::open");
118 ignore_shadow_deadlock_
= ignore_deadlock
;
119 return ACE_Token_Proxy::open (name
, 0, debug
);
123 ACE_Remote_Token_Proxy::set_server_address (const ACE_INET_Addr
&server_address
)
125 ACE_TRACE ("ACE_Remote_Token_Proxy::set_server_address");
126 ACE_Token_Connections::instance ()->set_server_address (server_address
);
130 ACE_Remote_Token_Proxy::initiate_connection (void)
132 ACE_TRACE ("ACE_Remote_Token_Proxy::initiate_connection");
136 ACE_ERROR_RETURN ((LM_ERROR
,
137 ACE_TEXT ("ACE_Remote_Token_Proxy not open.\n")), -1);
140 ACE_SOCK_Stream
*peer
= ACE_Token_Connections::instance ()->get_connection ();
141 return peer
== 0 ? 0 : 1;
144 // Do the work of sending a request and getting a reply.
147 ACE_Remote_Token_Proxy::request_reply (ACE_Token_Request
&request
,
150 ACE_TRACE ("ACE_Remote_Token_Proxy::request_reply");
154 if ((length
= request
.encode (buffer
)) == -1)
155 ACE_ERROR_RETURN ((LM_ERROR
, ACE_TEXT ("%p\n"), ACE_TEXT ("encode failed")), -1);
157 ACE_SOCK_Stream
*peer
= ACE_Token_Connections::instance ()->get_connection ();
160 ACE_ERROR_RETURN ((LM_ERROR
, "(%P|%t) %p\n", "BIG PROBLEMS with get_connection"), -1);
162 // Transmit request via a blocking send.
164 if (peer
->send_n (buffer
, length
) != length
)
165 ACE_ERROR_RETURN ((LM_ERROR
, ACE_TEXT ("%p\n"), ACE_TEXT ("send_n failed")), -1);
168 ACE_Token_Reply reply
;
170 // Receive reply via blocking read.
172 if (peer
->recv (&reply
, sizeof reply
) != sizeof reply
)
173 ACE_ERROR_RETURN ((LM_ERROR
, ACE_TEXT ("%p\n"), ACE_TEXT ("recv failed")), -1);
175 if (reply
.decode () == -1)
176 ACE_ERROR_RETURN ((LM_ERROR
, ACE_TEXT ("%p\n"), ACE_TEXT ("decode failed")), -1);
178 errno
= int (reply
.errnum ());
187 ACE_Remote_Token_Proxy::acquire (int notify
,
188 void (*sleep_hook
)(void *),
189 ACE_Synch_Options
&options
)
191 ACE_TRACE ("ACE_Remote_Token_Proxy::acquire");
193 // First grab the local shadow mutex.
194 if (ACE_Token_Proxy::acquire (notify
,
196 ACE_Synch_Options::asynch
) == -1)
198 // Acquire failed, deal with it...
202 // Whoah, we detected wouldblock via the shadow mutex!
204 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("(%t) shadow: acquire will block, owner is %s\n"),
205 this->token_
->owner_id ()));
206 // No error, but would block,
211 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("(%t) shadow: deadlock detected\n")));
213 if (ignore_shadow_deadlock_
)
222 ACE_ERROR_RETURN ((LM_ERROR
,
223 ACE_TEXT ("(%t) %p shadow acquire failed\n"),
224 ACE_TEXT ("ACE_Remote_Token_Proxy")),
229 ACE_Token_Request
request (token_
->type (),
231 ACE_Token_Request::ACQUIRE
,
236 request
.notify (notify
);
238 int result
= this->request_reply (request
, options
);
242 // Update the local shadow copy.
243 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("error on remote acquire, releasing shadow mutex.\n")));
244 ACE_Token_Proxy::release ();
248 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("(%t) acquired %s remotely.\n"), this->name ()));
249 // Our shadow call may have failed. However, it's still a race
250 // to the remote server. If we beat the client which holds the
251 // local token, we need to fix things locally to reflect the
252 // actual ownership. All that should happen is that our waiter
253 // is moved to the front of the waiter list.
254 token_
->make_owner (waiter_
);
261 ACE_Remote_Token_Proxy::tryacquire (void (*sleep_hook
)(void *))
263 ACE_TRACE ("ACE_Remote_Token_Proxy::tryacquire");
265 // If we can detect locally that the tryacquire will fail, there is
266 // no need to go remote.
267 if (ACE_Token_Proxy::tryacquire (sleep_hook
) == -1)
271 // Save/restore errno.
272 ACE_Errno_Guard
error (errno
);
273 ACE_DEBUG ((LM_DEBUG
,
274 ACE_TEXT ("shadow try acquire failed\n")));
280 ACE_Token_Request
request (token_
->type (),
282 ACE_Token_Request::TRY_ACQUIRE
,
285 ACE_Synch_Options::synch
);
287 return this->request_reply (request
,
288 ACE_Synch_Options::synch
);
292 ACE_Remote_Token_Proxy::renew (int requeue_position
,
293 ACE_Synch_Options
&options
)
295 ACE_TRACE ("ACE_Remote_Token_Proxy::renew");
297 if (ACE_Token_Proxy::renew (requeue_position
,
298 ACE_Synch_Options::asynch
) == -1)
301 if (errno
!= EWOULDBLOCK
)
304 ACE_DEBUG ((LM_DEBUG
,
305 ACE_TEXT ("(%t) shadow: renew would block. owner %s.\n"),
306 this->token_
->owner_id ()));
309 ACE_Token_Request
request (token_
->type (),
311 ACE_Token_Request::RENEW
,
316 request
.requeue_position (requeue_position
);
318 int result
= this->request_reply (request
, options
);
323 // Save/restore errno.
324 ACE_Errno_Guard
error (errno
);
325 ACE_Token_Proxy::release ();
327 ACE_ERROR_RETURN ((LM_ERROR
,
328 ACE_TEXT ("%p error on remote renew, releasing shadow mutex.\n"),
329 ACE_TEXT ("ACE_Remote_Token_Proxy")), -1);
334 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("(%t) renewed %s remotely.\n"), this->name ()));
335 // Make sure that the local shadow reflects our new ownership.
336 token_
->make_owner (waiter_
);
342 ACE_Remote_Token_Proxy::release (ACE_Synch_Options
&options
)
344 ACE_TRACE ("ACE_Remote_Token_Proxy::release");
346 ACE_Token_Request
request (token_
->type (),
348 ACE_Token_Request::RELEASE
,
353 int result
= this->request_reply (request
, options
);
355 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("(%t) released %s remotely.\n"), this->name ()));
357 // whether success or failure, we're going to release the shadow.
358 // If race conditions exist such that we are no longer the owner,
359 // this release will perform a remove.
360 if (ACE_Token_Proxy::release () == -1)
361 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("(%t) shadow: release failed\n")));
367 ACE_Remote_Token_Proxy::remove (ACE_Synch_Options
&)
369 ACE_TRACE ("ACE_Remote_Token_Proxy::remove");
374 ACE_Remote_Token_Proxy::token_acquired (ACE_TPQ_Entry
*)
376 ACE_TRACE ("ACE_Remote_Token_Proxy::token_acquired");
377 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("(%t) %s shadow token %s acquired\n"),
380 // ACE_Token_Proxy::token_acquired (vp);
384 ACE_Remote_Token_Proxy::owner_id (void)
386 ACE_TRACE ("ACE_Remote_Token_Proxy::owner_id");
387 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("owner_id called\n")));
388 // @@ special operation
393 ACE_Remote_Token_Proxy::dump (void) const
395 #if defined (ACE_HAS_DUMP)
396 ACE_TRACE ("ACE_Remote_Token_Proxy::dump");
397 ACE_DEBUG ((LM_DEBUG
, ACE_BEGIN_DUMP
, this));
398 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("ACE_Tokens::dump:\n")
399 ACE_TEXT (" ignore_shadow_deadlock_ = %d\n"),
400 ignore_shadow_deadlock_
));
401 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("base:\n")));
402 ACE_Token_Proxy::dump ();
403 ACE_DEBUG ((LM_DEBUG
, ACE_END_DUMP
));
404 #endif /* ACE_HAS_DUMP */
408 ACE_Remote_Mutex::clone (void) const
410 ACE_Token_Proxy
*temp
;
411 ACE_NEW_RETURN (temp
,
412 ACE_Remote_Mutex (this->name (),
420 ACE_Remote_Mutex::create_token (const ACE_TCHAR
*name
)
423 ACE_NEW_RETURN (temp
,
424 ACE_Mutex_Token (name
),
430 ACE_Remote_Mutex::dump (void) const
432 #if defined (ACE_HAS_DUMP)
433 ACE_TRACE ("ACE_Remote_Mutex::dump");
434 ACE_DEBUG ((LM_DEBUG
, ACE_BEGIN_DUMP
, this));
435 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("ACE_Remote_Mutex::dump:\n")));
436 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("base:\n")));
437 ACE_Remote_Token_Proxy::dump ();
438 ACE_DEBUG ((LM_DEBUG
, ACE_END_DUMP
));
439 #endif /* ACE_HAS_DUMP */
443 ACE_Remote_RLock::create_token (const ACE_TCHAR
*name
)
445 ACE_Tokens
*temp
= 0;
446 ACE_NEW_RETURN (temp
,
453 ACE_Remote_RLock::type (void) const
455 return ACE_RW_Token::READER
;
459 ACE_Remote_RLock::clone (void) const
461 ACE_Token_Proxy
*temp
= 0;
462 ACE_NEW_RETURN (temp
,
463 ACE_Remote_RLock (this->name (),
471 ACE_Remote_RLock::dump (void) const
473 #if defined (ACE_HAS_DUMP)
474 ACE_TRACE ("ACE_Remote_RLock::dump");
475 ACE_DEBUG ((LM_DEBUG
, ACE_BEGIN_DUMP
, this));
476 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("ACE_Remote_RLock::dump:\n")));
477 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("base:\n")));
478 ACE_Remote_Token_Proxy::dump ();
479 ACE_DEBUG ((LM_DEBUG
, ACE_END_DUMP
));
480 #endif /* ACE_HAS_DUMP */
485 ACE_Remote_WLock::create_token (const ACE_TCHAR
*name
)
487 ACE_Tokens
*temp
= 0;
488 ACE_NEW_RETURN (temp
,
495 ACE_Remote_WLock::type (void) const
497 return ACE_RW_Token::WRITER
;
501 ACE_Remote_WLock::clone (void) const
503 ACE_Token_Proxy
*temp
= 0;
504 ACE_NEW_RETURN (temp
,
505 ACE_Remote_WLock (this->name (),
513 ACE_Remote_WLock::dump (void) const
515 #if defined (ACE_HAS_DUMP)
516 ACE_TRACE ("ACE_Remote_WLock::dump");
517 ACE_DEBUG ((LM_DEBUG
, ACE_BEGIN_DUMP
, this));
518 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("ACE_Remote_WLock::dump:\n")));
519 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("base:\n")));
520 ACE_Remote_Token_Proxy::dump ();
521 ACE_DEBUG ((LM_DEBUG
, ACE_END_DUMP
));
522 #endif /* ACE_HAS_DUMP */
525 ACE_END_VERSIONED_NAMESPACE_DECL
527 #endif /* ACE_HAS_TOKENS_LIBRARY */