summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiroto Kagotani <hiroto.kagotani@gmail.com>2014-08-19 16:07:49 +0900
committerStephan Bergmann <sbergman@redhat.com>2014-08-25 11:31:55 +0200
commit48500bdd0571b11f56161579b576e37883f4c81d (patch)
tree6c82e59d56c74504af1e2d83312009ef58ff05b5
parent8bfde0c1a6275c396e43829619d17350ba68c151 (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.cxx38
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;
}