⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sbcacheentry.cpp

📁 sloedgy open sip stack source code
💻 CPP
📖 第 1 页 / 共 2 页
字号:
 
 // Create the entry
 VXIcacheResult SBcacheEntryDetails::Create( )
 {
   // Create the mutex
   VXIcacheResult rc = VXIcache_RESULT_SUCCESS;
   if ( _rwMutex.Create(L"SBcacheEntry rw mutex") != VXItrd_RESULT_SUCCESS ) {
     Error (109, L"%s%s", L"mutex", L"cache entry rw mutex");
     rc = VXIcache_RESULT_SYSTEM_ERROR;
   }
 
   return rc;
 }
 
 
 // Open the entry
 VXIcacheResult SBcacheEntryDetails::Open(VXIlogInterface       *log,
 					 const SBcacheString   &moduleName,
 					 const SBcacheKey      &key,
 					 const SBcachePath     &path,
 					 VXIcacheOpenMode       mode,
 					 VXIint32               flags,
 					 VXIulong               maxSizeBytes,
 					 const VXIMap          *properties,
 					 VXIMap                *streamInfo,
 					 VXIcacheStream       **stream)
 {
   VXIcacheResult rc = VXIcache_RESULT_SUCCESS;
   FILE *filePtr = NULL;
 
   // Lock and copy input data
   switch ( mode ) {
   case CACHE_MODE_WRITE:
     if ( _rwMutex.Lock( ) != VXItrd_RESULT_SUCCESS ) {
       Error (log, 110, L"%s%s", L"mutex", L"cache entry rw mutex, writer");
       rc = VXIcache_RESULT_SYSTEM_ERROR;
     } else {
       // If the open fails due to directory not existing, call
       // path.CreateDirectories( ) to create the dir tree then open
       // again
       if ( ! _invalidated ) {
 	filePtr = fopen (path.c_str( ), "wb");
         int retries = 10; // work around possible race condition w/ rmdir
 	while ((retries-- > 0) &&
             ( ! filePtr ) &&
             ( path.CreateDirectories( ) == VXIcache_RESULT_SUCCESS ))
 	  filePtr = fopen (path.c_str( ), "wb");
       }
 
       if ( ! filePtr ) {
 	if ( _invalidated ) {
 	  // Invalidated or another thread attempted an open for write
 	  // and failed, we only got here due to a race condition
 	  // where we were waiting on the mutex to start our write
 	  // before the failure/invalidation happened by the previous
 	  // writer
 	  rc = VXIcache_RESULT_FAILURE;
 	} else {
 	  // File open error
 	  LogIOError (log, 213, path);
 	  rc = VXIcache_RESULT_IO_ERROR;
 	}
 
 	_fileExists = false;
 	_rwMutex.Unlock( );
       } else {
 	_fileExists = true;
 	_creationCost = CACHE_CREATION_COST_DEFAULT;
 	_flags = flags;
 	_sizeBytes = 0;
 
         // Only set the path and key if they differ
         if (path != _path || key != _key) {
           _path = path;
           _key = key;
         }
 
 	// Load properties
 	if ( properties ) {
 	  const VXIValue *value =
 	    VXIMapGetProperty (properties, CACHE_CREATION_COST);
 	  if ( value ) {
 	    if ( VXIValueGetType(value) == VALUE_INTEGER )
 	      _creationCost = (VXIcacheCreationCost)
 		VXIIntegerValue ((const VXIInteger *) value);
 	    else
 	      Error (log, 301, L"%s%d", L"VXIValueType",
 		     VXIValueGetType(value));
 	  }
 	}
       }
     }
     break;
 
   case CACHE_MODE_READ:
     if ( _rwMutex.StartRead( ) != VXItrd_RESULT_SUCCESS ) {
       Error (log, 110, L"%s%s", L"mutex", L"cache entry rw mutex, reader");
       rc = VXIcache_RESULT_SYSTEM_ERROR;
     } else {
       if (( _fileExists ) && ( ! _invalidated )) {
 	filePtr = fopen (_path.c_str( ), "rb");
 	if ( ! filePtr ) {
 	  _fileExists = false;
 	  LogIOError (log, 214, _path);
 	  _rwMutex.EndRead( );
 	  rc = VXIcache_RESULT_IO_ERROR;
 	}
       } else {
 	// Invalidated or another thread attempted an open for write
 	// and failed, we only got here due to a race condition where
 	// we were waiting on the mutex to start our read before the
 	// failure/invalidation happened by the writer
 	_rwMutex.EndRead( );
 	rc = VXIcache_RESULT_FAILURE;
       }
     }
     break;
 
   default:
     Error (log, 215, L"%s%d", L"mode", mode);
     rc = VXIcache_RESULT_UNSUPPORTED;
   }
 
   if ( rc == VXIcache_RESULT_SUCCESS ) {
     // Update the accessed time
     _lastAccessed = time(0);
     if (mode == CACHE_MODE_WRITE)
       _lastModified = _lastAccessed;
 
     // Return stream information
     if ( streamInfo ) {
       if (( VXIMapSetProperty (streamInfo, CACHE_INFO_LAST_MODIFIED,
 			       (VXIValue *) VXIIntegerCreate(_lastModified)) !=
 	    VXIvalue_RESULT_SUCCESS ) ||
 	  ( VXIMapSetProperty (streamInfo, CACHE_INFO_SIZE_BYTES,
 			       (VXIValue *) VXIIntegerCreate (_sizeBytes)) !=
 	    VXIvalue_RESULT_SUCCESS )) {
 	Error (log, 100, NULL);
 	rc = VXIcache_RESULT_OUT_OF_MEMORY;
       }
     }
   }
 
   // Return the stream
   if ( rc == VXIcache_RESULT_SUCCESS ) {
     SBcacheEntry entry(this);
     *stream = new SBcacheStream (log, GetDiagBase( ), moduleName, key,
 				 entry, mode,
 				 ((flags & CACHE_FLAG_NONBLOCKING_IO) == 0),
 				 maxSizeBytes, filePtr);
     if ( ! *stream ) {
       Error (log, 100, NULL);
       fclose (filePtr);
       Close (log, mode, 0, true);
       rc = VXIcache_RESULT_OUT_OF_MEMORY;
     }
   }
 
   Diag (log, SBCACHE_ENTRY_TAGID, L"Open", L"%s, %S, 0x%x, 0x%x: rc = %d",
 	key.c_str( ), path.c_str( ), mode, flags, rc);
   return rc;
 }
 
 
 // Close the entry
 VXIcacheResult SBcacheEntryDetails::Close(VXIlogInterface   *log,
 					  VXIcacheOpenMode   mode,
 					  VXIunsigned        sizeBytes,
 					  bool               invalidate)
 {
   VXIcacheResult rc = VXIcache_RESULT_SUCCESS;
 
   Diag (log, SBCACHE_ENTRY_TAGID, L"Close", L"entering: %s, %S, 0x%x, %u, %d",
 	_key.c_str( ), _path.c_str( ), mode, sizeBytes, invalidate);
 
   // Invalidate the entry if requested to do so, we just set a flag so
   // when the entry is deleted we remove the on-disk copy. Can't just
   // do "_invalidated = invalidate" as there may be multiple readers
   // at once, if one reader thinks we're good (don't invalidate) and
   // another thinks we're bad (invalidate) don't want us to have race
   // conditions where we ignore the invalidate request.
   if ( invalidate )
     _invalidated = true;
 
   // Unlock the entry, note that we should avoid doing anything after
   // the unlock (including logging ) because this object may get
   // deleted as soon as we do so
   switch ( mode ) {
   case CACHE_MODE_WRITE:
     _sizeBytes = sizeBytes;
 
     if ( _rwMutex.Unlock( ) != VXItrd_RESULT_SUCCESS ) {
       Error (log, 111, L"%s%s", L"mutex", L"cache entry rw mutex, writer");
       rc = VXIcache_RESULT_SYSTEM_ERROR;
     }
     break;
 
   case CACHE_MODE_READ:
     if ( _rwMutex.EndRead( ) != VXItrd_RESULT_SUCCESS ) {
       Error (log, 111, L"%s%s", L"mutex", L"cache entry rw mutex, reader");
       rc = VXIcache_RESULT_SYSTEM_ERROR;
     }
     break;
 
   default:
     Error (log, 211, L"%s%d", L"mode", mode);
     rc = VXIcache_RESULT_FATAL_ERROR;
   }
 
   Diag (log, SBCACHE_ENTRY_TAGID, L"Close", L"exiting: rc = %d", rc);
   return rc;
 }
 
 
 // Unlock the entry
 VXIcacheResult SBcacheEntryDetails::Unlock(VXIlogInterface       *log)
 {
   VXIcacheResult rc = VXIcache_RESULT_SUCCESS;
 
   if ( _rwMutex.Lock( ) != VXItrd_RESULT_SUCCESS ) {
     Error (log, 110, L"%s%s", L"mutex", L"cache entry rw mutex, writer");
     rc = VXIcache_RESULT_SYSTEM_ERROR;
   } else {
     if ( _flags & CACHE_FLAG_LOCK )
       _flags = (_flags ^ CACHE_FLAG_LOCK);
     if ( _flags & CACHE_FLAG_LOCK_MEMORY )
       _flags = (_flags ^ CACHE_FLAG_LOCK_MEMORY);
 
     if ( _rwMutex.Unlock( ) != VXItrd_RESULT_SUCCESS ) {
       Error (log, 111, L"%s%s", L"mutex", L"cache entry rw mutex, writer");
       rc = VXIcache_RESULT_SYSTEM_ERROR;
     }
   }
 
   Diag (log, SBCACHE_ENTRY_TAGID, L"Unlock", L"%s, %S: rc = %d",
   	_key.c_str( ), _path.c_str( ), rc);
   return rc;
 }
 
 
 // Delete the on-disk entry, internal routine, no mutex held
 VXIcacheResult SBcacheEntryDetails::DeleteFile( )
 {
   VXIcacheResult rc = VXIcache_RESULT_SUCCESS;
 
   // Delete the file
   if  ( _fileExists ) {
     if ( remove (_path.c_str( )) != 0 )
       LogIOError (216);
 
     // Remove directory
     SBcacheNString head(_path.c_str());
     SBcacheNString::size_type pos = head.find_last_of("/\\");
     if (pos != SBcacheNString::npos) {
       head = head.substr(0, pos);
       if (!head.empty()) {
 #ifdef WIN32
         RemoveDirectory(head.c_str());
 #else
         rmdir(head.c_str());
 #endif
       }
     }
 
     _fileExists = false;
   }
 
   Diag (SBCACHE_ENTRY_TAGID, L"DeleteFile", L"%s, %S: rc = %d",
 	_key.c_str( ), _path.c_str( ), rc);
   return rc;
 }
 
 
 // -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8
 
 
 // Construct a SBcacheEntry from details
 SBcacheEntry::SBcacheEntry (SBcacheEntryDetails *details) : _details(details)
 {
   if ( SBcacheEntryDetails::AddRef (_details) != VXItrd_RESULT_SUCCESS )
     _details = NULL;
 }
 
 
 // Destructor
 SBcacheEntry::~SBcacheEntry( )
 {
   if ( _details )
     SBcacheEntryDetails::Release (&_details);
 }
 
 
 // Create the entry
 VXIcacheResult SBcacheEntry::Create(VXIlogInterface *log,
 				    VXIunsigned diagTagBase,
 				    SBcacheMutex *refCountMutex)
 {
   if ( _details )
     return VXIcache_RESULT_FATAL_ERROR;
 
   VXIcacheResult rc;
   _details = new SBcacheEntryDetails (log, diagTagBase, refCountMutex);
   if ( ! _details ) {
     SBinetLogger::Error (log, MODULE_SBCACHE, 100, NULL);
     rc = VXIcache_RESULT_OUT_OF_MEMORY;
   } else {
     rc = _details->Create( );
   }
 
   return rc;
 }
 
 
 // Open the entry
 VXIcacheResult SBcacheEntry::Open(VXIlogInterface       *log,
 				  const SBcacheString   &moduleName,
 				  const SBcacheKey      &key,
 				  const SBcachePath     &path,
 				  VXIcacheOpenMode       mode,
 				  VXIint32               flags,
 				  VXIulong               maxSizeBytes,
 				  const VXIMap          *properties,
 				  VXIMap                *streamInfo,
 				  VXIcacheStream       **stream)
 {
   return (_details == NULL ? VXIcache_RESULT_FATAL_ERROR :
 	  _details->Open (log, moduleName, key, path, mode, flags,
 			  maxSizeBytes, properties, streamInfo, stream));
 }
 
 
 // Close the entry
 VXIcacheResult SBcacheEntry::Close(VXIlogInterface  *log,
 				   VXIcacheOpenMode  mode,
 				   VXIunsigned       sizeBytes,
 				   bool              invalidate)
 {
   return (_details == NULL ? VXIcache_RESULT_FATAL_ERROR :
 	  _details->Close (log, mode, sizeBytes, invalidate));
 }
 
 
 // Unlock the entry
 VXIcacheResult SBcacheEntry::Unlock(VXIlogInterface       *log)
 {
   return (_details == NULL ? VXIcache_RESULT_FATAL_ERROR :
 	  _details->Unlock (log));
 }
 
 
 // Accessors
 bool SBcacheEntry::IsLocked( ) const
 {
   return _details->IsLocked( );
 }
 
 bool SBcacheEntry::IsExpired (time_t  cutoffTime,
 			      time_t *lastAccessed) const
 {
   return _details->IsExpired (cutoffTime, lastAccessed);
 }
 
 const SBcacheKey & SBcacheEntry::GetKey( ) const
 {
   return _details->GetKey( );
 }
 
 const SBcachePath & SBcacheEntry::GetPath( ) const
 {
   return _details->GetPath( );
 }
 
 VXIulong SBcacheEntry::GetSizeBytes (bool haveEntryOpen) const
 {
   return _details->GetSizeBytes (haveEntryOpen);
 }
 
 
 // Error logging
 VXIlogResult SBcacheEntry::LogIOError (VXIunsigned errorID) const
 {
   return _details->LogIOError (errorID);
 }
 
 
 // Copy constructor and assignment operator that implement reference
 // counting of the held SBcacheEntryData
 SBcacheEntry::SBcacheEntry (const SBcacheEntry & e) : _details(e._details)
 {
   if ( SBcacheEntryDetails::AddRef (_details) != VXItrd_RESULT_SUCCESS )
     _details = NULL;
 }
 
 SBcacheEntry & SBcacheEntry::operator= (const SBcacheEntry & e)
 {
   if ( &e != this ) {
     SBcacheEntryDetails::Release (&_details);
     if ( SBcacheEntryDetails::AddRef (e._details) == VXItrd_RESULT_SUCCESS )
       _details = e._details;
   }
   return *this;
 }
 
 
 // Comparison operators, smaller is defined as a preference for
 // deleting this entry first, equality is having equal preference
 bool SBcacheEntry::operator< (const SBcacheEntry &entry) const
 {
   return _details->operator< (*(entry._details));
 }
 
 bool SBcacheEntry::operator> (const SBcacheEntry &entry) const
 {
   return _details->operator> (*(entry._details));
 }
 
 bool SBcacheEntry::operator== (const SBcacheEntry &entry) const
 {
   return _details->operator== (*(entry._details));
 }
 
 bool SBcacheEntry::operator!= (const SBcacheEntry &entry) const
 {
   return _details->operator!= (*(entry._details));
 }

#endif // P_VXI

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -