Kaydet (Commit) 48500bdd authored tarafından Hiroto Kagotani's avatar Hiroto Kagotani Kaydeden (comit) Stephan Bergmann

fdo#82290: avoid pipe deadlock by executing write(2) in a new thread

Change-Id: I65737399d9ac7ffa1eb623f3ff5fffbce6929801
Signed-off-by: 's avatarStephan Bergmann <sbergman@redhat.com>
üst 8bfde0c1
......@@ -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;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment