☠☠ backed out by e4e4f6e4f952 ☠ ☠ | |
author | ISHIKAWA, Chiaki <ishikawa@yk.rim.or.jp> |
Sun, 21 Jun 2015 05:54:00 +0200 | |
changeset 251726 | f83eddcbebbc4c2c9554bb2a929f0f25bc6c563d |
parent 251725 | 004e123383ae3ce5c6332b684d7a16ce6b2f5185 |
child 251727 | 89ef09135c286244cde0ec474fc971fb4105f70b |
push id | 29007 |
push user | ryanvm@gmail.com |
push date | Tue, 07 Jul 2015 18:38:06 +0000 |
treeherder | mozilla-central@9340658848d1 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | michal |
bugs | 1170646 |
milestone | 42.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/netwerk/cache/nsDiskCacheBlockFile.cpp +++ b/netwerk/cache/nsDiskCacheBlockFile.cpp @@ -8,16 +8,43 @@ #include "nsDiskCache.h" #include "nsDiskCacheBlockFile.h" #include "mozilla/FileUtils.h" #include "mozilla/MemoryReporting.h" #include <algorithm> using namespace mozilla; +/* to cope with short read. + * xxx not sure if we want to repeat PR_Read() if no octet is ever read + * and is errno == EINTR + */ +static +ssize_t +busy_beaver_PR_Read(PRFileDesc *fd, void * start, PRInt32 len) +{ + int n; + PRInt32 remaining = len; + + while (remaining > 0) { + n = PR_Read(fd, start, remaining); + if (n < 0) { + if( (len - remaining) == 0 ) // no octet is ever read + return -1; + break; + } else { + remaining -= n; + char *cp = (char *) start; + cp += n; + start = cp; + } + } + return len - remaining; +} + /****************************************************************************** * nsDiskCacheBlockFile - *****************************************************************************/ /****************************************************************************** * Open *****************************************************************************/ nsresult @@ -69,17 +96,17 @@ nsDiskCacheBlockFile::Open(nsIFile * blo } else if ((uint32_t)mFileSize < bitMapBytes) { *corruptInfo = nsDiskCache::kBlockFileSizeLessThanBitMap; rv = NS_ERROR_UNEXPECTED; // XXX NS_ERROR_CACHE_INVALID; goto error_exit; } else { // read the bit map - const int32_t bytesRead = PR_Read(mFD, mBitMap, bitMapBytes); + const int32_t bytesRead = busy_beaver_PR_Read(mFD, mBitMap, bitMapBytes); if ((bytesRead < 0) || ((uint32_t)bytesRead < bitMapBytes)) { *corruptInfo = nsDiskCache::kBlockFileBitMapReadError; rv = NS_ERROR_UNEXPECTED; goto error_exit; } #if defined(IS_LITTLE_ENDIAN) // Swap from network format for (unsigned int i = 0; i < mBitMapWords; ++i) @@ -248,21 +275,25 @@ nsDiskCacheBlockFile::ReadBlocks( void * int32_t filePos = PR_Seek(mFD, blockPos, PR_SEEK_SET); if (filePos != blockPos) return NS_ERROR_UNEXPECTED; // read the blocks int32_t bytesToRead = *bytesRead; if ((bytesToRead <= 0) || ((uint32_t)bytesToRead > mBlockSize * numBlocks)) { bytesToRead = mBlockSize * numBlocks; } - *bytesRead = PR_Read(mFD, buffer, bytesToRead); - + /* This has to tolerate short read, i.e., we need to repeat! */ + *bytesRead = busy_beaver_PR_Read(mFD, buffer, bytesToRead); + CACHE_LOG_DEBUG(("CACHE: nsDiskCacheBlockFile::Read [this=%p] " "returned %d / %d bytes", this, *bytesRead, bytesToRead)); + if(*bytesRead == -1) + return NS_ERROR_UNEXPECTED; + return NS_OK; } /****************************************************************************** * FlushBitMap *****************************************************************************/ nsresult