Go to the documentation of this file.00001 #include "ace/Token_Manager.h"
00002
00003 #if defined (ACE_HAS_TOKENS_LIBRARY)
00004
00005 #include "ace/Object_Manager.h"
00006 #include "ace/os_include/os_typeinfo.h"
00007
00008 #if !defined (__ACE_INLINE__)
00009 #include "ace/Token_Manager.inl"
00010 #endif
00011
00012 ACE_RCSID (ace,
00013 Token_Manager,
00014 "$Id: Token_Manager.cpp 84179 2009-01-16 07:26:45Z johnnyw $")
00015
00016 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00017
00018
00019 ACE_Token_Manager *ACE_Token_Manager::token_manager_ = 0;
00020
00021 ACE_Token_Manager::ACE_Token_Manager ()
00022 {
00023 ACE_TRACE ("ACE_Token_Manager::ACE_Token_Manager");
00024 }
00025
00026 ACE_Token_Manager::~ACE_Token_Manager ()
00027 {
00028 ACE_TRACE ("ACE_Token_Manager::~ACE_Token_Manager");
00029
00030 COLLECTION::ITERATOR iterator (collection_);
00031
00032 for (COLLECTION::ENTRY *temp = 0;
00033 iterator.next (temp) != 0;
00034 iterator.advance ())
00035 {
00036
00037 delete temp->int_id_;
00038
00039
00040 }
00041 }
00042
00043 ACE_Token_Manager *
00044 ACE_Token_Manager::instance (void)
00045 {
00046 ACE_TRACE ("ACE_Token_Manager::instance");
00047
00048
00049
00050 if (token_manager_ == 0)
00051 {
00052 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00053 ACE_TOKEN_CONST::MUTEX *lock =
00054 ACE_Managed_Object<ACE_TOKEN_CONST::MUTEX>::get_preallocated_object
00055 (ACE_Object_Manager::ACE_TOKEN_MANAGER_CREATION_LOCK);
00056 ACE_GUARD_RETURN (ACE_TOKEN_CONST::MUTEX, ace_mon, *lock, 0);
00057 #endif
00058
00059 if (token_manager_ == 0)
00060 {
00061 ACE_NEW_RETURN (token_manager_,
00062 ACE_Token_Manager,
00063 0);
00064
00065 ACE_Object_Manager::at_exit (token_manager_, 0, typeid (token_manager_).name ());
00066 }
00067 }
00068
00069 return token_manager_;
00070 }
00071
00072 void
00073 ACE_Token_Manager::get_token (ACE_Token_Proxy *proxy,
00074 const ACE_TCHAR *token_name)
00075 {
00076 ACE_TRACE ("ACE_Token_Manager::get_token");
00077
00078
00079
00080
00081 ACE_GUARD (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_);
00082
00083 TOKEN_NAME name (token_name);
00084
00085 if (collection_.find (name, proxy->token_) == -1)
00086
00087 {
00088
00089 proxy->token_ = proxy->create_token (token_name);
00090
00091
00092 if (collection_.bind (name, proxy->token_) == -1)
00093 {
00094 delete proxy->token_;
00095 proxy->token_ = 0;
00096 }
00097 }
00098
00099 if (proxy->token_ != 0)
00100 proxy->token_->inc_reference ();
00101
00102
00103
00104 }
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 int
00117 ACE_Token_Manager::check_deadlock (ACE_Token_Proxy *proxy)
00118 {
00119 ACE_TRACE ("ACE_Token_Manager::check_deadlock");
00120
00121
00122 int result = this->check_deadlock (proxy->token_, proxy);
00123
00124
00125
00126 COLLECTION::ITERATOR iterator (collection_);
00127 for (COLLECTION::ENTRY *temp = 0;
00128 iterator.next (temp) != 0;
00129 iterator.advance ())
00130 temp->int_id_->visit (0);
00131
00132 return result;
00133 }
00134
00135 int
00136 ACE_Token_Manager::check_deadlock (ACE_Tokens *token, ACE_Token_Proxy *proxy)
00137 {
00138 ACE_TRACE ("ACE_Token_Manager::check_deadlock");
00139
00140 if (token->visited ())
00141 return 0;
00142
00143 token->visit (1);
00144
00145 ACE_Tokens::OWNER_STACK owners;
00146
00147 int is_owner = token->owners (owners, proxy->client_id ());
00148
00149 switch (is_owner)
00150 {
00151 case -1:
00152
00153 return -1;
00154 case 1:
00155
00156 if (debug_)
00157 {
00158 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) Deadlock detected.\n")));
00159 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%s owns %s and is waiting for %s.\n"),
00160 proxy->client_id (),
00161 token->name (),
00162 proxy->token_->name ()));
00163 }
00164
00165 return 1;
00166 case 0:
00167 default:
00168
00169 while (!owners.is_empty ())
00170 {
00171 ACE_TPQ_Entry *e;
00172 owners.pop (e);
00173
00174 ACE_Tokens *twf = this->token_waiting_for (e->client_id ());
00175 if ((twf != 0) &&
00176 (this->check_deadlock (twf, proxy) == 1))
00177 {
00178 if (debug_)
00179 {
00180 ACE_DEBUG ((LM_DEBUG,
00181 ACE_TEXT ("%s owns %s and is waiting for %s.\n"),
00182 e->client_id (),
00183 token->name (),
00184 twf->name ()));
00185 }
00186 return 1;
00187 }
00188
00189 }
00190
00191
00192 return 0;
00193 }
00194 }
00195
00196
00197 ACE_Tokens *
00198 ACE_Token_Manager::token_waiting_for (const ACE_TCHAR *client_id)
00199 {
00200 COLLECTION::ITERATOR iterator (collection_);
00201 for (COLLECTION::ENTRY *temp = 0;
00202 iterator.next (temp) != 0;
00203 iterator.advance ())
00204 {
00205 if (temp->int_id_->is_waiting_for (client_id))
00206 return temp->int_id_;
00207 }
00208
00209
00210 return 0;
00211 }
00212
00213
00214
00215
00216 void
00217 ACE_Token_Manager::release_token (ACE_Tokens *&token)
00218 {
00219 ACE_TRACE ("ACE_Token_Manager::release_token");
00220
00221
00222 ACE_GUARD (ACE_TOKEN_CONST::MUTEX, ace_mon, this->lock_);
00223
00224 if (token->dec_reference () == 0)
00225 {
00226
00227
00228 TOKEN_NAME token_name (token->name ());
00229
00230 ACE_Tokens *temp;
00231
00232 if (collection_.unbind (token_name, temp) == -1)
00233
00234 {
00235 errno = ENOENT;
00236 ACE_ERROR ((LM_ERROR, ACE_TEXT ("Token Manager could not release %s:%d\n"),
00237 token->name (), token->type ()));
00238
00239 }
00240 else
00241
00242 {
00243
00244
00245 ACE_ASSERT (token == temp);
00246 delete token;
00247
00248
00249
00250 token = 0;
00251 }
00252 }
00253
00254
00255 }
00256
00257 void
00258 ACE_Token_Manager::dump (void) const
00259 {
00260 #if defined (ACE_HAS_DUMP)
00261 ACE_TRACE ("ACE_Token_Manager::dump");
00262 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00263 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_Token_Manager::dump:\n")));
00264 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("lock_\n")));
00265 lock_.dump ();
00266 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("collection_\n")));
00267 collection_.dump ();
00268 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00269 #endif
00270 }
00271
00272 ACE_END_VERSIONED_NAMESPACE_DECL
00273
00274 #endif