PageRenderTime 27ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 0ms

/dep/acelite/ace/Filecache.cpp

https://github.com/chucho/FaceCore
C++ | 742 lines | 556 code | 115 blank | 71 comment | 86 complexity | a23eaab396ccc67f3346db3afab9b987 MD5 | raw file
  1. // $Id: Filecache.cpp 91368 2010-08-16 13:03:34Z mhengstmengel $
  2. #include "ace/Filecache.h"
  3. #include "ace/Object_Manager.h"
  4. #include "ace/Log_Msg.h"
  5. #include "ace/ACE.h"
  6. #include "ace/Guard_T.h"
  7. #include "ace/OS_NS_string.h"
  8. #include "ace/OS_NS_time.h"
  9. #include "ace/OS_NS_unistd.h"
  10. #include "ace/OS_NS_fcntl.h"
  11. #include "ace/Truncate.h"
  12. #if defined (ACE_WIN32)
  13. // Specifies no sharing flags.
  14. #define R_MASK ACE_DEFAULT_OPEN_PERMS
  15. #define W_MASK 0
  16. #else
  17. #define R_MASK S_IRUSR|S_IRGRP|S_IROTH
  18. #define W_MASK S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR|S_IWGRP|S_IWOTH
  19. #endif /* ACE_WIN32 */
  20. #if defined (ACE_WIN32)
  21. // See if you can get rid of some of these.
  22. #define READ_FLAGS (FILE_FLAG_SEQUENTIAL_SCAN | \
  23. FILE_FLAG_OVERLAPPED | \
  24. O_RDONLY)
  25. // static const int RCOPY_FLAGS = (FILE_FLAG_SEQUENTIAL_SCAN |
  26. // O_RDONLY);
  27. #define WRITE_FLAGS (FILE_FLAG_SEQUENTIAL_SCAN | \
  28. FILE_FLAG_OVERLAPPED | \
  29. O_RDWR | O_CREAT | O_TRUNC)
  30. // static const int WCOPY_FLAGS = (FILE_FLAG_SEQUENTIAL_SCAN |
  31. // O_RDWR | O_CREAT | O_TRUNC);
  32. #else
  33. #define READ_FLAGS O_RDONLY
  34. // static const int RCOPY_FLAGS = O_RDONLY;
  35. #define WRITE_FLAGS (O_RDWR | O_CREAT | O_TRUNC)
  36. // static const int WCOPY_FLAGS = O_RDWR | O_CREAT | O_TRUNC;
  37. #endif /* ACE_WIN32 */
  38. ACE_BEGIN_VERSIONED_NAMESPACE_DECL
  39. // static data members
  40. ACE_Filecache *ACE_Filecache::cvf_ = 0;
  41. void
  42. ACE_Filecache_Handle::init (void)
  43. {
  44. this->file_ = 0;
  45. this->handle_ = ACE_INVALID_HANDLE;
  46. }
  47. ACE_Filecache_Handle::ACE_Filecache_Handle (void)
  48. : file_ (0), handle_ (0), mapit_ (0)
  49. {
  50. this->init ();
  51. }
  52. ACE_Filecache_Handle::ACE_Filecache_Handle (const ACE_TCHAR *filename,
  53. ACE_Filecache_Flag mapit)
  54. : file_ (0), handle_ (0), mapit_ (mapit)
  55. {
  56. this->init ();
  57. // Fetch the file from the Virtual_Filesystem let the
  58. // Virtual_Filesystem do the work of cache coherency.
  59. // Filecache will also do the acquire, since it holds the lock at
  60. // that time.
  61. this->file_ = ACE_Filecache::instance ()->fetch (filename, mapit);
  62. }
  63. ACE_Filecache_Handle::ACE_Filecache_Handle (const ACE_TCHAR *filename,
  64. int size,
  65. ACE_Filecache_Flag mapit)
  66. : file_ (0), handle_ (0), mapit_ (mapit)
  67. {
  68. this->init ();
  69. if (size == 0)
  70. ACE_Filecache::instance ()->remove (filename);
  71. else
  72. {
  73. // Since this is being opened for a write, simply create a new
  74. // ACE_Filecache_Object now, and let the destructor add it into CVF
  75. // later
  76. // Filecache will also do the acquire, since it holds the lock at
  77. // that time.
  78. this->file_ = ACE_Filecache::instance ()->create (filename, size);
  79. }
  80. }
  81. ACE_Filecache_Handle::~ACE_Filecache_Handle (void)
  82. {
  83. if (this->handle_ != ACE_INVALID_HANDLE)
  84. // this was dup ()'d
  85. ACE_OS::close (this->handle_);
  86. ACE_Filecache::instance ()->finish (this->file_);
  87. }
  88. void *
  89. ACE_Filecache_Handle::address (void) const
  90. {
  91. return this->file_ == 0 ? 0 : this->file_->address ();
  92. }
  93. ACE_HANDLE
  94. ACE_Filecache_Handle::handle (void) const
  95. {
  96. if (this->handle_ == ACE_INVALID_HANDLE && this->file_ != 0)
  97. {
  98. ACE_Filecache_Handle *mutable_this =
  99. const_cast<ACE_Filecache_Handle *> (this);
  100. mutable_this->handle_ = ACE_OS::dup (this->file_->handle ());
  101. }
  102. return this->handle_;
  103. }
  104. int
  105. ACE_Filecache_Handle::error (void) const
  106. {
  107. if (this->file_ == 0)
  108. return -1;
  109. else
  110. return this->file_->error ();
  111. }
  112. ACE_OFF_T
  113. ACE_Filecache_Handle::size (void) const
  114. {
  115. if (this->file_ == 0)
  116. return -1;
  117. else
  118. return this->file_->size ();
  119. }
  120. // ------------------
  121. // ACE_Filecache_Hash
  122. // ------------------
  123. #define ACE_Filecache_Hash \
  124. 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>
  125. #define ACE_Filecache_Hash_Entry \
  126. ACE_Hash_Map_Entry<const ACE_TCHAR *, ACE_Filecache_Object *>
  127. template <>
  128. ACE_Filecache_Hash_Entry::ACE_Hash_Map_Entry (
  129. const ACE_TCHAR *const &ext_id,
  130. ACE_Filecache_Object *const &int_id,
  131. ACE_Filecache_Hash_Entry *next,
  132. ACE_Filecache_Hash_Entry *prev)
  133. : ext_id_ (ext_id
  134. ? ACE_OS::strdup (ext_id)
  135. : ACE_OS::strdup (ACE_TEXT (""))),
  136. int_id_ (int_id),
  137. next_ (next),
  138. prev_ (prev)
  139. {
  140. }
  141. template <>
  142. ACE_Filecache_Hash_Entry::ACE_Hash_Map_Entry (ACE_Filecache_Hash_Entry *next,
  143. ACE_Filecache_Hash_Entry *prev)
  144. : ext_id_ (0),
  145. next_ (next),
  146. prev_ (prev)
  147. {
  148. }
  149. template <>
  150. ACE_Filecache_Hash_Entry::~ACE_Hash_Map_Entry (void)
  151. {
  152. ACE_OS::free ((void *) ext_id_);
  153. }
  154. // We need these template specializations since KEY is defined as a
  155. // ACE_TCHAR*, which doesn't have a hash() or equal() method defined on it.
  156. template <>
  157. unsigned long
  158. ACE_Filecache_Hash::hash (const ACE_TCHAR *const &ext_id)
  159. {
  160. return ACE::hash_pjw (ext_id);
  161. }
  162. template <>
  163. int
  164. ACE_Filecache_Hash::equal (const ACE_TCHAR *const &id1,
  165. const ACE_TCHAR *const &id2)
  166. {
  167. return ACE_OS::strcmp (id1, id2) == 0;
  168. }
  169. #undef ACE_Filecache_Hash
  170. #undef ACE_Filecache_Hash_Entry
  171. // -------------
  172. // ACE_Filecache
  173. // -------------
  174. ACE_Filecache *
  175. ACE_Filecache::instance (void)
  176. {
  177. // Double check locking pattern.
  178. if (ACE_Filecache::cvf_ == 0)
  179. {
  180. ACE_SYNCH_RW_MUTEX &lock =
  181. *ACE_Managed_Object<ACE_SYNCH_RW_MUTEX>::get_preallocated_object
  182. (ACE_Object_Manager::ACE_FILECACHE_LOCK);
  183. ACE_GUARD_RETURN (ACE_SYNCH_RW_MUTEX, ace_mon, lock, 0);
  184. // @@ James, please check each of the ACE_NEW_RETURN calls to
  185. // make sure that it is safe to return if allocation fails.
  186. if (ACE_Filecache::cvf_ == 0)
  187. ACE_NEW_RETURN (ACE_Filecache::cvf_,
  188. ACE_Filecache,
  189. 0);
  190. }
  191. return ACE_Filecache::cvf_;
  192. }
  193. ACE_Filecache::ACE_Filecache (void)
  194. : size_ (ACE_DEFAULT_VIRTUAL_FILESYSTEM_TABLE_SIZE),
  195. hash_ (size_)
  196. {
  197. }
  198. ACE_Filecache::~ACE_Filecache (void)
  199. {
  200. }
  201. ACE_Filecache_Object *
  202. ACE_Filecache::insert_i (const ACE_TCHAR *filename,
  203. ACE_SYNCH_RW_MUTEX &filelock,
  204. int mapit)
  205. {
  206. ACE_Filecache_Object *handle = 0;
  207. if (this->hash_.find (filename, handle) == -1)
  208. {
  209. ACE_NEW_RETURN (handle,
  210. ACE_Filecache_Object (filename, filelock, 0, mapit),
  211. 0);
  212. // ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" (%t) CVF: creating %s\n"), filename));
  213. if (this->hash_.bind (filename, handle) == -1)
  214. {
  215. delete handle;
  216. handle = 0;
  217. }
  218. }
  219. else
  220. handle = 0;
  221. return handle;
  222. }
  223. ACE_Filecache_Object *
  224. ACE_Filecache::remove_i (const ACE_TCHAR *filename)
  225. {
  226. ACE_Filecache_Object *handle = 0;
  227. // Disassociate file from the cache.
  228. if (this->hash_.unbind (filename, handle) == 0)
  229. {
  230. handle->stale_ = 1;
  231. // Try a lock. If it succeeds, we can delete it now.
  232. // Otherwise, it will clean itself up later.
  233. if (handle->lock_.tryacquire_write () == 0)
  234. {
  235. delete handle;
  236. handle = 0;
  237. }
  238. }
  239. else
  240. handle = 0;
  241. return handle;
  242. }
  243. ACE_Filecache_Object *
  244. ACE_Filecache::update_i (const ACE_TCHAR *filename,
  245. ACE_SYNCH_RW_MUTEX &filelock,
  246. int mapit)
  247. {
  248. ACE_Filecache_Object *handle = 0;
  249. handle = this->remove_i (filename);
  250. handle = this->insert_i (filename, filelock, mapit);
  251. return handle;
  252. }
  253. int
  254. ACE_Filecache::find (const ACE_TCHAR *filename)
  255. {
  256. return this->hash_.find (filename);
  257. }
  258. ACE_Filecache_Object *
  259. ACE_Filecache::remove (const ACE_TCHAR *filename)
  260. {
  261. ACE_Filecache_Object *handle = 0;
  262. ACE_OFF_T loc = ACE::hash_pjw (filename) % this->size_;
  263. ACE_SYNCH_RW_MUTEX &hashlock = this->hash_lock_[loc];
  264. // ACE_SYNCH_RW_MUTEX &filelock = this->file_lock_[loc];
  265. if (this->hash_.find (filename, handle) != -1)
  266. {
  267. ACE_WRITE_GUARD_RETURN (ACE_SYNCH_RW_MUTEX,
  268. ace_mon,
  269. hashlock,
  270. 0);
  271. return this->remove_i (filename);
  272. }
  273. return 0;
  274. }
  275. ACE_Filecache_Object *
  276. ACE_Filecache::fetch (const ACE_TCHAR *filename, int mapit)
  277. {
  278. ACE_Filecache_Object *handle = 0;
  279. ACE_OFF_T loc = ACE::hash_pjw (filename) % this->size_;
  280. ACE_SYNCH_RW_MUTEX &hashlock = this->hash_lock_[loc];
  281. ACE_SYNCH_RW_MUTEX &filelock = this->file_lock_[loc];
  282. filelock.acquire_read ();
  283. if (this->hash_.find (filename, handle) == -1)
  284. {
  285. ACE_WRITE_GUARD_RETURN (ACE_SYNCH_RW_MUTEX,
  286. ace_mon,
  287. hashlock,
  288. 0);
  289. // Second check in the method call
  290. handle = this->insert_i (filename, filelock, mapit);
  291. if (handle == 0)
  292. filelock.release ();
  293. }
  294. else
  295. {
  296. if (handle->update ())
  297. {
  298. {
  299. // Double check locking pattern
  300. ACE_WRITE_GUARD_RETURN (ACE_SYNCH_RW_MUTEX,
  301. ace_mon,
  302. hashlock,
  303. 0);
  304. // Second check in the method call
  305. handle = this->update_i (filename, filelock, mapit);
  306. if (handle == 0)
  307. filelock.release ();
  308. }
  309. }
  310. // ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" (%t) CVF: found %s\n"), filename));
  311. }
  312. return handle;
  313. }
  314. ACE_Filecache_Object *
  315. ACE_Filecache::create (const ACE_TCHAR *filename, int size)
  316. {
  317. ACE_Filecache_Object *handle = 0;
  318. ACE_OFF_T loc = ACE::hash_pjw (filename) % this->size_;
  319. ACE_SYNCH_RW_MUTEX &filelock = this->file_lock_[loc];
  320. ACE_NEW_RETURN (handle,
  321. ACE_Filecache_Object (filename, size, filelock),
  322. 0);
  323. handle->acquire ();
  324. return handle;
  325. }
  326. ACE_Filecache_Object *
  327. ACE_Filecache::finish (ACE_Filecache_Object *&file)
  328. {
  329. if (file == 0)
  330. return file;
  331. ACE_OFF_T loc = ACE::hash_pjw (file->filename_) % this->size_;
  332. ACE_SYNCH_RW_MUTEX &hashlock = this->hash_lock_[loc];
  333. if (file != 0)
  334. switch (file->action_)
  335. {
  336. case ACE_Filecache_Object::ACE_WRITING:
  337. {
  338. ACE_WRITE_GUARD_RETURN (ACE_SYNCH_RW_MUTEX,
  339. ace_mon,
  340. hashlock,
  341. 0);
  342. file->release ();
  343. this->remove_i (file->filename_);
  344. #if 0
  345. int result = this->hash_.bind (file->filename (), file);
  346. if (result == 0)
  347. file->acquire ();
  348. #else
  349. // Last one using a stale file is resposible for deleting it.
  350. if (file->stale_)
  351. {
  352. // Try a lock. If it succeds, we can delete it now.
  353. // Otherwise, it will clean itself up later.
  354. if (file->lock_.tryacquire_write () == 0)
  355. {
  356. delete file;
  357. file = 0;
  358. }
  359. }
  360. #endif
  361. }
  362. break;
  363. default:
  364. file->release ();
  365. // Last one using a stale file is resposible for deleting it.
  366. if (file->stale_)
  367. {
  368. // Try a lock. If it succeds, we can delete it now.
  369. // Otherwise, it will clean itself up later.
  370. if (file->lock_.tryacquire_write () == 0)
  371. {
  372. delete file;
  373. file = 0;
  374. }
  375. }
  376. break;
  377. }
  378. return file;
  379. }
  380. void
  381. ACE_Filecache_Object::init (void)
  382. {
  383. this->filename_[0] = '\0';
  384. this->handle_ = ACE_INVALID_HANDLE;
  385. this->error_ = ACE_SUCCESS;
  386. this->tempname_ = 0;
  387. this->size_ = 0;
  388. ACE_OS::memset (&(this->stat_), 0, sizeof (this->stat_));
  389. }
  390. ACE_Filecache_Object::ACE_Filecache_Object (void)
  391. : tempname_ (0),
  392. mmap_ (),
  393. handle_ (0),
  394. // stat_ (),
  395. size_ (0),
  396. action_ (0),
  397. error_ (0),
  398. stale_ (0),
  399. // sa_ (),
  400. junklock_ (),
  401. lock_ (junklock_)
  402. {
  403. this->init ();
  404. }
  405. ACE_Filecache_Object::ACE_Filecache_Object (const ACE_TCHAR *filename,
  406. ACE_SYNCH_RW_MUTEX &lock,
  407. LPSECURITY_ATTRIBUTES sa,
  408. int mapit)
  409. : tempname_ (0),
  410. mmap_ (),
  411. handle_ (0),
  412. // stat_ (),
  413. size_ (0),
  414. action_ (0),
  415. error_ (0),
  416. stale_ (0),
  417. sa_ (sa),
  418. junklock_ (),
  419. lock_ (lock)
  420. {
  421. this->init ();
  422. // ASSERT strlen(filename) < sizeof (this->filename_)
  423. ACE_OS::strcpy (this->filename_, filename);
  424. this->action_ = ACE_Filecache_Object::ACE_READING;
  425. // place ourselves into the READING state
  426. // Can we access the file?
  427. if (ACE_OS::access (this->filename_, R_OK) == -1)
  428. {
  429. this->error_i (ACE_Filecache_Object::ACE_ACCESS_FAILED);
  430. return;
  431. }
  432. // Can we stat the file?
  433. if (ACE_OS::stat (this->filename_, &this->stat_) == -1)
  434. {
  435. this->error_i (ACE_Filecache_Object::ACE_STAT_FAILED);
  436. return;
  437. }
  438. this->size_ = ACE_Utils::truncate_cast<ACE_OFF_T> (this->stat_.st_size);
  439. this->tempname_ = this->filename_;
  440. // Can we open the file?
  441. this->handle_ = ACE_OS::open (this->tempname_,
  442. READ_FLAGS, R_MASK, this->sa_);
  443. if (this->handle_ == ACE_INVALID_HANDLE)
  444. {
  445. this->error_i (ACE_Filecache_Object::ACE_OPEN_FAILED,
  446. ACE_TEXT ("ACE_Filecache_Object::ctor: open"));
  447. return;
  448. }
  449. if (mapit)
  450. {
  451. // Can we map the file?
  452. if (this->mmap_.map (this->handle_, static_cast<size_t> (-1),
  453. PROT_READ, ACE_MAP_PRIVATE, 0, 0, this->sa_) != 0)
  454. {
  455. this->error_i (ACE_Filecache_Object::ACE_MEMMAP_FAILED,
  456. ACE_TEXT ("ACE_Filecache_Object::ctor: map"));
  457. ACE_OS::close (this->handle_);
  458. this->handle_ = ACE_INVALID_HANDLE;
  459. return;
  460. }
  461. }
  462. // Ok, finished!
  463. this->action_ = ACE_Filecache_Object::ACE_READING;
  464. }
  465. ACE_Filecache_Object::ACE_Filecache_Object (const ACE_TCHAR *filename,
  466. ACE_OFF_T size,
  467. ACE_SYNCH_RW_MUTEX &lock,
  468. LPSECURITY_ATTRIBUTES sa)
  469. : stale_ (0),
  470. sa_ (sa),
  471. lock_ (lock)
  472. {
  473. this->init ();
  474. this->size_ = size;
  475. ACE_OS::strcpy (this->filename_, filename);
  476. this->action_ = ACE_Filecache_Object::ACE_WRITING;
  477. // Can we access the file?
  478. if (ACE_OS::access (this->filename_, R_OK|W_OK) == -1
  479. // Does it exist?
  480. && ACE_OS::access (this->filename_, F_OK) != -1)
  481. {
  482. // File exists, but we cannot access it.
  483. this->error_i (ACE_Filecache_Object::ACE_ACCESS_FAILED);
  484. return;
  485. }
  486. this->tempname_ = this->filename_;
  487. // Can we open the file?
  488. this->handle_ = ACE_OS::open (this->tempname_, WRITE_FLAGS, W_MASK, this->sa_);
  489. if (this->handle_ == ACE_INVALID_HANDLE)
  490. {
  491. this->error_i (ACE_Filecache_Object::ACE_OPEN_FAILED,
  492. ACE_TEXT ("ACE_Filecache_Object::acquire: open"));
  493. return;
  494. }
  495. // Can we write?
  496. if (ACE_OS::pwrite (this->handle_, "", 1, this->size_ - 1) != 1)
  497. {
  498. this->error_i (ACE_Filecache_Object::ACE_WRITE_FAILED,
  499. ACE_TEXT ("ACE_Filecache_Object::acquire: write"));
  500. ACE_OS::close (this->handle_);
  501. return;
  502. }
  503. // Can we map?
  504. if (this->mmap_.map (this->handle_, this->size_, PROT_RDWR, MAP_SHARED,
  505. 0, 0, this->sa_) != 0)
  506. {
  507. this->error_i (ACE_Filecache_Object::ACE_MEMMAP_FAILED,
  508. ACE_TEXT ("ACE_Filecache_Object::acquire: map"));
  509. ACE_OS::close (this->handle_);
  510. }
  511. // Ok, done!
  512. }
  513. ACE_Filecache_Object::~ACE_Filecache_Object (void)
  514. {
  515. if (this->error_ == ACE_SUCCESS)
  516. {
  517. this->mmap_.unmap ();
  518. ACE_OS::close (this->handle_);
  519. this->handle_ = ACE_INVALID_HANDLE;
  520. }
  521. this->lock_.release ();
  522. }
  523. int
  524. ACE_Filecache_Object::acquire (void)
  525. {
  526. return this->lock_.tryacquire_read ();
  527. }
  528. int
  529. ACE_Filecache_Object::release (void)
  530. {
  531. if (this->action_ == ACE_WRITING)
  532. {
  533. // We are safe since only one thread has a writable Filecache_Object
  534. #if 0
  535. ACE_HANDLE original = ACE_OS::open (this->filename_, WRITE_FLAGS, W_MASK,
  536. this->sa_);
  537. if (original == ACE_INVALID_HANDLE)
  538. this->error_ = ACE_Filecache_Object::ACE_OPEN_FAILED;
  539. else if (ACE_OS::write (original, this->mmap_.addr (),
  540. this->size_) == -1)
  541. {
  542. this->error_ = ACE_Filecache_Object::ACE_WRITE_FAILED;
  543. ACE_OS::close (original);
  544. ACE_OS::unlink (this->filename_);
  545. }
  546. else if (ACE_OS::stat (this->filename_, &this->stat_) == -1)
  547. this->error_ = ACE_Filecache_Object::ACE_STAT_FAILED;
  548. #endif
  549. this->mmap_.unmap ();
  550. ACE_OS::close (this->handle_);
  551. this->handle_ = ACE_INVALID_HANDLE;
  552. #if 0
  553. // Leave the file in an acquirable state.
  554. this->handle_ = ACE_OS::open (this->tempname_, READ_FLAGS, R_MASK);
  555. if (this->handle_ == ACE_INVALID_HANDLE)
  556. {
  557. this->error_i (ACE_Filecache_Object::ACE_OPEN_FAILED,
  558. "ACE_Filecache_Object::acquire: open");
  559. }
  560. else if (this->mmap_.map (this->handle_, -1,
  561. PROT_READ,
  562. ACE_MAP_PRIVATE,
  563. 0,
  564. 0,
  565. this->sa_) != 0)
  566. {
  567. this->error_i (ACE_Filecache_Object::ACE_MEMMAP_FAILED,
  568. "ACE_Filecache_Object::acquire: map");
  569. ACE_OS::close (this->handle_);
  570. this->handle_ = ACE_INVALID_HANDLE;
  571. }
  572. this->action_ = ACE_Filecache_Object::ACE_READING;
  573. #endif
  574. }
  575. return this->lock_.release ();
  576. }
  577. int
  578. ACE_Filecache_Object::error (void) const
  579. {
  580. // The existence of the object means a read lock is being held.
  581. return this->error_;
  582. }
  583. int
  584. ACE_Filecache_Object::error_i (int error_value, const ACE_TCHAR *s)
  585. {
  586. s = s;
  587. ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p.\n"), s));
  588. this->error_ = error_value;
  589. return error_value;
  590. }
  591. const ACE_TCHAR *
  592. ACE_Filecache_Object::filename (void) const
  593. {
  594. // The existence of the object means a read lock is being held.
  595. return this->filename_;
  596. }
  597. ACE_OFF_T
  598. ACE_Filecache_Object::size (void) const
  599. {
  600. // The existence of the object means a read lock is being held.
  601. return this->size_;
  602. }
  603. ACE_HANDLE
  604. ACE_Filecache_Object::handle (void) const
  605. {
  606. // The existence of the object means a read lock is being held.
  607. return this->handle_;
  608. }
  609. void *
  610. ACE_Filecache_Object::address (void) const
  611. {
  612. // The existence of the object means a read lock is being held.
  613. return this->mmap_.addr ();
  614. }
  615. int
  616. ACE_Filecache_Object::update (void) const
  617. {
  618. // The existence of the object means a read lock is being held.
  619. int result;
  620. ACE_stat statbuf;
  621. if (ACE_OS::stat (this->filename_, &statbuf) == -1)
  622. result = 1;
  623. else
  624. result = ACE_OS::difftime (this->stat_.st_mtime, statbuf.st_mtime) < 0;
  625. return result;
  626. }
  627. ACE_END_VERSIONED_NAMESPACE_DECL