Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Filecache.cpp

Go to the documentation of this file.
00001 #include "ace_pch.h"
00002 // $Id: Filecache.cpp,v 1.1.1.4.2.1 2003/03/13 19:44:21 chad Exp $
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 // Specifies no sharing flags.
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 /* __BORLANDC__ */
00018 
00019 #if defined (ACE_WIN32)
00020 // See if you can get rid of some of these.
00021 #define READ_FLAGS (FILE_FLAG_SEQUENTIAL_SCAN | \
00022                     FILE_FLAG_OVERLAPPED | \
00023                     O_RDONLY)
00024 // static const int RCOPY_FLAGS = (FILE_FLAG_SEQUENTIAL_SCAN |
00025 //                                 O_RDONLY);
00026 #define WRITE_FLAGS (FILE_FLAG_SEQUENTIAL_SCAN | \
00027                      FILE_FLAG_OVERLAPPED | \
00028                      O_RDWR | O_CREAT | O_TRUNC)
00029 // static const int WCOPY_FLAGS = (FILE_FLAG_SEQUENTIAL_SCAN |
00030 //                                 O_RDWR | O_CREAT | O_TRUNC);
00031 #else
00032 #define READ_FLAGS O_RDONLY
00033 // static const int RCOPY_FLAGS = O_RDONLY;
00034 #define WRITE_FLAGS (O_RDWR | O_CREAT | O_TRUNC)
00035 // static const int WCOPY_FLAGS = O_RDWR | O_CREAT | O_TRUNC;
00036 #endif /* ACE_WIN32 */
00037 
00038 // static data members
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   // Fetch the file from the Virtual_Filesystem let the
00060   // Virtual_Filesystem do the work of cache coherency.
00061 
00062   // Filecache will also do the acquire, since it holds the lock at
00063   // that time.
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       // Since this is being opened for a write, simply create a new
00079       // ACE_Filecache_Object now, and let the destructor add it into CVF
00080       // later
00081 
00082       // Filecache will also do the acquire, since it holds the lock at
00083       // that time.
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     // this was dup ()'d
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 // ACE_Filecache_Hash
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 // We need these template specializations since KEY is defined as a
00172 // ACE_TCHAR*, which doesn't have a hash() or equal() method defined on it.
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 /* ACE_HAS_TEMPLATE_SPECIALIZATION */
00192 
00193 
00194 // -------------
00195 // ACE_Filecache
00196 // -------------
00197 
00198 ACE_Filecache *
00199 ACE_Filecache::instance (void)
00200 {
00201   // Double check locking pattern.
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       // @@ James, please check each of the ACE_NEW_RETURN calls to
00210       // make sure that it is safe to return if allocation fails.
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       //      ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("   (%t) CVF: creating %s\n"), filename));
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   // Disassociate file from the cache.
00263   if (this->hash_.unbind (filename, handle) == 0)
00264     {
00265       handle->stale_ = 1;
00266 
00267       // Try a lock.  If it succeds, we can delete it now.
00268       // Otherwise, it will clean itself up later.
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   // ACE_SYNCH_RW_MUTEX &filelock = this->file_lock_[loc];
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       // Second check in the method call
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             // Double check locking pattern
00354             ACE_WRITE_GUARD_RETURN (ACE_SYNCH_RW_MUTEX,
00355                                     ace_mon,
00356                                     hashlock,
00357                                     0);
00358 
00359             // Second check in the method call
00360             handle = this->update_i (filename, filelock, mapit);
00361 
00362             if (handle == 0)
00363               filelock.release ();
00364           }
00365         }
00366       //      ACE_DEBUG ((LM_DEBUG,  ACE_LIB_TEXT ("   (%t) CVF: found %s\n"), filename));
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         // Last one using a stale file is resposible for deleting it.
00417         if (file->stale_)
00418           {
00419             // Try a lock.  If it succeds, we can delete it now.
00420             // Otherwise, it will clean itself up later.
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         // Last one using a stale file is resposible for deleting it.
00435         if (file->stale_)
00436           {
00437             // Try a lock.  If it succeds, we can delete it now.
00438             // Otherwise, it will clean itself up later.
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     // stat_ (),
00469     size_ (0),
00470     action_ (0),
00471     error_ (0),
00472     stale_ (0),
00473     // sa_ (),
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     // stat_ (),
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   // ASSERT strlen(filename) < sizeof (this->filename_)
00499   ACE_OS::strcpy (this->filename_, filename);
00500   this->action_ = ACE_Filecache_Object::ACE_READING;
00501   // place ourselves into the READING state
00502 
00503   // Can we access the file?
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   // Can we stat the file?
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   // Can we open the file?
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       // Can we map the file?
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    // Ok, finished!
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   // Can we access the file?
00563   if (ACE_OS::access (this->filename_, R_OK|W_OK) == -1
00564       // Does it exist?
00565       && ACE_OS::access (this->filename_, F_OK) != -1)
00566     {
00567       // File exists, but we cannot access it.
00568       this->error_i (ACE_Filecache_Object::ACE_ACCESS_FAILED);
00569       return;
00570     }
00571 
00572   this->tempname_ = this->filename_;
00573 
00574   // Can we open the file?
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   // Can we write?
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   // Can we map?
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   // Ok, done!
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       // We are safe since only one thread has a writable Filecache_Object
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       // Leave the file in an acquirable state.
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   // The existence of the object means a read lock is being held.
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   // The existence of the object means a read lock is being held.
00695   return this->filename_;
00696 }
00697 
00698 off_t
00699 ACE_Filecache_Object::size (void) const
00700 {
00701   // The existence of the object means a read lock is being held.
00702   return this->size_;
00703 }
00704 
00705 ACE_HANDLE
00706 ACE_Filecache_Object::handle (void) const
00707 {
00708   // The existence of the object means a read lock is being held.
00709   return this->handle_;
00710 }
00711 
00712 void *
00713 ACE_Filecache_Object::address (void) const
00714 {
00715   // The existence of the object means a read lock is being held.
00716   return this->mmap_.addr ();
00717 }
00718 
00719 int
00720 ACE_Filecache_Object::update (void) const
00721 {
00722   // The existence of the object means a read lock is being held.
00723   int result;
00724   ACE_stat statbuf;
00725 
00726   if (ACE_OS::stat (this->filename_, &statbuf) == -1)
00727     result = 1;
00728   else
00729     // non-portable code may follow
00730 #if defined (ACE_HAS_WINCE)
00731     // Yup, non-portable... there's probably a way to safely implement
00732     // difftime() on WinCE, but for now, this will have to do. It flags
00733     // every file as having changed since cached.
00734     result = 1;
00735 #else
00736     result = ACE_OS::difftime (this->stat_.st_mtime, statbuf.st_mtime) < 0;
00737 #endif /* ACE_HAS_WINCE */
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 /* ACE_HAS_TEMPLATE_SPECIALIZATION */
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 /* ACE_HAS_TEMPLATE_SPECIALIZATION */
00782 #endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */

Generated on Mon Jun 16 11:19:42 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002