diff options
Diffstat (limited to 'package/source/zipapi/ZipOutputStream.cxx')
-rw-r--r-- | package/source/zipapi/ZipOutputStream.cxx | 100 |
1 files changed, 74 insertions, 26 deletions
diff --git a/package/source/zipapi/ZipOutputStream.cxx b/package/source/zipapi/ZipOutputStream.cxx index 7d8378261666..8cd8b9056989 100644 --- a/package/source/zipapi/ZipOutputStream.cxx +++ b/package/source/zipapi/ZipOutputStream.cxx @@ -93,42 +93,90 @@ void ZipOutputStream::rawCloseEntry( bool bEncrypt ) m_pCurrentEntry = nullptr; } -void ZipOutputStream::finish() - throw(IOException, RuntimeException) +void ZipOutputStream::consumeScheduledThreadEntry(ZipOutputEntry* pCandidate) { - assert(!m_aZipList.empty() && "Zip file must have at least one entry!"); + //Any exceptions thrown in the threads were caught and stored for now + ::css::uno::Any aCaughtException(pCandidate->getParallelDeflateException()); + if (aCaughtException.hasValue()) + ::cppu::throwException(aCaughtException); - // Wait for all threads to finish & write - m_rSharedThreadPool.waitUntilEmpty(); - for (size_t i = 0; i < m_aEntries.size(); i++) + writeLOC(pCandidate->getZipEntry(), pCandidate->isEncrypt()); + + sal_Int32 nRead; + uno::Sequence< sal_Int8 > aSequence(n_ConstBufferSize); + uno::Reference< io::XInputStream > xInput = pCandidate->getData(); + do { - //Any exceptions thrown in the threads were caught and stored for now - ::css::uno::Any aCaughtException(m_aEntries[i]->getParallelDeflateException()); - if (aCaughtException.hasValue()) - ::cppu::throwException(aCaughtException); + nRead = xInput->readBytes(aSequence, n_ConstBufferSize); + if (nRead < n_ConstBufferSize) + aSequence.realloc(nRead); - writeLOC(m_aEntries[i]->getZipEntry(), m_aEntries[i]->isEncrypt()); + rawWrite(aSequence); + } + while (nRead == n_ConstBufferSize); + xInput.clear(); - sal_Int32 nRead; - uno::Sequence< sal_Int8 > aSequence(n_ConstBufferSize); - uno::Reference< io::XInputStream > xInput = m_aEntries[i]->getData(); - do - { - nRead = xInput->readBytes(aSequence, n_ConstBufferSize); - if (nRead < n_ConstBufferSize) - aSequence.realloc(nRead); + rawCloseEntry(pCandidate->isEncrypt()); + + pCandidate->getZipPackageStream()->successfullyWritten(pCandidate->getZipEntry()); + pCandidate->deleteBufferFile(); + delete pCandidate; +} - rawWrite(aSequence); +void ZipOutputStream::consumeFinishedScheduledThreadEntries() +{ + std::vector< ZipOutputEntry* > aNonFinishedEntries; + + for(auto aIter = m_aEntries.begin(); aIter != m_aEntries.end(); ++aIter) + { + if((*aIter)->isFinished()) + { + consumeScheduledThreadEntry(*aIter); } - while (nRead == n_ConstBufferSize); - xInput.clear(); + else + { + aNonFinishedEntries.push_back(*aIter); + } + } + + // always reset to non-consumed entries + m_aEntries = aNonFinishedEntries; +} - rawCloseEntry(m_aEntries[i]->isEncrypt()); +void ZipOutputStream::consumeAllScheduledThreadEntries() +{ + while(!m_aEntries.empty()) + { + ZipOutputEntry* pCandidate = m_aEntries.back(); + m_aEntries.pop_back(); + consumeScheduledThreadEntry(pCandidate); + } +} + +void ZipOutputStream::reduceScheduledThreadsToGivenNumberOrLess(sal_Int32 nThreads, sal_Int32 nWaitTimeInTenthSeconds) +{ + while(static_cast< sal_Int32 >(m_aEntries.size()) > nThreads) + { + consumeFinishedScheduledThreadEntries(); - m_aEntries[i]->getZipPackageStream()->successfullyWritten(m_aEntries[i]->getZipEntry()); - m_aEntries[i]->deleteBufferFile(); - delete m_aEntries[i]; + if(static_cast< sal_Int32 >(m_aEntries.size()) > nThreads) + { + const TimeValue aTimeValue(0, 100000 * nWaitTimeInTenthSeconds); + osl_waitThread(&aTimeValue); + } } +} + +void ZipOutputStream::finish() + throw(IOException, RuntimeException) +{ + assert(!m_aZipList.empty() && "Zip file must have at least one entry!"); + + // Wait for all threads to finish & write + m_rSharedThreadPool.waitUntilEmpty(); + + // consume all processed entries + consumeAllScheduledThreadEntries(); sal_Int32 nOffset= static_cast < sal_Int32 > (m_aChucker.GetPosition()); for (size_t i = 0; i < m_aZipList.size(); i++) |