00001 #include "ace_pch.h"
00002
00003
00004 #include "ace/Filecache.h"
00005 #include "ace/Object_Manager.h"
00006 #include "ace/Log_Msg.h"
00007
00008 ACE_RCSID(ace, Filecache, "$Id: Filecache.cpp,v 1.1.1.4.2.1 2003/03/13 19:44:21 chad Exp $")
00009
00010 #if defined (ACE_WIN32)
00011
00012 #define R_MASK ACE_DEFAULT_OPEN_PERMS
00013 #define W_MASK 0
00014 #else
00015 #define R_MASK S_IRUSR|S_IRGRP|S_IROTH
00016 #define W_MASK S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR|S_IWGRP|S_IWOTH
00017 #endif
00018
00019 #if defined (ACE_WIN32)
00020
00021 #define READ_FLAGS (FILE_FLAG_SEQUENTIAL_SCAN | \
00022 FILE_FLAG_OVERLAPPED | \
00023 O_RDONLY)
00024
00025
00026 #define WRITE_FLAGS (FILE_FLAG_SEQUENTIAL_SCAN | \
00027 FILE_FLAG_OVERLAPPED | \
00028 O_RDWR | O_CREAT | O_TRUNC)
00029
00030
00031 #else
00032 #define READ_FLAGS O_RDONLY
00033
00034 #define WRITE_FLAGS (O_RDWR | O_CREAT | O_TRUNC)
00035
00036 #endif
00037
00038
00039 ACE_Filecache *ACE_Filecache::cvf_ = 0;
00040
00041 void
00042 ACE_Filecache_Handle::init (void)
00043 {
00044 this->file_ = 0;
00045 this->handle_ = ACE_INVALID_HANDLE;
00046 }
00047
00048 ACE_Filecache_Handle::ACE_Filecache_Handle (void)
00049 : file_ (0), handle_ (0), mapit_ (0)
00050 {
00051 this->init ();
00052 }
00053
00054 ACE_Filecache_Handle::ACE_Filecache_Handle (const ACE_TCHAR *filename,
00055 ACE_Filecache_Flag mapit)
00056 : file_ (0), handle_ (0), mapit_ (mapit)
00057 {
00058 this->init ();
00059
00060
00061
00062
00063
00064 this->file_ = ACE_Filecache::instance ()->fetch (filename, mapit);
00065 }
00066
00067 ACE_Filecache_Handle::ACE_Filecache_Handle (const ACE_TCHAR *filename,
00068 int size,
00069 ACE_Filecache_Flag mapit)
00070 : file_ (0), handle_ (0), mapit_ (mapit)
00071 {
00072 this->init ();
00073
00074 if (size == 0)
00075 ACE_Filecache::instance ()->remove (filename);
00076 else
00077 {
00078
00079
00080
00081
00082
00083
00084 this->file_ = ACE_Filecache::instance ()->create (filename, size);
00085 }
00086 }
00087
00088 ACE_Filecache_Handle::~ACE_Filecache_Handle (void)
00089 {
00090 if (this->handle_ != ACE_INVALID_HANDLE)
00091
00092 ACE_OS::close (this->handle_);
00093
00094 ACE_Filecache::instance ()->finish (this->file_);
00095 }
00096
00097 void *
00098 ACE_Filecache_Handle::address (void) const
00099 {
00100 return this->file_ == 0 ? 0 : this->file_->address ();
00101 }
00102
00103 ACE_HANDLE
00104 ACE_Filecache_Handle::handle (void) const
00105 {
00106 if (this->handle_ == ACE_INVALID_HANDLE && this->file_ != 0)
00107 {
00108 ACE_Filecache_Handle *mutable_this =
00109 (ACE_Filecache_Handle *) this;
00110 mutable_this->handle_ = ACE_OS::dup (this->file_->handle ());
00111 }
00112 return this->handle_;
00113 }
00114
00115 int
00116 ACE_Filecache_Handle::error (void) const
00117 {
00118 if (this->file_ == 0)
00119 return -1;
00120 else
00121 return this->file_->error ();
00122 }
00123
00124 off_t
00125 ACE_Filecache_Handle::size (void) const
00126 {
00127 if (this->file_ == 0)
00128 return -1;
00129 else
00130 return this->file_->size ();
00131 }
00132
00133
00134
00135
00136
00137 #if defined (ACE_HAS_TEMPLATE_SPECIALIZATION)
00138
00139 #define ACE_Filecache_Hash \
00140 ACE_Hash_Map_Manager<const ACE_TCHAR *, ACE_Filecache_Object *, ACE_Null_Mutex>
00141 #define ACE_Filecache_Hash_Entry \
00142 ACE_Hash_Map_Entry<const ACE_TCHAR *, ACE_Filecache_Object *>
00143
00144 ACE_TEMPLATE_SPECIALIZATION
00145 ACE_Filecache_Hash_Entry::ACE_Hash_Map_Entry (const ACE_TCHAR *const &ext_id,
00146 ACE_Filecache_Object *const &int_id,
00147 ACE_Filecache_Hash_Entry *next,
00148 ACE_Filecache_Hash_Entry *prev)
00149 : ext_id_ (ext_id ? ACE_OS::strdup (ext_id) : ACE_OS::strdup (ACE_LIB_TEXT (""))),
00150 int_id_ (int_id),
00151 next_ (next),
00152 prev_ (prev)
00153 {
00154 }
00155
00156 ACE_TEMPLATE_SPECIALIZATION
00157 ACE_Filecache_Hash_Entry::ACE_Hash_Map_Entry (ACE_Filecache_Hash_Entry *next,
00158 ACE_Filecache_Hash_Entry *prev)
00159 : ext_id_ (0),
00160 next_ (next),
00161 prev_ (prev)
00162 {
00163 }
00164
00165 ACE_TEMPLATE_SPECIALIZATION
00166 ACE_Filecache_Hash_Entry::~ACE_Hash_Map_Entry (void)
00167 {
00168 ACE_OS::free ((void *) ext_id_);
00169 }
00170
00171
00172
00173
00174 ACE_TEMPLATE_SPECIALIZATION
00175 unsigned long
00176 ACE_Filecache_Hash::hash (const ACE_TCHAR *const &ext_id)
00177 {
00178 return ACE::hash_pjw (ext_id);
00179 }
00180
00181 ACE_TEMPLATE_SPECIALIZATION
00182 int
00183 ACE_Filecache_Hash::equal (const ACE_TCHAR *const &id1, const ACE_TCHAR *const &id2)
00184 {
00185 return ACE_OS::strcmp (id1, id2) == 0;
00186 }
00187
00188 #undef ACE_Filecache_Hash
00189 #undef ACE_Filecache_Hash_Entry
00190
00191 #endif
00192
00193
00194
00195
00196
00197
00198 ACE_Filecache *
00199 ACE_Filecache::instance (void)
00200 {
00201
00202 if (ACE_Filecache::cvf_ == 0)
00203 {
00204 ACE_SYNCH_RW_MUTEX &lock =
00205 *ACE_Managed_Object<ACE_SYNCH_RW_MUTEX>::get_preallocated_object
00206 (ACE_Object_Manager::ACE_FILECACHE_LOCK);
00207 ACE_GUARD_RETURN (ACE_SYNCH_RW_MUTEX, ace_mon, lock, 0);
00208
00209
00210
00211 if (ACE_Filecache::cvf_ == 0)
00212 ACE_NEW_RETURN (ACE_Filecache::cvf_,
00213 ACE_Filecache,
00214 0);
00215 }
00216
00217 return ACE_Filecache::cvf_;
00218 }
00219
00220 ACE_Filecache::ACE_Filecache (void)
00221 : size_ (ACE_DEFAULT_VIRTUAL_FILESYSTEM_TABLE_SIZE),
00222 hash_ (this->size_)
00223 {
00224 }
00225
00226 ACE_Filecache::~ACE_Filecache (void)
00227 {
00228 }
00229
00230 ACE_Filecache_Object *
00231 ACE_Filecache::insert_i (const ACE_TCHAR *filename,
00232 ACE_SYNCH_RW_MUTEX &filelock,
00233 int mapit)
00234 {
00235 ACE_Filecache_Object *handle = 0;
00236
00237 if (this->hash_.find (filename, handle) == -1)
00238 {
00239 ACE_NEW_RETURN (handle,
00240 ACE_Filecache_Object (filename, filelock, 0, mapit),
00241 0);
00242
00243
00244
00245 if (this->hash_.bind (filename, handle) == -1)
00246 {
00247 delete handle;
00248 handle = 0;
00249 }
00250 }
00251 else
00252 handle = 0;
00253
00254 return handle;
00255 }
00256
00257 ACE_Filecache_Object *
00258 ACE_Filecache::remove_i (const ACE_TCHAR *filename)
00259 {
00260 ACE_Filecache_Object *handle = 0;
00261
00262
00263 if (this->hash_.unbind (filename, handle) == 0)
00264 {
00265 handle->stale_ = 1;
00266
00267
00268
00269 if (handle->lock_.tryacquire_write () == 0)
00270 {
00271 delete handle;
00272 handle = 0;
00273 }
00274 }
00275 else
00276 handle = 0;
00277
00278 return handle;
00279 }
00280
00281 ACE_Filecache_Object *
00282 ACE_Filecache::update_i (const ACE_TCHAR *filename,
00283 ACE_SYNCH_RW_MUTEX &filelock,
00284 int mapit)
00285 {
00286 ACE_Filecache_Object *handle = 0;
00287
00288 handle = this->remove_i (filename);
00289 handle = this->insert_i (filename, filelock, mapit);
00290
00291 return handle;
00292 }
00293
00294 int
00295 ACE_Filecache::find (const ACE_TCHAR *filename)
00296 {
00297 return this->hash_.find (filename);
00298 }
00299
00300
00301 ACE_Filecache_Object *
00302 ACE_Filecache::remove (const ACE_TCHAR *filename)
00303 {
00304 ACE_Filecache_Object *handle = 0;
00305
00306 u_long loc = ACE::hash_pjw (filename) % this->size_;
00307 ACE_SYNCH_RW_MUTEX &hashlock = this->hash_lock_[loc];
00308
00309
00310 if (this->hash_.find (filename, handle) != -1)
00311 {
00312 ACE_WRITE_GUARD_RETURN (ACE_SYNCH_RW_MUTEX,
00313 ace_mon,
00314 hashlock,
00315 0);
00316
00317 return this->remove_i (filename);
00318 }
00319
00320 return 0;
00321 }
00322
00323
00324 ACE_Filecache_Object *
00325 ACE_Filecache::fetch (const ACE_TCHAR *filename, int mapit)
00326 {
00327 ACE_Filecache_Object *handle = 0;
00328
00329 u_long loc = ACE::hash_pjw (filename) % this->size_;
00330 ACE_SYNCH_RW_MUTEX &hashlock = this->hash_lock_[loc];
00331 ACE_SYNCH_RW_MUTEX &filelock = this->file_lock_[loc];
00332
00333 filelock.acquire_read ();
00334
00335 if (this->hash_.find (filename, handle) == -1)
00336 {
00337 ACE_WRITE_GUARD_RETURN (ACE_SYNCH_RW_MUTEX,
00338 ace_mon,
00339 hashlock,
00340 0);
00341
00342
00343 handle = this->insert_i (filename, filelock, mapit);
00344
00345 if (handle == 0)
00346 filelock.release ();
00347 }
00348 else
00349 {
00350 if (handle->update ())
00351 {
00352 {
00353
00354 ACE_WRITE_GUARD_RETURN (ACE_SYNCH_RW_MUTEX,
00355 ace_mon,
00356 hashlock,
00357 0);
00358
00359
00360 handle = this->update_i (filename, filelock, mapit);
00361
00362 if (handle == 0)
00363 filelock.release ();
00364 }
00365 }
00366
00367 }
00368
00369 return handle;
00370 }
00371
00372 ACE_Filecache_Object *
00373 ACE_Filecache::create (const ACE_TCHAR *filename, int size)
00374 {
00375 ACE_Filecache_Object *handle = 0;
00376
00377 u_long loc = ACE::hash_pjw (filename) % this->size_;
00378 ACE_SYNCH_RW_MUTEX &filelock = this->file_lock_[loc];
00379
00380 ACE_NEW_RETURN (handle,
00381 ACE_Filecache_Object (filename, size, filelock),
00382 0);
00383 handle->acquire ();
00384
00385 return handle;
00386 }
00387
00388 ACE_Filecache_Object *
00389 ACE_Filecache::finish (ACE_Filecache_Object *&file)
00390 {
00391 if (file == 0)
00392 return file;
00393
00394 u_long loc = ACE::hash_pjw (file->filename_) % this->size_;
00395 ACE_SYNCH_RW_MUTEX &hashlock = this->hash_lock_[loc];
00396
00397 if (file != 0)
00398 switch (file->action_)
00399 {
00400 case ACE_Filecache_Object::ACE_WRITING:
00401 {
00402 ACE_WRITE_GUARD_RETURN (ACE_SYNCH_RW_MUTEX,
00403 ace_mon,
00404 hashlock,
00405 0);
00406
00407 file->release ();
00408
00409 this->remove_i (file->filename_);
00410 #if 0
00411 int result = this->hash_.bind (file->filename (), file);
00412
00413 if (result == 0)
00414 file->acquire ();
00415 #else
00416
00417 if (file->stale_)
00418 {
00419
00420
00421 if (file->lock_.tryacquire_write () == 0)
00422 {
00423 delete file;
00424 file = 0;
00425 }
00426 }
00427 #endif
00428 }
00429
00430 break;
00431 default:
00432 file->release ();
00433
00434
00435 if (file->stale_)
00436 {
00437
00438
00439 if (file->lock_.tryacquire_write () == 0)
00440 {
00441 delete file;
00442 file = 0;
00443 }
00444 }
00445
00446 break;
00447 }
00448
00449 return file;
00450 }
00451
00452 void
00453 ACE_Filecache_Object::init (void)
00454 {
00455 this->filename_[0] = '\0';
00456 this->handle_ = ACE_INVALID_HANDLE;
00457 this->error_ = ACE_SUCCESS;
00458 this->tempname_ = 0;
00459 this->size_ = 0;
00460
00461 ACE_OS::memset (&(this->stat_), 0, sizeof (this->stat_));
00462 }
00463
00464 ACE_Filecache_Object::ACE_Filecache_Object (void)
00465 : tempname_ (0),
00466 mmap_ (),
00467 handle_ (0),
00468
00469 size_ (0),
00470 action_ (0),
00471 error_ (0),
00472 stale_ (0),
00473
00474 junklock_ (),
00475 lock_ (junklock_)
00476 {
00477 this->init ();
00478 }
00479
00480 ACE_Filecache_Object::ACE_Filecache_Object (const ACE_TCHAR *filename,
00481 ACE_SYNCH_RW_MUTEX &lock,
00482 LPSECURITY_ATTRIBUTES sa,
00483 int mapit)
00484 : tempname_ (0),
00485 mmap_ (),
00486 handle_ (0),
00487
00488 size_ (0),
00489 action_ (0),
00490 error_ (0),
00491 stale_ (0),
00492 sa_ (sa),
00493 junklock_ (),
00494 lock_ (lock)
00495 {
00496 this->init ();
00497
00498
00499 ACE_OS::strcpy (this->filename_, filename);
00500 this->action_ = ACE_Filecache_Object::ACE_READING;
00501
00502
00503
00504 if (ACE_OS::access (this->filename_, R_OK) == -1)
00505 {
00506 this->error_i (ACE_Filecache_Object::ACE_ACCESS_FAILED);
00507 return;
00508 }
00509
00510
00511 if (ACE_OS::stat (this->filename_, &this->stat_) == -1)
00512 {
00513 this->error_i (ACE_Filecache_Object::ACE_STAT_FAILED);
00514 return;
00515 }
00516
00517 this->size_ = this->stat_.st_size;
00518 this->tempname_ = this->filename_;
00519
00520
00521 this->handle_ = ACE_OS::open (this->tempname_,
00522 READ_FLAGS, R_MASK, this->sa_);
00523 if (this->handle_ == ACE_INVALID_HANDLE)
00524 {
00525 this->error_i (ACE_Filecache_Object::ACE_OPEN_FAILED,
00526 ACE_LIB_TEXT ("ACE_Filecache_Object::ctor: open"));
00527 return;
00528 }
00529
00530 if (mapit)
00531 {
00532
00533 if (this->mmap_.map (this->handle_, -1,
00534 PROT_READ, ACE_MAP_PRIVATE, 0, 0, this->sa_) != 0)
00535 {
00536 this->error_i (ACE_Filecache_Object::ACE_MEMMAP_FAILED,
00537 ACE_LIB_TEXT ("ACE_Filecache_Object::ctor: map"));
00538 ACE_OS::close (this->handle_);
00539 this->handle_ = ACE_INVALID_HANDLE;
00540 return;
00541 }
00542 }
00543
00544
00545 this->action_ = ACE_Filecache_Object::ACE_READING;
00546 }
00547
00548 ACE_Filecache_Object::ACE_Filecache_Object (const ACE_TCHAR *filename,
00549 off_t size,
00550 ACE_SYNCH_RW_MUTEX &lock,
00551 LPSECURITY_ATTRIBUTES sa)
00552 : stale_ (0),
00553 sa_ (sa),
00554 lock_ (lock)
00555 {
00556 this->init ();
00557
00558 this->size_ = size;
00559 ACE_OS::strcpy (this->filename_, filename);
00560 this->action_ = ACE_Filecache_Object::ACE_WRITING;
00561
00562
00563 if (ACE_OS::access (this->filename_, R_OK|W_OK) == -1
00564
00565 && ACE_OS::access (this->filename_, F_OK) != -1)
00566 {
00567
00568 this->error_i (ACE_Filecache_Object::ACE_ACCESS_FAILED);
00569 return;
00570 }
00571
00572 this->tempname_ = this->filename_;
00573
00574
00575 this->handle_ = ACE_OS::open (this->tempname_, WRITE_FLAGS, W_MASK, this->sa_);
00576 if (this->handle_ == ACE_INVALID_HANDLE)
00577 {
00578 this->error_i (ACE_Filecache_Object::ACE_OPEN_FAILED,
00579 ACE_LIB_TEXT ("ACE_Filecache_Object::acquire: open"));
00580 return;
00581 }
00582
00583
00584 if (ACE_OS::pwrite (this->handle_, "", 1, this->size_ - 1) != 1)
00585 {
00586 this->error_i (ACE_Filecache_Object::ACE_WRITE_FAILED,
00587 ACE_LIB_TEXT ("ACE_Filecache_Object::acquire: write"));
00588 ACE_OS::close (this->handle_);
00589 return;
00590 }
00591
00592
00593 if (this->mmap_.map (this->handle_, this->size_, PROT_RDWR, MAP_SHARED,
00594 0, 0, this->sa_) != 0)
00595 {
00596 this->error_i (ACE_Filecache_Object::ACE_MEMMAP_FAILED,
00597 ACE_LIB_TEXT ("ACE_Filecache_Object::acquire: map"));
00598 ACE_OS::close (this->handle_);
00599 }
00600
00601
00602 }
00603
00604 ACE_Filecache_Object::~ACE_Filecache_Object (void)
00605 {
00606 if (this->error_ == ACE_SUCCESS)
00607 {
00608 this->mmap_.unmap ();
00609 ACE_OS::close (this->handle_);
00610 this->handle_ = ACE_INVALID_HANDLE;
00611 }
00612 }
00613
00614 int
00615 ACE_Filecache_Object::acquire (void)
00616 {
00617 return this->lock_.tryacquire_read ();
00618 }
00619
00620 int
00621 ACE_Filecache_Object::release (void)
00622 {
00623 if (this->action_ == ACE_WRITING)
00624 {
00625
00626
00627 #if 0
00628 ACE_HANDLE original = ACE_OS::open (this->filename_, WRITE_FLAGS, W_MASK,
00629 this->sa_);
00630 if (original == ACE_INVALID_HANDLE)
00631 this->error_ = ACE_Filecache_Object::ACE_OPEN_FAILED;
00632 else if (ACE_OS::write (original, this->mmap_.addr (),
00633 this->size_) == -1)
00634 {
00635 this->error_ = ACE_Filecache_Object::ACE_WRITE_FAILED;
00636 ACE_OS::close (original);
00637 ACE_OS::unlink (this->filename_);
00638 }
00639 else if (ACE_OS::stat (this->filename_, &this->stat_) == -1)
00640 this->error_ = ACE_Filecache_Object::ACE_STAT_FAILED;
00641 #endif
00642
00643 this->mmap_.unmap ();
00644 ACE_OS::close (this->handle_);
00645 this->handle_ = ACE_INVALID_HANDLE;
00646
00647 #if 0
00648
00649 this->handle_ = ACE_OS::open (this->tempname_, READ_FLAGS, R_MASK);
00650 if (this->handle_ == ACE_INVALID_HANDLE)
00651 {
00652 this->error_i (ACE_Filecache_Object::ACE_OPEN_FAILED,
00653 "ACE_Filecache_Object::acquire: open");
00654 }
00655 else if (this->mmap_.map (this->handle_, -1,
00656 PROT_READ,
00657 ACE_MAP_PRIVATE,
00658 0,
00659 0,
00660 this->sa_) != 0)
00661 {
00662 this->error_i (ACE_Filecache_Object::ACE_MEMMAP_FAILED,
00663 "ACE_Filecache_Object::acquire: map");
00664 ACE_OS::close (this->handle_);
00665 this->handle_ = ACE_INVALID_HANDLE;
00666 }
00667
00668 this->action_ = ACE_Filecache_Object::ACE_READING;
00669 #endif
00670 }
00671
00672 return this->lock_.release ();
00673 }
00674
00675 int
00676 ACE_Filecache_Object::error (void) const
00677 {
00678
00679 return this->error_;
00680 }
00681
00682 int
00683 ACE_Filecache_Object::error_i (int error_value, const ACE_TCHAR *s)
00684 {
00685 s = s;
00686 ACE_ERROR ((LM_ERROR, ACE_LIB_TEXT ("%p.\n"), s));
00687 this->error_ = error_value;
00688 return error_value;
00689 }
00690
00691 const ACE_TCHAR *
00692 ACE_Filecache_Object::filename (void) const
00693 {
00694
00695 return this->filename_;
00696 }
00697
00698 off_t
00699 ACE_Filecache_Object::size (void) const
00700 {
00701
00702 return this->size_;
00703 }
00704
00705 ACE_HANDLE
00706 ACE_Filecache_Object::handle (void) const
00707 {
00708
00709 return this->handle_;
00710 }
00711
00712 void *
00713 ACE_Filecache_Object::address (void) const
00714 {
00715
00716 return this->mmap_.addr ();
00717 }
00718
00719 int
00720 ACE_Filecache_Object::update (void) const
00721 {
00722
00723 int result;
00724 ACE_stat statbuf;
00725
00726 if (ACE_OS::stat (this->filename_, &statbuf) == -1)
00727 result = 1;
00728 else
00729
00730 #if defined (ACE_HAS_WINCE)
00731
00732
00733
00734 result = 1;
00735 #else
00736 result = ACE_OS::difftime (this->stat_.st_mtime, statbuf.st_mtime) < 0;
00737 #endif
00738
00739 return result;
00740 }
00741
00742 #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
00743 #if defined (ACE_HAS_TEMPLATE_SPECIALIZATION)
00744 template class ACE_Hash_Map_Entry<const ACE_TCHAR *, ACE_Filecache_Object *>;
00745 template class ACE_Hash_Map_Manager<const ACE_TCHAR *, ACE_Filecache_Object *, ACE_Null_Mutex>;
00746 template class ACE_Hash_Map_Iterator<const ACE_TCHAR *, ACE_Filecache_Object *, ACE_Null_Mutex>;
00747 template class ACE_Hash_Map_Reverse_Iterator<const ACE_TCHAR *, ACE_Filecache_Object *, ACE_Null_Mutex>;
00748 template class ACE_Hash_Map_Manager_Ex<const ACE_TCHAR *, ACE_Filecache_Object *, ACE_Hash<const ACE_TCHAR *>, ACE_Equal_To<const ACE_TCHAR *>, ACE_Null_Mutex>;
00749 template class ACE_Hash_Map_Iterator_Base_Ex<const ACE_TCHAR *, ACE_Filecache_Object *, ACE_Hash<const ACE_TCHAR *>, ACE_Equal_To<const ACE_TCHAR *>, ACE_Null_Mutex>;
00750 template class ACE_Hash_Map_Iterator_Ex<const ACE_TCHAR *, ACE_Filecache_Object *, ACE_Hash<const ACE_TCHAR *>, ACE_Equal_To<const ACE_TCHAR *>, ACE_Null_Mutex>;
00751 template class ACE_Hash_Map_Reverse_Iterator_Ex<const ACE_TCHAR *, ACE_Filecache_Object *, ACE_Hash<const ACE_TCHAR *>, ACE_Equal_To<const ACE_TCHAR *>, ACE_Null_Mutex>;
00752 #else
00753 template class ACE_Hash_Map_Entry<ACE_TString, ACE_Filecache_Object *>;
00754 template class ACE_Hash_Map_Manager<ACE_TString, ACE_Filecache_Object *, ACE_Null_Mutex>;
00755 template class ACE_Hash_Map_Iterator<ACE_TString, ACE_Filecache_Object *, ACE_Null_Mutex>;
00756 template class ACE_Hash_Map_Reverse_Iterator<ACE_TString, ACE_Filecache_Object *, ACE_Null_Mutex>;
00757 template class ACE_Hash_Map_Manager_Ex<ACE_TString, ACE_Filecache_Object *, ACE_Hash<ACE_TString>, ACE_Equal_To<ACE_TString>, ACE_Null_Mutex>;
00758 template class ACE_Hash_Map_Iterator_Base_Ex<ACE_TString, ACE_Filecache_Object *, ACE_Hash<ACE_TString>, ACE_Equal_To<ACE_TString>, ACE_Null_Mutex>;
00759 template class ACE_Hash_Map_Iterator_Ex<ACE_TString, ACE_Filecache_Object *, ACE_Hash<ACE_TString>, ACE_Equal_To<ACE_TString>, ACE_Null_Mutex>;
00760 template class ACE_Hash_Map_Reverse_Iterator_Ex<ACE_TString, ACE_Filecache_Object *, ACE_Hash<ACE_TString>, ACE_Equal_To<ACE_TString>, ACE_Null_Mutex>;
00761 #endif
00762 #elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
00763 #if defined (ACE_HAS_TEMPLATE_SPECIALIZATION)
00764 #pragma instantiate ACE_Hash_Map_Entry<const ACE_TCHAR *, ACE_Filecache_Object *>
00765 #pragma instantiate ACE_Hash_Map_Manager<const ACE_TCHAR *, ACE_Filecache_Object *, ACE_Null_Mutex>
00766 #pragma instantiate ACE_Hash_Map_Iterator<const ACE_TCHAR *, ACE_Filecache_Object *, ACE_Null_Mutex>
00767 #pragma instantiate ACE_Hash_Map_Reverse_Iterator<const ACE_TCHAR *, ACE_Filecache_Object *, ACE_Null_Mutex>
00768 #pragma instantiate ACE_Hash_Map_Manager_Ex<const ACE_TCHAR *, ACE_Filecache_Object *, ACE_Hash<const ACE_TCHAR *>, ACE_Equal_To<const ACE_TCHAR *>, ACE_Null_Mutex>
00769 #pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<const ACE_TCHAR *, ACE_Filecache_Object *, ACE_Hash<const ACE_TCHAR *>, ACE_Equal_To<const ACE_TCHAR *>, ACE_Null_Mutex>
00770 #pragma instantiate ACE_Hash_Map_Iterator_Ex<const ACE_TCHAR *, ACE_Filecache_Object *, ACE_Hash<const ACE_TCHAR *>, ACE_Equal_To<const ACE_TCHAR *>, ACE_Null_Mutex>
00771 #pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex<const ACE_TCHAR *, ACE_Filecache_Object *, ACE_Hash<const ACE_TCHAR *>, ACE_Equal_To<const ACE_TCHAR *>, ACE_Null_Mutex>
00772 #else
00773 #pragma instantiate ACE_Hash_Map_Entry<ACE_TString, ACE_Filecache_Object *>
00774 #pragma instantiate ACE_Hash_Map_Manager<ACE_TString, ACE_Filecache_Object *, ACE_Null_Mutex>
00775 #pragma instantiate ACE_Hash_Map_Iterator<ACE_TString, ACE_Filecache_Object *, ACE_Null_Mutex>
00776 #pragma instantiate ACE_Hash_Map_Reverse_Iterator<ACE_TString, ACE_Filecache_Object *, ACE_Null_Mutex>
00777 #pragma instantiate ACE_Hash_Map_Manager_Ex<ACE_TString, ACE_Filecache_Object *, ACE_Hash<ACE_TString>, ACE_Equal_To<ACE_TString>, ACE_Null_Mutex>
00778 #pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<ACE_TString, ACE_Filecache_Object *, ACE_Hash<ACE_TString>, ACE_Equal_To<ACE_TString>, ACE_Null_Mutex>
00779 #pragma instantiate ACE_Hash_Map_Iterator_Ex<ACE_TString, ACE_Filecache_Object *, ACE_Hash<ACE_TString>, ACE_Equal_To<ACE_TString>, ACE_Null_Mutex>
00780 #pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex<ACE_TString, ACE_Filecache_Object *, ACE_Hash<ACE_TString>, ACE_Equal_To<ACE_TString>, ACE_Null_Mutex>
00781 #endif
00782 #endif