Filecache.cpp

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

Generated on Tue Feb 2 17:18:39 2010 for ACE by  doxygen 1.4.7