Only have a single call into pdfium at a time.
Pdfium is not thread safe and uses global variables, hence no
parallel call pdfium is safe
Fixes: 28705066
Change-Id: I04309ee691bd9cea37587e0af5be2c07ce8c9f2c
(cherry picked from commit 0768a7dc45)
This commit is contained in:
@@ -52,11 +52,9 @@ static struct {
|
|||||||
} gRectClassInfo;
|
} gRectClassInfo;
|
||||||
|
|
||||||
// Also used in PdfRenderer.cpp
|
// Also used in PdfRenderer.cpp
|
||||||
Mutex sPdfiumLock;
|
|
||||||
int sUnmatchedPdfiumInitRequestCount = 0;
|
int sUnmatchedPdfiumInitRequestCount = 0;
|
||||||
|
|
||||||
static void initializeLibraryIfNeeded() {
|
static void initializeLibraryIfNeeded() {
|
||||||
Mutex::Autolock _l(sPdfiumLock);
|
|
||||||
if (sUnmatchedPdfiumInitRequestCount == 0) {
|
if (sUnmatchedPdfiumInitRequestCount == 0) {
|
||||||
FPDF_InitLibrary();
|
FPDF_InitLibrary();
|
||||||
}
|
}
|
||||||
@@ -64,7 +62,6 @@ static void initializeLibraryIfNeeded() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void destroyLibraryIfNeeded() {
|
static void destroyLibraryIfNeeded() {
|
||||||
Mutex::Autolock _l(sPdfiumLock);
|
|
||||||
sUnmatchedPdfiumInitRequestCount--;
|
sUnmatchedPdfiumInitRequestCount--;
|
||||||
if (sUnmatchedPdfiumInitRequestCount == 0) {
|
if (sUnmatchedPdfiumInitRequestCount == 0) {
|
||||||
FPDF_DestroyLibrary();
|
FPDF_DestroyLibrary();
|
||||||
|
|||||||
@@ -44,11 +44,9 @@ static struct {
|
|||||||
} gPointClassInfo;
|
} gPointClassInfo;
|
||||||
|
|
||||||
// See PdfEditor.cpp
|
// See PdfEditor.cpp
|
||||||
extern Mutex sPdfiumLock;
|
|
||||||
extern int sUnmatchedPdfiumInitRequestCount;
|
extern int sUnmatchedPdfiumInitRequestCount;
|
||||||
|
|
||||||
static void initializeLibraryIfNeeded() {
|
static void initializeLibraryIfNeeded() {
|
||||||
Mutex::Autolock _l(sPdfiumLock);
|
|
||||||
if (sUnmatchedPdfiumInitRequestCount == 0) {
|
if (sUnmatchedPdfiumInitRequestCount == 0) {
|
||||||
FPDF_InitLibrary();
|
FPDF_InitLibrary();
|
||||||
}
|
}
|
||||||
@@ -56,7 +54,6 @@ static void initializeLibraryIfNeeded() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void destroyLibraryIfNeeded() {
|
static void destroyLibraryIfNeeded() {
|
||||||
Mutex::Autolock _l(sPdfiumLock);
|
|
||||||
sUnmatchedPdfiumInitRequestCount--;
|
sUnmatchedPdfiumInitRequestCount--;
|
||||||
if (sUnmatchedPdfiumInitRequestCount == 0) {
|
if (sUnmatchedPdfiumInitRequestCount == 0) {
|
||||||
FPDF_DestroyLibrary();
|
FPDF_DestroyLibrary();
|
||||||
|
|||||||
@@ -79,8 +79,12 @@ public final class PdfEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mInput = input;
|
mInput = input;
|
||||||
mNativeDocument = nativeOpen(mInput.getFd(), size);
|
|
||||||
mPageCount = nativeGetPageCount(mNativeDocument);
|
synchronized (PdfRenderer.sPdfiumLock) {
|
||||||
|
mNativeDocument = nativeOpen(mInput.getFd(), size);
|
||||||
|
mPageCount = nativeGetPageCount(mNativeDocument);
|
||||||
|
}
|
||||||
|
|
||||||
mCloseGuard.open("close");
|
mCloseGuard.open("close");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +106,10 @@ public final class PdfEditor {
|
|||||||
public void removePage(int pageIndex) {
|
public void removePage(int pageIndex) {
|
||||||
throwIfClosed();
|
throwIfClosed();
|
||||||
throwIfPageNotInDocument(pageIndex);
|
throwIfPageNotInDocument(pageIndex);
|
||||||
mPageCount = nativeRemovePage(mNativeDocument, pageIndex);
|
|
||||||
|
synchronized (PdfRenderer.sPdfiumLock) {
|
||||||
|
mPageCount = nativeRemovePage(mNativeDocument, pageIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -125,11 +132,16 @@ public final class PdfEditor {
|
|||||||
if (clip == null) {
|
if (clip == null) {
|
||||||
Point size = new Point();
|
Point size = new Point();
|
||||||
getPageSize(pageIndex, size);
|
getPageSize(pageIndex, size);
|
||||||
nativeSetTransformAndClip(mNativeDocument, pageIndex, transform.native_instance,
|
|
||||||
0, 0, size.x, size.y);
|
synchronized (PdfRenderer.sPdfiumLock) {
|
||||||
|
nativeSetTransformAndClip(mNativeDocument, pageIndex, transform.native_instance,
|
||||||
|
0, 0, size.x, size.y);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
nativeSetTransformAndClip(mNativeDocument, pageIndex, transform.native_instance,
|
synchronized (PdfRenderer.sPdfiumLock) {
|
||||||
clip.left, clip.top, clip.right, clip.bottom);
|
nativeSetTransformAndClip(mNativeDocument, pageIndex, transform.native_instance,
|
||||||
|
clip.left, clip.top, clip.right, clip.bottom);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,7 +155,10 @@ public final class PdfEditor {
|
|||||||
throwIfClosed();
|
throwIfClosed();
|
||||||
throwIfOutSizeNull(outSize);
|
throwIfOutSizeNull(outSize);
|
||||||
throwIfPageNotInDocument(pageIndex);
|
throwIfPageNotInDocument(pageIndex);
|
||||||
nativeGetPageSize(mNativeDocument, pageIndex, outSize);
|
|
||||||
|
synchronized (PdfRenderer.sPdfiumLock) {
|
||||||
|
nativeGetPageSize(mNativeDocument, pageIndex, outSize);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -156,7 +171,10 @@ public final class PdfEditor {
|
|||||||
throwIfClosed();
|
throwIfClosed();
|
||||||
throwIfOutMediaBoxNull(outMediaBox);
|
throwIfOutMediaBoxNull(outMediaBox);
|
||||||
throwIfPageNotInDocument(pageIndex);
|
throwIfPageNotInDocument(pageIndex);
|
||||||
return nativeGetPageMediaBox(mNativeDocument, pageIndex, outMediaBox);
|
|
||||||
|
synchronized (PdfRenderer.sPdfiumLock) {
|
||||||
|
return nativeGetPageMediaBox(mNativeDocument, pageIndex, outMediaBox);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -169,7 +187,10 @@ public final class PdfEditor {
|
|||||||
throwIfClosed();
|
throwIfClosed();
|
||||||
throwIfMediaBoxNull(mediaBox);
|
throwIfMediaBoxNull(mediaBox);
|
||||||
throwIfPageNotInDocument(pageIndex);
|
throwIfPageNotInDocument(pageIndex);
|
||||||
nativeSetPageMediaBox(mNativeDocument, pageIndex, mediaBox);
|
|
||||||
|
synchronized (PdfRenderer.sPdfiumLock) {
|
||||||
|
nativeSetPageMediaBox(mNativeDocument, pageIndex, mediaBox);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -182,7 +203,10 @@ public final class PdfEditor {
|
|||||||
throwIfClosed();
|
throwIfClosed();
|
||||||
throwIfOutCropBoxNull(outCropBox);
|
throwIfOutCropBoxNull(outCropBox);
|
||||||
throwIfPageNotInDocument(pageIndex);
|
throwIfPageNotInDocument(pageIndex);
|
||||||
return nativeGetPageCropBox(mNativeDocument, pageIndex, outCropBox);
|
|
||||||
|
synchronized (PdfRenderer.sPdfiumLock) {
|
||||||
|
return nativeGetPageCropBox(mNativeDocument, pageIndex, outCropBox);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -195,7 +219,10 @@ public final class PdfEditor {
|
|||||||
throwIfClosed();
|
throwIfClosed();
|
||||||
throwIfCropBoxNull(cropBox);
|
throwIfCropBoxNull(cropBox);
|
||||||
throwIfPageNotInDocument(pageIndex);
|
throwIfPageNotInDocument(pageIndex);
|
||||||
nativeSetPageCropBox(mNativeDocument, pageIndex, cropBox);
|
|
||||||
|
synchronized (PdfRenderer.sPdfiumLock) {
|
||||||
|
nativeSetPageCropBox(mNativeDocument, pageIndex, cropBox);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -205,7 +232,10 @@ public final class PdfEditor {
|
|||||||
*/
|
*/
|
||||||
public boolean shouldScaleForPrinting() {
|
public boolean shouldScaleForPrinting() {
|
||||||
throwIfClosed();
|
throwIfClosed();
|
||||||
return nativeScaleForPrinting(mNativeDocument);
|
|
||||||
|
synchronized (PdfRenderer.sPdfiumLock) {
|
||||||
|
return nativeScaleForPrinting(mNativeDocument);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -219,7 +249,10 @@ public final class PdfEditor {
|
|||||||
public void write(ParcelFileDescriptor output) throws IOException {
|
public void write(ParcelFileDescriptor output) throws IOException {
|
||||||
try {
|
try {
|
||||||
throwIfClosed();
|
throwIfClosed();
|
||||||
nativeWrite(mNativeDocument, output.getFd());
|
|
||||||
|
synchronized (PdfRenderer.sPdfiumLock) {
|
||||||
|
nativeWrite(mNativeDocument, output.getFd());
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
IoUtils.closeQuietly(output);
|
IoUtils.closeQuietly(output);
|
||||||
}
|
}
|
||||||
@@ -247,7 +280,9 @@ public final class PdfEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void doClose() {
|
private void doClose() {
|
||||||
nativeClose(mNativeDocument);
|
synchronized (PdfRenderer.sPdfiumLock) {
|
||||||
|
nativeClose(mNativeDocument);
|
||||||
|
}
|
||||||
IoUtils.closeQuietly(mInput);
|
IoUtils.closeQuietly(mInput);
|
||||||
mInput = null;
|
mInput = null;
|
||||||
mCloseGuard.close();
|
mCloseGuard.close();
|
||||||
|
|||||||
@@ -99,6 +99,12 @@ import java.lang.annotation.RetentionPolicy;
|
|||||||
* @see #close()
|
* @see #close()
|
||||||
*/
|
*/
|
||||||
public final class PdfRenderer implements AutoCloseable {
|
public final class PdfRenderer implements AutoCloseable {
|
||||||
|
/**
|
||||||
|
* Any call the native pdfium code has to be single threaded as the library does not support
|
||||||
|
* parallel use.
|
||||||
|
*/
|
||||||
|
final static Object sPdfiumLock = new Object();
|
||||||
|
|
||||||
private final CloseGuard mCloseGuard = CloseGuard.get();
|
private final CloseGuard mCloseGuard = CloseGuard.get();
|
||||||
|
|
||||||
private final Point mTempPoint = new Point();
|
private final Point mTempPoint = new Point();
|
||||||
@@ -154,8 +160,12 @@ public final class PdfRenderer implements AutoCloseable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mInput = input;
|
mInput = input;
|
||||||
mNativeDocument = nativeCreate(mInput.getFd(), size);
|
|
||||||
mPageCount = nativeGetPageCount(mNativeDocument);
|
synchronized (sPdfiumLock) {
|
||||||
|
mNativeDocument = nativeCreate(mInput.getFd(), size);
|
||||||
|
mPageCount = nativeGetPageCount(mNativeDocument);
|
||||||
|
}
|
||||||
|
|
||||||
mCloseGuard.open("close");
|
mCloseGuard.open("close");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,7 +199,10 @@ public final class PdfRenderer implements AutoCloseable {
|
|||||||
*/
|
*/
|
||||||
public boolean shouldScaleForPrinting() {
|
public boolean shouldScaleForPrinting() {
|
||||||
throwIfClosed();
|
throwIfClosed();
|
||||||
return nativeScaleForPrinting(mNativeDocument);
|
|
||||||
|
synchronized (sPdfiumLock) {
|
||||||
|
return nativeScaleForPrinting(mNativeDocument);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -224,7 +237,9 @@ public final class PdfRenderer implements AutoCloseable {
|
|||||||
if (mCurrentPage != null) {
|
if (mCurrentPage != null) {
|
||||||
mCurrentPage.close();
|
mCurrentPage.close();
|
||||||
}
|
}
|
||||||
nativeClose(mNativeDocument);
|
synchronized (sPdfiumLock) {
|
||||||
|
nativeClose(mNativeDocument);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
mInput.close();
|
mInput.close();
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
@@ -277,7 +292,9 @@ public final class PdfRenderer implements AutoCloseable {
|
|||||||
|
|
||||||
private Page(int index) {
|
private Page(int index) {
|
||||||
Point size = mTempPoint;
|
Point size = mTempPoint;
|
||||||
mNativePage = nativeOpenPageAndGetSize(mNativeDocument, index, size);
|
synchronized (sPdfiumLock) {
|
||||||
|
mNativePage = nativeOpenPageAndGetSize(mNativeDocument, index, size);
|
||||||
|
}
|
||||||
mIndex = index;
|
mIndex = index;
|
||||||
mWidth = size.x;
|
mWidth = size.x;
|
||||||
mHeight = size.y;
|
mHeight = size.y;
|
||||||
@@ -384,8 +401,10 @@ public final class PdfRenderer implements AutoCloseable {
|
|||||||
|
|
||||||
final long transformPtr = (transform != null) ? transform.native_instance : 0;
|
final long transformPtr = (transform != null) ? transform.native_instance : 0;
|
||||||
|
|
||||||
nativeRenderPage(mNativeDocument, mNativePage, destination, contentLeft,
|
synchronized (sPdfiumLock) {
|
||||||
contentTop, contentRight, contentBottom, transformPtr, renderMode);
|
nativeRenderPage(mNativeDocument, mNativePage, destination, contentLeft,
|
||||||
|
contentTop, contentRight, contentBottom, transformPtr, renderMode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -412,7 +431,9 @@ public final class PdfRenderer implements AutoCloseable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void doClose() {
|
private void doClose() {
|
||||||
nativeClosePage(mNativePage);
|
synchronized (sPdfiumLock) {
|
||||||
|
nativeClosePage(mNativePage);
|
||||||
|
}
|
||||||
mNativePage = 0;
|
mNativePage = 0;
|
||||||
mCloseGuard.close();
|
mCloseGuard.close();
|
||||||
mCurrentPage = null;
|
mCurrentPage = null;
|
||||||
|
|||||||
Reference in New Issue
Block a user