diff options
author | Hiroto Kagotani <hiroto.kagotani@gmail.com> | 2014-08-19 16:07:49 +0900 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2014-08-25 11:31:55 +0200 |
commit | 48500bdd0571b11f56161579b576e37883f4c81d (patch) | |
tree | 6c82e59d56c74504af1e2d83312009ef58ff05b5 | |
parent | 8bfde0c1a6275c396e43829619d17350ba68c151 (diff) |
fdo#82290: avoid pipe deadlock by executing write(2) in a new thread
Change-Id: I65737399d9ac7ffa1eb623f3ff5fffbce6929801
Signed-off-by: Stephan Bergmann <sbergman@redhat.com>
-rw-r--r-- | filter/source/graphicfilter/ieps/ieps.cxx | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/filter/source/graphicfilter/ieps/ieps.cxx b/filter/source/graphicfilter/ieps/ieps.cxx index 003a52b73b97..d24b6fc86796 100644 --- a/filter/source/graphicfilter/ieps/ieps.cxx +++ b/filter/source/graphicfilter/ieps/ieps.cxx @@ -36,6 +36,7 @@ #include <unotools/tempfile.hxx> #include <osl/process.h> #include <osl/file.hxx> +#include <osl/thread.h> #include <boost/scoped_array.hpp> class FilterConfigItem; @@ -265,6 +266,32 @@ static bool RenderAsEMF(const sal_uInt8* pBuf, sal_uInt32 nBytesRead, Graphic &r return bRet; } +struct WriteData +{ + oslFileHandle m_pFile; + const sal_uInt8 *m_pBuf; + sal_uInt32 m_nBytesToWrite; +}; + +extern "C" { + +static void WriteFileInThread(void *wData) +{ + sal_uInt64 nCount; + WriteData *wdata = (WriteData *)wData; + osl_writeFile(wdata->m_pFile, wdata->m_pBuf, wdata->m_nBytesToWrite, &nCount); + // The number of bytes written does not matter. + // The helper process may close its input stream before reading it all. + // (e.g. at "showpage" in EPS) + + // File must be closed here. + // Otherwise, the helper process may wait for the next input, + // then its stdout is not closed and osl_readFile() blocks. + if (wdata->m_pFile) osl_closeFile(wdata->m_pFile); +} + +} + static bool RenderAsBMPThroughHelper(const sal_uInt8* pBuf, sal_uInt32 nBytesRead, Graphic &rGraphic, OUString &rProgName, rtl_uString *pArgs[], size_t nArgs) { @@ -278,11 +305,14 @@ static bool RenderAsBMPThroughHelper(const sal_uInt8* pBuf, sal_uInt32 nBytesRea if (eErr!=osl_Process_E_None) return false; + WriteData Data; + Data.m_pFile = pIn; + Data.m_pBuf = pBuf; + Data.m_nBytesToWrite = nBytesRead; + oslThread hThread = osl_createThread(WriteFileInThread, &Data); + bool bRet = false; sal_uInt64 nCount; - osl_writeFile(pIn, pBuf, nBytesRead, &nCount); - if (pIn) osl_closeFile(pIn); - if (nCount == nBytesRead) { SvMemoryStream aMemStm; sal_uInt8 aBuf[32000]; @@ -307,6 +337,8 @@ static bool RenderAsBMPThroughHelper(const sal_uInt8* pBuf, sal_uInt32 nBytesRea if (pErr) osl_closeFile(pErr); osl_joinProcess(aProcess); osl_freeProcessHandle(aProcess); + osl_joinWithThread(hThread); + osl_destroyThread(hThread); return bRet; } |