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