Filecache.cpp

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

Generated on Thu Nov 9 09:41:51 2006 for ACE by doxygen 1.3.6