Bug 897723 - Allow faulty.lib's on-demand decompression to be reentrant. r=nfroyd

This commit is contained in:
Mike Hommey 2013-07-26 12:57:53 +09:00
Родитель 1591b955e1
Коммит 92fbf52fbf
2 изменённых файлов: 20 добавлений и 3 удалений

Просмотреть файл

@ -344,7 +344,11 @@ MappableSeekableZStream::Create(const char *name, Zip *zip,
mozilla::ScopedDeletePtr<MappableSeekableZStream> mappable;
mappable = new MappableSeekableZStream(zip);
if (pthread_mutex_init(&mappable->mutex, NULL))
pthread_mutexattr_t recursiveAttr;
pthread_mutexattr_init(&recursiveAttr);
pthread_mutexattr_settype(&recursiveAttr, PTHREAD_MUTEX_RECURSIVE);
if (pthread_mutex_init(&mappable->mutex, &recursiveAttr))
return NULL;
if (!mappable->zStream.Init(stream->GetBuffer(), stream->GetSize()))
@ -466,6 +470,19 @@ MappableSeekableZStream::ensure(const void *addr)
length = PageAlignedSize(length);
/* The following lock can be re-acquired by the thread holding it.
* If this happens, it means the following code is interrupted somehow by
* some signal, and ends up retriggering a chunk decompression for the
* same MappableSeekableZStream.
* If the chunk to decompress is different the second time, then everything
* is safe as the only common data touched below is chunkAvailNum, and it is
* atomically updated (leaving out any chance of an interruption while it is
* updated affecting the result). If the chunk to decompress is the same, the
* worst thing that can happen is chunkAvailNum being incremented one too
* many times, which doesn't affect functionality. The chances of it
* happening being pretty slim, and the effect being harmless, we can just
* ignore the issue. Other than that, we'd just be wasting time decompressing
* the same chunk twice. */
AutoLock lock(&mutex);
/* The very first page is mapped and accessed separately of the rest, and
@ -522,7 +539,7 @@ MappableSeekableZStream::stats(const char *when, const char *name) const
{
size_t nEntries = zStream.GetChunksNum();
DEBUG_LOG("%s: %s; %" PRIdSize "/%" PRIdSize " chunks decompressed",
name, when, chunkAvailNum, nEntries);
name, when, static_cast<size_t>(chunkAvailNum), nEntries);
size_t len = 64;
mozilla::ScopedDeleteArray<char> map;

Просмотреть файл

@ -265,7 +265,7 @@ private:
mozilla::ScopedDeleteArray<unsigned char> chunkAvail;
/* Number of chunks that have already been decompressed. */
size_t chunkAvailNum;
mozilla::Atomic<size_t> chunkAvailNum;
/* Mutex protecting decompression */
pthread_mutex_t mutex;