summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2016-11-21 14:23:45 +0000
committerRobin Watts <robin.watts@artifex.com>2016-11-23 10:01:25 +0000
commitcb44c9ae591ae5cdfda932f04bf321932a0e1d0f (patch)
tree4fe8f3d70d6f951ee8cd50c96bc4dc732179a7f0
parent30afe6fa458cef7a6f84020de5bd15d8ae164521 (diff)
downloadmupdf-cb44c9ae591ae5cdfda932f04bf321932a0e1d0f.tar.xz
Convert mudraw and muraster to use mu-threads.
Saves having the same threading code repeatedly.
-rw-r--r--Makefile12
-rw-r--r--include/mupdf/fitz/system.h5
-rw-r--r--platform/win32/mupdf.sln21
-rw-r--r--source/tools/mudraw.c283
-rw-r--r--source/tools/muraster.c364
5 files changed, 209 insertions, 476 deletions
diff --git a/Makefile b/Makefile
index e4bb7301..4798c748 100644
--- a/Makefile
+++ b/Makefile
@@ -73,6 +73,7 @@ ALL_DIR += $(OUT)/cbz
ALL_DIR += $(OUT)/html
ALL_DIR += $(OUT)/gprf
ALL_DIR += $(OUT)/tools
+ALL_DIR += $(OUT)/helper
ALL_DIR += $(OUT)/platform/x11
ALL_DIR += $(OUT)/platform/x11/curl
ALL_DIR += $(OUT)/platform/gl
@@ -82,6 +83,7 @@ FITZ_HDR := include/mupdf/fitz.h $(wildcard include/mupdf/fitz/*.h)
PDF_HDR := include/mupdf/pdf.h $(wildcard include/mupdf/pdf/*.h)
SVG_HDR := include/mupdf/svg.h
HTML_HDR := include/mupdf/html.h
+THREAD_HDR := include/mupdf/helper/mu-threads.h
FITZ_SRC := $(wildcard source/fitz/*.c)
PDF_SRC := $(wildcard source/pdf/*.c)
@@ -90,6 +92,7 @@ SVG_SRC := $(wildcard source/svg/*.c)
CBZ_SRC := $(wildcard source/cbz/*.c)
HTML_SRC := $(wildcard source/html/*.c)
GPRF_SRC := $(wildcard source/gprf/*.c)
+THREAD_SRC := source/helper/mu-threads.c
FITZ_SRC_HDR := $(wildcard source/fitz/*.h)
PDF_SRC_HDR := $(wildcard source/pdf/*.h) source/pdf/pdf-name-table.h
@@ -105,6 +108,7 @@ SVG_OBJ := $(subst source/, $(OUT)/, $(addsuffix .o, $(basename $(SVG_SRC))))
CBZ_OBJ := $(subst source/, $(OUT)/, $(addsuffix .o, $(basename $(CBZ_SRC))))
HTML_OBJ := $(subst source/, $(OUT)/, $(addsuffix .o, $(basename $(HTML_SRC))))
GPRF_OBJ := $(subst source/, $(OUT)/, $(addsuffix .o, $(basename $(GPRF_SRC))))
+THREAD_OBJ := $(subst source/, $(OUT)/, $(addsuffix .o, $(basename $(THREAD_SRC))))
$(FITZ_OBJ) : $(FITZ_HDR) $(FITZ_SRC_HDR)
$(PDF_OBJ) : $(FITZ_HDR) $(PDF_HDR) $(PDF_SRC_HDR)
@@ -113,6 +117,7 @@ $(SVG_OBJ) : $(FITZ_HDR) $(SVG_HDR) $(SVG_SRC_HDR)
$(CBZ_OBJ) : $(FITZ_HDR)
$(HTML_OBJ) : $(FITZ_HDR) $(HTML_HDR) $(HTML_SRC_HDR)
$(GPRF_OBJ) : $(FITZ_HDR) $(GPRF_HDR) $(GPRF_SRC_HDR)
+$(THREAD_OBJ) : $(THREAD_HDR)
# --- Generated embedded font files ---
@@ -154,12 +159,15 @@ $(FONT_GEN_SIL) : $(FONT_BIN_SIL)
MUPDF_LIB = $(OUT)/libmupdf.a
THIRD_LIB = $(OUT)/libmupdfthird.a
+THREAD_LIB = $(OUT)/libmuthreads.a
MUPDF_OBJ := $(FITZ_OBJ) $(FONT_OBJ) $(PDF_OBJ) $(XPS_OBJ) $(SVG_OBJ) $(CBZ_OBJ) $(HTML_OBJ) $(GPRF_OBJ)
THIRD_OBJ := $(FREETYPE_OBJ) $(HARFBUZZ_OBJ) $(JBIG2DEC_OBJ) $(JPEG_OBJ) $(JPEGXR_OBJ) $(LURATECH_OBJ) $(MUJS_OBJ) $(OPENJPEG_OBJ) $(ZLIB_OBJ)
+THREAD_OBJ := $(THREAD_OBJ)
$(MUPDF_LIB) : $(MUPDF_OBJ)
$(THIRD_LIB) : $(THIRD_OBJ)
+$(THREAD_LIB) : $(THREAD_OBJ)
INSTALL_LIBS := $(MUPDF_LIB) $(THIRD_LIB)
@@ -265,13 +273,13 @@ MUTOOL_OBJ += $(addprefix $(OUT)/tools/, pdfclean.o pdfcreate.o pdfextract.o pdf
$(MUTOOL_OBJ): $(FITZ_HDR) $(PDF_HDR)
MUTOOL_LIB = $(OUT)/libmutools.a
$(MUTOOL_LIB) : $(MUTOOL_OBJ)
-$(MUTOOL) : $(MUTOOL_LIB) $(MUPDF_LIB) $(THIRD_LIB)
+$(MUTOOL) : $(MUTOOL_LIB) $(MUPDF_LIB) $(THIRD_LIB) $(THREAD_LIB)
$(LINK_CMD)
MURASTER := $(OUT)/muraster
MURASTER_OBJ := $(addprefix $(OUT)/tools/, muraster.o)
$(MURASTER_OBJ): $(FITZ_HDR)
-$(MURASTER) : $(MURASTER_OBJ) $(MUPDF_LIB) $(THIRD_LIB)
+$(MURASTER) : $(MURASTER_OBJ) $(MUPDF_LIB) $(THIRD_LIB) $(THREAD_LIB)
$(LINK_CMD)
MJSGEN := $(OUT)/mjsgen
diff --git a/include/mupdf/fitz/system.h b/include/mupdf/fitz/system.h
index 1723824f..3fe4311a 100644
--- a/include/mupdf/fitz/system.h
+++ b/include/mupdf/fitz/system.h
@@ -81,6 +81,11 @@
#define fz_jmp_buf jmp_buf
#endif
+#ifndef _MSC_VER
+/* For gettimeofday */
+#include <sys/time.h>
+#endif
+
#ifdef _MSC_VER /* Microsoft Visual C */
/* MSVC up to VS2012 */
diff --git a/platform/win32/mupdf.sln b/platform/win32/mupdf.sln
index 723b8dea..998b8186 100644
--- a/platform/win32/mupdf.sln
+++ b/platform/win32/mupdf.sln
@@ -10,20 +10,22 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libthirdparty", "libthirdpa
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmupdf", "libmupdf.vcproj", "{5F615F91-DFF8-4F05-BF48-6222B7D86519}"
ProjectSection(ProjectDependencies) = postProject
- {B0091365-C9BA-4F40-AE2B-EF93702871B2} = {B0091365-C9BA-4F40-AE2B-EF93702871B2}
- {5EDCF4FD-0291-4FB9-8D96-D58957CA5E3C} = {5EDCF4FD-0291-4FB9-8D96-D58957CA5E3C}
- {A5053AA7-02E5-4903-B596-04F17AEB1526} = {A5053AA7-02E5-4903-B596-04F17AEB1526}
{52DCAB29-C8EE-4422-954C-29AFA6B33E22} = {52DCAB29-C8EE-4422-954C-29AFA6B33E22}
+ {A5053AA7-02E5-4903-B596-04F17AEB1526} = {A5053AA7-02E5-4903-B596-04F17AEB1526}
+ {5EDCF4FD-0291-4FB9-8D96-D58957CA5E3C} = {5EDCF4FD-0291-4FB9-8D96-D58957CA5E3C}
+ {B0091365-C9BA-4F40-AE2B-EF93702871B2} = {B0091365-C9BA-4F40-AE2B-EF93702871B2}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mudraw", "mudraw.vcproj", "{0B51171B-B10E-4EAC-8FFA-19226A1828A3}"
ProjectSection(ProjectDependencies) = postProject
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B} = {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}
{5F615F91-DFF8-4F05-BF48-6222B7D86519} = {5F615F91-DFF8-4F05-BF48-6222B7D86519}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mutool", "mutool.vcproj", "{00811970-815B-4F64-BC9D-219078B1F3AA}"
ProjectSection(ProjectDependencies) = postProject
{5F615F91-DFF8-4F05-BF48-6222B7D86519} = {5F615F91-DFF8-4F05-BF48-6222B7D86519}
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B} = {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "generated", "generated.vcproj", "{A5053AA7-02E5-4903-B596-04F17AEB1526}"
@@ -32,8 +34,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcurl", "..\..\thirdparty
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mupdf-curl", "mupdf-curl.vcproj", "{27B53E5C-ACAB-423C-854E-BECE56D73544}"
ProjectSection(ProjectDependencies) = postProject
- {5F615F91-DFF8-4F05-BF48-6222B7D86519} = {5F615F91-DFF8-4F05-BF48-6222B7D86519}
{87EE9DA4-DE1E-4448-8324-183C98DCA588} = {87EE9DA4-DE1E-4448-8324-183C98DCA588}
+ {5F615F91-DFF8-4F05-BF48-6222B7D86519} = {5F615F91-DFF8-4F05-BF48-6222B7D86519}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mujstest", "mujstest.vcproj", "{21E28758-E4D2-4B84-8EC5-B631CEE66B30}"
@@ -45,8 +47,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libglfw", "libglfw.vcproj",
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mupdf-gl", "mupdf-gl.vcproj", "{CE3A76A8-A28F-4991-8FB9-C9453D922037}"
ProjectSection(ProjectDependencies) = postProject
- {A1B75D29-9F5C-4A0F-B368-322A10477D0C} = {A1B75D29-9F5C-4A0F-B368-322A10477D0C}
{5F615F91-DFF8-4F05-BF48-6222B7D86519} = {5F615F91-DFF8-4F05-BF48-6222B7D86519}
+ {A1B75D29-9F5C-4A0F-B368-322A10477D0C} = {A1B75D29-9F5C-4A0F-B368-322A10477D0C}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libfonts", "libfonts.vcproj", "{52DCAB29-C8EE-4422-954C-29AFA6B33E22}"
@@ -57,20 +59,21 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "muraster", "muraster.vcproj", "{0FDC74D7-D18C-45CE-94D6-EDFCC5A0CDF2}"
ProjectSection(ProjectDependencies) = postProject
{52DCAB29-C8EE-4422-954C-29AFA6B33E22} = {52DCAB29-C8EE-4422-954C-29AFA6B33E22}
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B} = {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}
{5F615F91-DFF8-4F05-BF48-6222B7D86519} = {5F615F91-DFF8-4F05-BF48-6222B7D86519}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "javaviewerlib", "javaviewerlib.vcproj", "{3DB35F2D-9679-4DED-BA0C-240A4E6E6674}"
ProjectSection(ProjectDependencies) = postProject
- {5F615F91-DFF8-4F05-BF48-6222B7D86519} = {5F615F91-DFF8-4F05-BF48-6222B7D86519}
{52DCAB29-C8EE-4422-954C-29AFA6B33E22} = {52DCAB29-C8EE-4422-954C-29AFA6B33E22}
+ {5F615F91-DFF8-4F05-BF48-6222B7D86519} = {5F615F91-DFF8-4F05-BF48-6222B7D86519}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "javaviewer", "javaviewer.vcproj", "{FB8DC595-90A5-44D6-9FFF-2BDFA912FD8C}"
ProjectSection(ProjectDependencies) = postProject
- {5F615F91-DFF8-4F05-BF48-6222B7D86519} = {5F615F91-DFF8-4F05-BF48-6222B7D86519}
- {3DB35F2D-9679-4DED-BA0C-240A4E6E6674} = {3DB35F2D-9679-4DED-BA0C-240A4E6E6674}
{52DCAB29-C8EE-4422-954C-29AFA6B33E22} = {52DCAB29-C8EE-4422-954C-29AFA6B33E22}
+ {3DB35F2D-9679-4DED-BA0C-240A4E6E6674} = {3DB35F2D-9679-4DED-BA0C-240A4E6E6674}
+ {5F615F91-DFF8-4F05-BF48-6222B7D86519} = {5F615F91-DFF8-4F05-BF48-6222B7D86519}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libluratech", "libluratech.vcproj", "{B0091365-C9BA-4F40-AE2B-EF93702871B2}"
@@ -79,8 +82,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmuthreads", "libmuthread
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mu-office-lib", "mu-office-lib.vcproj", "{FFF91365-C9BA-4F40-AE2B-EF93702871B2}"
ProjectSection(ProjectDependencies) = postProject
- {5F615F91-DFF8-4F05-BF48-6222B7D86519} = {5F615F91-DFF8-4F05-BF48-6222B7D86519}
{DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B} = {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}
+ {5F615F91-DFF8-4F05-BF48-6222B7D86519} = {5F615F91-DFF8-4F05-BF48-6222B7D86519}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mu-office-test", "mu-office-test.vcproj", "{FB51171B-B10E-4EAC-8FFA-19226A1828A3}"
diff --git a/source/tools/mudraw.c b/source/tools/mudraw.c
index 0b091fee..20122563 100644
--- a/source/tools/mudraw.c
+++ b/source/tools/mudraw.c
@@ -5,18 +5,7 @@
#include "mupdf/fitz.h"
#include "mupdf/pdf.h" /* for pdf output */
-#ifdef _MSC_VER
-#include <winsock2.h>
-#include <windows.h>
-#define MUDRAW_THREADS 1
-#else
-#include <sys/time.h>
-#ifdef HAVE_PTHREADS
-#define MUDRAW_THREADS 2
-#include <pthread.h>
-#include <semaphore.h>
-#endif
-#endif
+#include "mupdf/helpers/mu-threads.h"
/* Enable for helpful threading debug */
/* #define DEBUG_THREADS(A) do { printf A; fflush(stdout); } while (0) */
@@ -131,144 +120,18 @@ static const format_cs_table_t format_cs_table[] =
a multi-threaded option. In the absence, of such, we degrade
nicely.
*/
-#ifdef MUDRAW_THREADS
-#if MUDRAW_THREADS == 1
-
-/* Windows threads */
-#define SEMAPHORE HANDLE
-#define SEMAPHORE_INIT(A) do { A = CreateSemaphore(NULL, 0, 1, NULL); } while (0)
-#define SEMAPHORE_FIN(A) do { CloseHandle(A); } while (0)
-#define SEMAPHORE_TRIGGER(A) do { (void)ReleaseSemaphore(A, 1, NULL); } while (0)
-#define SEMAPHORE_WAIT(A) do { (void)WaitForSingleObject(A, INFINITE); } while (0)
-#define THREAD HANDLE
-#define THREAD_INIT(A,B,C) do { A = CreateThread(NULL, 0, B, C, 0, NULL); } while (0)
-#define THREAD_FIN(A) do { CloseHandle(A); } while (0)
-#define THREAD_RETURN_TYPE DWORD WINAPI
-#define THREAD_RETURN() return 0
-#define MUTEX CRITICAL_SECTION
-#define MUTEX_INIT(A) do { InitializeCriticalSection(&A); } while (0)
-#define MUTEX_FIN(A) do { DeleteCriticalSection(&A); } while (0)
-#define MUTEX_LOCK(A) do { EnterCriticalSection(&A); } while (0)
-#define MUTEX_UNLOCK(A) do { LeaveCriticalSection(&A); } while (0)
-
-#elif MUDRAW_THREADS == 2
-
-/*
- PThreads - without working unnamed semaphores.
-
- Neither ios nor OSX supports unnamed semaphores.
- Named semaphores are a pain to use, so we implement
- our own semaphores using condition variables and
- mutexes.
-*/
+#ifndef DISABLE_MUTHREADS
-typedef struct
-{
- int count;
- pthread_mutex_t mutex;
- pthread_cond_t cond;
-} my_semaphore_t;
-
-int
-my_semaphore_open(my_semaphore_t *sem)
-{
- int scode;
-
- sem->count = 0;
- scode = pthread_mutex_init(&sem->mutex, NULL);
- if (scode == 0)
- {
- scode = pthread_cond_init(&sem->cond, NULL);
- if (scode)
- pthread_mutex_destroy(&sem->mutex);
- }
- if (scode)
- memset(sem, 0, sizeof(*sem));
- return scode;
-}
-
-int
-my_semaphore_close(my_semaphore_t *sem)
-{
- int scode, scode2;
-
- scode = pthread_cond_destroy(&sem->cond);
- scode2 = pthread_mutex_destroy(&sem->mutex);
- if (scode == 0)
- scode = scode2;
- return scode;
-}
-
-int
-my_semaphore_wait(my_semaphore_t *sem)
-{
- int scode, scode2;
-
- scode = pthread_mutex_lock(&sem->mutex);
- if (scode)
- return scode;
- while (sem->count == 0) {
- scode = pthread_cond_wait(&sem->cond, &sem->mutex);
- if (scode)
- break;
- }
- if (scode == 0)
- --sem->count;
- scode2 = pthread_mutex_unlock(&sem->mutex);
- if (scode == 0)
- scode = scode2;
- return scode;
-}
-
-int
-my_semaphore_signal(my_semaphore_t * sem)
-{
- int scode, scode2;
-
- scode = pthread_mutex_lock(&sem->mutex);
- if (scode)
- return scode;
- if (sem->count++ == 0)
- scode = pthread_cond_signal(&sem->cond);
- scode2 = pthread_mutex_unlock(&sem->mutex);
- if (scode == 0)
- scode = scode2;
- return scode;
-}
-
-#define SEMAPHORE my_semaphore_t
-#define SEMAPHORE_INIT(A) do { (void)my_semaphore_open(&A); } while (0)
-#define SEMAPHORE_FIN(A) do { (void)my_semaphore_close(&A); } while (0)
-#define SEMAPHORE_TRIGGER(A) do { (void)my_semaphore_signal(&A); } while (0)
-#define SEMAPHORE_WAIT(A) do { (void)my_semaphore_wait(&A); } while (0)
-#define THREAD pthread_t
-#define THREAD_INIT(A,B,C) do { (void)pthread_create(&A, NULL, B, C); } while (0)
-#define THREAD_FIN(A) do { void *res; (void)pthread_join(A, &res); } while (0)
-#define THREAD_RETURN_TYPE void *
-#define THREAD_RETURN() return NULL
-#define MUTEX pthread_mutex_t
-#define MUTEX_INIT(A) do { (void)pthread_mutex_init(&A, NULL); } while (0)
-#define MUTEX_FIN(A) do { (void)pthread_mutex_destroy(&A); } while (0)
-#define MUTEX_LOCK(A) do { (void)pthread_mutex_lock(&A); } while (0)
-#define MUTEX_UNLOCK(A) do { (void)pthread_mutex_unlock(&A); } while (0)
-
-#else
-#error Unknown MUDRAW_THREADS setting
-#endif
-
-#define LOCKS_INIT() init_mudraw_locks()
-#define LOCKS_FIN() fin_mudraw_locks()
-
-static MUTEX mutexes[FZ_LOCK_MAX];
+static mu_mutex mutexes[FZ_LOCK_MAX];
static void mudraw_lock(void *user, int lock)
{
- MUTEX_LOCK(mutexes[lock]);
+ mu_lock_mutex(&mutexes[lock]);
}
static void mudraw_unlock(void *user, int lock)
{
- MUTEX_UNLOCK(mutexes[lock]);
+ mu_unlock_mutex(&mutexes[lock]);
}
static fz_locks_context mudraw_locks =
@@ -276,37 +139,30 @@ static fz_locks_context mudraw_locks =
NULL, mudraw_lock, mudraw_unlock
};
-static fz_locks_context *init_mudraw_locks(void)
+static void fin_mudraw_locks(void)
{
int i;
for (i = 0; i < FZ_LOCK_MAX; i++)
- MUTEX_INIT(mutexes[i]);
-
- return &mudraw_locks;
+ mu_destroy_mutex(&mutexes[i]);
}
-static void fin_mudraw_locks(void)
+static fz_locks_context *init_mudraw_locks(void)
{
int i;
+ int failed = 0;
for (i = 0; i < FZ_LOCK_MAX; i++)
- MUTEX_FIN(mutexes[i]);
-}
+ failed |= mu_create_mutex(&mutexes[i]);
-#else
+ if (failed)
+ {
+ fin_mudraw_locks();
+ return NULL;
+ }
-/* Null Threads implementation */
-#define SEMAPHORE int
-#define THREAD int
-#define SEMAPHORE_INIT(A) do { A = 0; } while (0)
-#define SEMAPHORE_FIN(A) do { A = 0; } while (0)
-#define SEMAPHORE_TRIGGER(A) do { A = 0; } while (0)
-#define SEMAPHORE_WAIT(A) do { A = 0; } while (0)
-#define THREAD_INIT(A,B,C) do { A = 0; (void)C; } while (0)
-#define THREAD_FIN(A) do { A = 0; } while (0)
-#define LOCKS_INIT() NULL
-#define LOCKS_FIN() do { } while (0)
+ return &mudraw_locks;
+}
#endif
@@ -320,9 +176,9 @@ typedef struct worker_t {
fz_pixmap *pix;
fz_bitmap *bit;
fz_cookie cookie;
- SEMAPHORE start;
- SEMAPHORE stop;
- THREAD thread;
+ mu_semaphore start;
+ mu_semaphore stop;
+ mu_thread thread;
} worker_t;
static char *output = NULL;
@@ -385,9 +241,9 @@ static struct {
int active;
int started;
fz_context *ctx;
- THREAD thread;
- SEMAPHORE start;
- SEMAPHORE stop;
+ mu_thread thread;
+ mu_semaphore start;
+ mu_semaphore stop;
int pagenum;
char *filename;
fz_display_list *list;
@@ -865,7 +721,7 @@ static void dodrawpage(fz_context *ctx, fz_page *page, fz_display_list *list, in
workers[band].pix = fz_new_pixmap_with_bbox(ctx, colorspace, &band_ibounds, alpha);
fz_set_pixmap_resolution(ctx, workers[band].pix, resolution, resolution);
DEBUG_THREADS(("Worker %d, Pre-triggering band %d\n", band, band));
- SEMAPHORE_TRIGGER(workers[band].start);
+ mu_trigger_semaphore(&workers[band].start);
ctm.f -= drawheight;
}
pix = workers[0].pix;
@@ -908,7 +764,7 @@ static void dodrawpage(fz_context *ctx, fz_page *page, fz_display_list *list, in
{
worker_t *w = &workers[band % num_workers];
DEBUG_THREADS(("Waiting for worker %d to complete band %d\n", w->num, band));
- SEMAPHORE_WAIT(w->stop);
+ mu_wait_semaphore(&w->stop);
pix = w->pix;
bit = w->bit;
w->bit = NULL;
@@ -937,7 +793,7 @@ static void dodrawpage(fz_context *ctx, fz_page *page, fz_display_list *list, in
w->tbounds = tbounds;
memset(&w->cookie, 0, sizeof(fz_cookie));
DEBUG_THREADS(("Triggering worker %d for band %d\n", w->num, w->band));
- SEMAPHORE_TRIGGER(w->start);
+ mu_trigger_semaphore(&w->start);
}
ctm.f -= drawheight;
}
@@ -1059,7 +915,7 @@ static void bgprint_flush(void)
if (!bgprint.active || !bgprint.started)
return;
- SEMAPHORE_WAIT(bgprint.stop);
+ mu_wait_semaphore(&bgprint.stop);
bgprint.started = 0;
}
@@ -1165,7 +1021,7 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum)
bgprint.filename = filename;
bgprint.pagenum = pagenum;
bgprint.interptime = start;
- SEMAPHORE_TRIGGER(bgprint.start);
+ mu_trigger_semaphore(&bgprint.start);
}
else
{
@@ -1267,26 +1123,25 @@ trace_realloc(void *arg, void *p_, size_t size)
return &p[1];
}
-#ifdef MUDRAW_THREADS
-static THREAD_RETURN_TYPE worker_thread(void *arg)
+#ifndef DISABLE_MUTHREADS
+static void worker_thread(void *arg)
{
worker_t *me = (worker_t *)arg;
do
{
DEBUG_THREADS(("Worker %d waiting\n", me->num));
- SEMAPHORE_WAIT(me->start);
+ mu_wait_semaphore(&me->start);
DEBUG_THREADS(("Worker %d woken for band %d\n", me->num, me->band));
if (me->band >= 0)
drawband(me->ctx, NULL, me->list, &me->ctm, &me->tbounds, &me->cookie, me->band * band_height, me->pix, &me->bit);
DEBUG_THREADS(("Worker %d completed band %d\n", me->num, me->band));
- SEMAPHORE_TRIGGER(me->stop);
+ mu_trigger_semaphore(&me->stop);
}
while (me->band >= 0);
- THREAD_RETURN();
}
-static THREAD_RETURN_TYPE bgprint_worker(void *arg)
+static void bgprint_worker(void *arg)
{
fz_cookie cookie = { 0 };
int pagenum;
@@ -1296,7 +1151,7 @@ static THREAD_RETURN_TYPE bgprint_worker(void *arg)
do
{
DEBUG_THREADS(("BGPrint waiting\n"));
- SEMAPHORE_WAIT(bgprint.start);
+ mu_wait_semaphore(&bgprint.start);
pagenum = bgprint.pagenum;
DEBUG_THREADS(("BGPrint woken for pagenum %d\n", pagenum));
if (pagenum >= 0)
@@ -1306,10 +1161,9 @@ static THREAD_RETURN_TYPE bgprint_worker(void *arg)
dodrawpage(bgprint.ctx, bgprint.page, bgprint.list, pagenum, &cookie, start, bgprint.interptime, bgprint.filename, 1);
}
DEBUG_THREADS(("BGPrint completed page %d\n", pagenum));
- SEMAPHORE_TRIGGER(bgprint.stop);
+ mu_trigger_semaphore(&bgprint.stop);
}
while (pagenum >= 0);
- THREAD_RETURN();
}
#endif
@@ -1426,6 +1280,7 @@ int mudraw_main(int argc, char **argv)
int c, i;
fz_context *ctx;
fz_alloc_context alloc_ctx = { NULL, trace_malloc, trace_realloc, trace_free };
+ fz_locks_context *locks = NULL;
fz_var(doc);
@@ -1479,7 +1334,7 @@ int mudraw_main(int argc, char **argv)
case 'i': ignore_errors = 1; break;
case 'T':
-#ifdef MUDRAW_THREADS
+#ifndef DISABLE_MUTHREADS
num_workers = atoi(fz_optarg); break;
#else
fprintf(stderr, "Threads not enabled in this build\n");
@@ -1520,7 +1375,16 @@ int mudraw_main(int argc, char **argv)
}
}
- ctx = fz_new_context((showmemory == 0 ? NULL : &alloc_ctx), LOCKS_INIT(), (lowmemory ? 1 : FZ_STORE_DEFAULT));
+#ifndef DISABLE_MUTHREADS
+ locks = init_mudraw_locks();
+ if (locks == NULL)
+ {
+ fprintf(stderr, "mutex initialisation failed\n");
+ exit(1);
+ }
+#endif
+
+ ctx = fz_new_context((showmemory == 0 ? NULL : &alloc_ctx), locks, (lowmemory ? 1 : FZ_STORE_DEFAULT));
if (!ctx)
{
fprintf(stderr, "cannot initialise context\n");
@@ -1531,26 +1395,40 @@ int mudraw_main(int argc, char **argv)
fz_set_graphics_aa_level(ctx, alphabits_graphics);
fz_set_graphics_min_line_width(ctx, min_line_width);
+#ifndef DISABLE_MUTHREADS
if (bgprint.active)
{
+ int fail = 0;
bgprint.ctx = fz_clone_context(ctx);
- SEMAPHORE_INIT(bgprint.start);
- SEMAPHORE_INIT(bgprint.stop);
- THREAD_INIT(bgprint.thread, bgprint_worker, NULL);
+ fail |= mu_create_semaphore(&bgprint.start);
+ fail |= mu_create_semaphore(&bgprint.stop);
+ fail |= mu_create_thread(&bgprint.thread, bgprint_worker, NULL);
+ if (fail)
+ {
+ fprintf(stderr, "bgprint startup failed\n");
+ exit(1);
+ }
}
if (num_workers > 0)
{
+ int fail = 0;
workers = fz_calloc(ctx, num_workers, sizeof(*workers));
for (i = 0; i < num_workers; i++)
{
workers[i].ctx = fz_clone_context(ctx);
workers[i].num = i;
- SEMAPHORE_INIT(workers[i].start);
- SEMAPHORE_INIT(workers[i].stop);
- THREAD_INIT(workers[i].thread, worker_thread, &workers[i]);
+ fail |= mu_create_semaphore(&workers[i].start);
+ fail |= mu_create_semaphore(&workers[i].stop);
+ fail |= mu_create_thread(&workers[i].thread, worker_thread, &workers[i]);
+ }
+ if (fail)
+ {
+ fprintf(stderr, "worker startup failed\n");
+ exit(1);
}
}
+#endif /* DISABLE_MUTHREADS */
if (layout_css)
{
@@ -1813,16 +1691,17 @@ int mudraw_main(int argc, char **argv)
}
}
+#ifndef DISABLE_MUTHREADS
if (num_workers > 0)
{
for (i = 0; i < num_workers; i++)
{
workers[i].band = -1;
- SEMAPHORE_TRIGGER(workers[i].start);
- SEMAPHORE_WAIT(workers[i].stop);
- SEMAPHORE_FIN(workers[i].start);
- SEMAPHORE_FIN(workers[i].stop);
- THREAD_FIN(workers[i].thread);
+ mu_trigger_semaphore(&workers[i].start);
+ mu_wait_semaphore(&workers[i].stop);
+ mu_destroy_semaphore(&workers[i].start);
+ mu_destroy_semaphore(&workers[i].stop);
+ mu_destroy_thread(&workers[i].thread);
fz_drop_context(workers[i].ctx);
}
fz_free(ctx, workers);
@@ -1831,16 +1710,20 @@ int mudraw_main(int argc, char **argv)
if (bgprint.active)
{
bgprint.pagenum = -1;
- SEMAPHORE_TRIGGER(bgprint.start);
- SEMAPHORE_WAIT(bgprint.stop);
- SEMAPHORE_FIN(bgprint.start);
- SEMAPHORE_FIN(bgprint.stop);
- THREAD_FIN(bgprint.thread);
+ mu_trigger_semaphore(&bgprint.start);
+ mu_wait_semaphore(&bgprint.stop);
+ mu_destroy_semaphore(&bgprint.start);
+ mu_destroy_semaphore(&bgprint.stop);
+ mu_destroy_thread(&bgprint.thread);
fz_drop_context(bgprint.ctx);
}
+#endif /* DISABLE_MUTHREADS */
fz_drop_context(ctx);
- LOCKS_FIN();
+
+#ifndef DISABLE_MUTHREADS
+ fin_mudraw_locks();
+#endif /* DISABLE_MUTHREADS */
if (showmemory)
{
diff --git a/source/tools/muraster.c b/source/tools/muraster.c
index a22ee0a8..d65074d5 100644
--- a/source/tools/muraster.c
+++ b/source/tools/muraster.c
@@ -16,6 +16,17 @@
/*
CONFIGURATION SECTION
+ The first bit of configuration for this is actually in
+ how the muthreads helper library is built. If muthreads
+ does not know how to support threading on your system
+ then it will ensure that DISABLE_MUTHREADS is set. All
+ the muthreads entrypoints/types will still be defined
+ (as dummy types/functions), but attempting to use them
+ will return errors.
+
+ Configuration options affecting threading should be
+ turned off if DISABLE_MUTHREADS is set.
+
Integrators can/should define the following
MURASTER_CONFIG_ values. If not set, we'll
attempt to set sensible defaults.
@@ -122,32 +133,11 @@
/* #define MURASTER_CONFIG_GREY_FALLBACK 1 */
/*
- MURASTER_CONFIG_THREAD_SYSTEM:
-
- 0 for no threading available.
-
- 1 for Windows (or leave undefined to autodetect)
-
- 2 for PThreads (or leave undefined and use HAVE_PTHREADS)
-
- 3 (or higher) for custom threading options.
- Add your implementations further down the
- file.
-*/
-/* #undef MURASTER_CONFIG_THREAD_SYSTEM */
-
-/*
END OF CONFIGURATION SECTION
*/
#include "mupdf/fitz.h"
-
-#ifdef _MSC_VER
-#include <winsock2.h>
-#include <windows.h>
-#else
-#include <sys/time.h>
-#endif
+#include "mupdf/helpers/mu-threads.h"
/*
After this point, we convert the #defines set (or not set)
@@ -155,21 +145,6 @@
these for configuration.
*/
-/* Detect threading */
-#ifdef MURASTER_CONFIG_THREAD_SYSTEM
-#define MURASTER_THREADS MURASTER_CONFIG_THREAD_SYSTEM
-#else
-#ifdef _MSC_VER
-#define MURASTER_THREADS 1
-#else
-#ifdef HAVE_PTHREADS
-#define MURASTER_THREADS 2
-#include <pthread.h>
-#include <semaphore.h>
-#endif
-#endif
-#endif
-
#ifdef MURASTER_CONFIG_X_RESOLUTION
#define X_RESOLUTION MURASTER_CONFIG_X_RESOLUTION
#else
@@ -278,171 +253,16 @@ static const suffix_t suffix_table[] =
#endif
};
-/*
- In the presence of pthreads or Windows threads, we can offer
- a multi-threaded option. In the absence, of such, we degrade
- nicely.
-*/
-#ifdef MURASTER_THREADS
-#if MURASTER_THREADS == 1
-
-/* Windows threads */
-#define SEMAPHORE HANDLE
-#define SEMAPHORE_INIT(A) do { A = CreateSemaphore(NULL, 0, 1, NULL); } while (0)
-#define SEMAPHORE_FIN(A) do { CloseHandle(A); } while (0)
-#define SEMAPHORE_TRIGGER(A) do { (void)ReleaseSemaphore(A, 1, NULL); } while (0)
-#define SEMAPHORE_WAIT(A) do { (void)WaitForSingleObject(A, INFINITE); } while (0)
-#define THREAD HANDLE
-#define THREAD_INIT(A,B,C) do { A = CreateThread(NULL, 0, B, C, 0, NULL); } while (0)
-#define THREAD_FIN(A) do { CloseHandle(A); } while (0)
-#define THREAD_RETURN_TYPE DWORD WINAPI
-#define THREAD_RETURN() return 0
-#define MUTEX CRITICAL_SECTION
-#define MUTEX_INIT(A) do { InitializeCriticalSection(&A); } while (0)
-#define MUTEX_FIN(A) do { DeleteCriticalSection(&A); } while (0)
-#define MUTEX_LOCK(A) do { EnterCriticalSection(&A); } while (0)
-#define MUTEX_UNLOCK(A) do { LeaveCriticalSection(&A); } while (0)
-
-#elif MURASTER_THREADS == 2
-
-/*
- PThreads - without working unnamed semaphores.
-
- Neither ios nor OSX supports unnamed semaphores.
- Named semaphores are a pain to use, so we implement
- our own sempahores using condition variables and
- mutexes.
-*/
-
-typedef struct
-{
- int count;
- pthread_mutex_t mutex;
- pthread_cond_t cond;
-} my_semaphore_t;
-
-int
-my_semaphore_open(my_semaphore_t *sem)
-{
- int scode;
-
- sem->count = 0;
- scode = pthread_mutex_init(&sem->mutex, NULL);
- if (scode == 0)
- {
- scode = pthread_cond_init(&sem->cond, NULL);
- if (scode)
- pthread_mutex_destroy(&sem->mutex);
- }
- if (scode)
- memset(sem, 0, sizeof(*sem));
- return scode;
-}
-
-int
-my_semaphore_close(my_semaphore_t *sem)
-{
- int scode, scode2;
-
- scode = pthread_cond_destroy(&sem->cond);
- scode2 = pthread_mutex_destroy(&sem->mutex);
- if (scode == 0)
- scode = scode2;
- return scode;
-}
-
-int
-my_semaphore_wait(my_semaphore_t *sem)
-{
- int scode, scode2;
-
- scode = pthread_mutex_lock(&sem->mutex);
- if (scode)
- return scode;
- while (sem->count == 0) {
- scode = pthread_cond_wait(&sem->cond, &sem->mutex);
- if (scode)
- break;
- }
- if (scode == 0)
- --sem->count;
- scode2 = pthread_mutex_unlock(&sem->mutex);
- if (scode == 0)
- scode = scode2;
- return scode;
-}
-
-int
-my_semaphore_signal(my_semaphore_t * sem)
-{
- int scode, scode2;
-
- scode = pthread_mutex_lock(&sem->mutex);
- if (scode)
- return scode;
- if (sem->count++ == 0)
- scode = pthread_cond_signal(&sem->cond);
- scode2 = pthread_mutex_unlock(&sem->mutex);
- if (scode == 0)
- scode = scode2;
- return scode;
-}
-
-#define SEMAPHORE my_semaphore_t
-#define SEMAPHORE_INIT(A) do { (void)my_semaphore_open(&A); } while (0)
-#define SEMAPHORE_FIN(A) do { (void)my_semaphore_close(&A); } while (0)
-#define SEMAPHORE_TRIGGER(A) do { (void)my_semaphore_signal(&A); } while (0)
-#define SEMAPHORE_WAIT(A) do { (void)my_semaphore_wait(&A); } while (0)
-#define THREAD pthread_t
-#define THREAD_INIT(A,B,C) do { (void)pthread_create(&A, NULL, B, C); } while (0)
-#define THREAD_FIN(A) do { void *res; (void)pthread_join(A, &res); } while (0)
-#define THREAD_RETURN_TYPE void *
-#define THREAD_RETURN() return NULL
-#define MUTEX pthread_mutex_t
-#define MUTEX_INIT(A) do { (void)pthread_mutex_init(&A, NULL); } while (0)
-#define MUTEX_FIN(A) do { (void)pthread_mutex_destroy(&A); } while (0)
-#define MUTEX_LOCK(A) do { (void)pthread_mutex_lock(&A); } while (0)
-#define MUTEX_UNLOCK(A) do { (void)pthread_mutex_unlock(&A); } while (0)
-
-// ADD OTHER THREADING IMPLEMENTATIONS HERE.
-// See the above implementations for what the different
-// arguments mean.
-//
-//#elif MURASTER_THREADS == 3
-//
-//#define SEMAPHORE /* type for a semaphore */
-//#define SEMAPHORE_INIT(A) /* init a semaphore */
-//#define SEMAPHORE_FIN(A) /* finalise a semaphore */
-//#define SEMAPHORE_TRIGGER(A) /* trigger a semaphore */
-//#define SEMAPHORE_WAIT(A) /* wait for a semaphore */
-//#define THREAD /* type for a thread */
-//#define THREAD_INIT(A,B,C) /* initialise a new thread */
-//#define THREAD_FIN(A) /* finalise a thread */
-//#define THREAD_RETURN_TYPE /* return type for the thread */
-//#define THREAD_RETURN() /* command to return from a thread */
-//#define MUTEX /* type for a mutex */
-//#define MUTEX_INIT(A) /* initialise a mutex */
-//#define MUTEX_FIN(A) /* finalise a mutex */
-//#define MUTEX_LOCK(A) /* lock a mutex */
-//#define MUTEX_UNLOCK(A) /* unlock a mutex */
-
-#else
-#error Unknown MURASTER_THREADS setting
-#endif
-
-#define LOCKS_INIT() init_muraster_locks()
-#define LOCKS_FIN() fin_muraster_locks()
-
-static MUTEX mutexes[FZ_LOCK_MAX];
+static mu_mutex mutexes[FZ_LOCK_MAX];
static void muraster_lock(void *user, int lock)
{
- MUTEX_LOCK(mutexes[lock]);
+ mu_lock_mutex(&mutexes[lock]);
}
static void muraster_unlock(void *user, int lock)
{
- MUTEX_UNLOCK(mutexes[lock]);
+ mu_unlock_mutex(&mutexes[lock]);
}
static fz_locks_context muraster_locks =
@@ -450,52 +270,40 @@ static fz_locks_context muraster_locks =
NULL, muraster_lock, muraster_unlock
};
-static fz_locks_context *init_muraster_locks(void)
+static void fin_muraster_locks(void)
{
int i;
for (i = 0; i < FZ_LOCK_MAX; i++)
- MUTEX_INIT(mutexes[i]);
-
- return &muraster_locks;
+ mu_destroy_mutex(&mutexes[i]);
}
-static void fin_muraster_locks(void)
+static fz_locks_context *init_muraster_locks(void)
{
int i;
+ int failed = 0;
for (i = 0; i < FZ_LOCK_MAX; i++)
- MUTEX_FIN(mutexes[i]);
-}
-
-#else
+ failed |= mu_create_mutex(&mutexes[i]);
-/* Null Threads implementation */
-#define SEMAPHORE int
-#define THREAD int
-#define SEMAPHORE_INIT(A) do { A = 0; } while (0)
-#define SEMAPHORE_FIN(A) do { A = 0; } while (0)
-#define SEMAPHORE_TRIGGER(A) do { A = 0; } while (0)
-#define SEMAPHORE_WAIT(A) do { A = 0; } while (0)
-#define THREAD_INIT(A,B,C) do { A = 0; (void)C; } while (0)
-#define THREAD_FIN(A) do { A = 0; } while (0)
-#define LOCKS_INIT() NULL
-#define LOCKS_FIN() do { } while (0)
-
-#undef MURASTER_THREADS
-#define MURASTER_THREADS 0
+ if (failed)
+ {
+ fin_muraster_locks();
+ return NULL;
+ }
-#endif
+ return &muraster_locks;
+}
#ifdef MURASTER_CONFIG_RENDER_THREADS
#define NUM_RENDER_THREADS MURASTER_CONFIG_RENDER_THREADS
-#elif MURASTER_THREADS == 0
+#elif defined(DISABLE_MUTHREADS)
#define NUM_RENDER_THREADS 0
#else
#define NUM_RENDER_THREADS 3
#endif
-#if MURASTER_THREADS == 0 && NUM_RENDER_THREADS != 0
+#if defined(DISABLE_MUTHREADS) && NUM_RENDER_THREADS != 0
#error "Can't have MURASTER_CONFIG_RENDER_THREADS > 0 without having a threading library!"
#endif
@@ -507,7 +315,7 @@ static void fin_muraster_locks(void)
#define BGPRINT 1
#endif
-#if MURASTER_THREADS == 0 && BGPRINT != 0
+#if defined(DISABLE_MUTHREADS) && BGPRINT != 0
#error "Can't have MURASTER_CONFIG_BGPRINT > 0 without having a threading library!"
#endif
@@ -523,9 +331,9 @@ typedef struct worker_t {
fz_pixmap *pix;
fz_bitmap *bit;
fz_cookie cookie;
- SEMAPHORE start;
- SEMAPHORE stop;
- THREAD thread;
+ mu_semaphore start;
+ mu_semaphore stop;
+ mu_thread thread;
} worker_t;
static char *output = NULL;
@@ -625,9 +433,9 @@ static struct {
int solo;
int status;
fz_context *ctx;
- THREAD thread;
- SEMAPHORE start;
- SEMAPHORE stop;
+ mu_thread thread;
+ mu_semaphore start;
+ mu_semaphore stop;
int pagenum;
char *filename;
render_details render;
@@ -668,7 +476,7 @@ static void usage(void)
"\t-f\tfit file to page if too large\n"
"\t-B -\tminimum band height (e.g. 32)\n"
"\t-M -\tmax bandmemory (e.g. 655360)\n"
-#if MURASTER_THREADS != 0
+#ifndef DISABLE_MUTHREADS
"\t-T -\tnumber of threads to use for rendering\n"
"\t-P\tparallel interpretation/rendering\n"
#endif
@@ -780,7 +588,7 @@ static int dodrawpage(fz_context *ctx, int pagenum, fz_cookie *cookie, render_de
fz_set_pixmap_resolution(ctx, w->pix, x_resolution, y_resolution);
DEBUG_THREADS(("Worker %d, Pre-triggering band %d\n", band, band));
w->started = 1;
- SEMAPHORE_TRIGGER(w->start);
+ mu_trigger_semaphore(&w->start);
ctm.f -= band_height;
}
pix = workers[0].pix;
@@ -805,7 +613,7 @@ static int dodrawpage(fz_context *ctx, int pagenum, fz_cookie *cookie, render_de
{
worker_t *w = &workers[band % render->num_workers];
DEBUG_THREADS(("Waiting for worker %d to complete band %d\n", w->num, band));
- SEMAPHORE_WAIT(w->stop);
+ mu_wait_semaphore(&w->stop);
w->started = 0;
status = w->status;
pix = w->pix;
@@ -840,7 +648,7 @@ static int dodrawpage(fz_context *ctx, int pagenum, fz_cookie *cookie, render_de
memset(&w->cookie, 0, sizeof(fz_cookie));
DEBUG_THREADS(("Triggering worker %d for band_start= %d\n", w->num, w->band_start));
w->started = 1;
- SEMAPHORE_TRIGGER(w->start);
+ mu_trigger_semaphore(&w->start);
}
ctm.f -= draw_height;
}
@@ -858,7 +666,7 @@ static int dodrawpage(fz_context *ctx, int pagenum, fz_cookie *cookie, render_de
w->cookie.abort = 1;
if (w->started)
{
- SEMAPHORE_WAIT(w->stop);
+ mu_wait_semaphore(&w->stop);
w->started = 0;
}
fz_drop_pixmap(ctx, w->pix);
@@ -1011,7 +819,7 @@ static int wait_for_bgprint_to_finish(void)
if (!bgprint.active || !bgprint.started)
return 0;
- SEMAPHORE_WAIT(bgprint.stop);
+ mu_wait_semaphore(&bgprint.stop);
bgprint.started = 0;
return bgprint.status;
}
@@ -1336,7 +1144,7 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum)
}
bgprint.started = 1;
bgprint.solo = 1;
- SEMAPHORE_TRIGGER(bgprint.start);
+ mu_trigger_semaphore(&bgprint.start);
status = wait_for_bgprint_to_finish();
if (status != 0)
{
@@ -1359,7 +1167,7 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum)
bgprint.filename = filename;
bgprint.pagenum = pagenum;
bgprint.interptime = start;
- SEMAPHORE_TRIGGER(bgprint.start);
+ mu_trigger_semaphore(&bgprint.start);
}
else
{
@@ -1396,7 +1204,7 @@ finish_bgprint(fz_context *ctx)
}
bgprint.started = 1;
bgprint.solo = 1;
- SEMAPHORE_TRIGGER(bgprint.start);
+ mu_trigger_semaphore(&bgprint.start);
status = wait_for_bgprint_to_finish();
if (status != 0)
{
@@ -1484,27 +1292,26 @@ trace_realloc(void *arg, void *p_, size_t size)
return &p[1];
}
-#if MURASTER_THREADS != 0
-static THREAD_RETURN_TYPE worker_thread(void *arg)
+#ifndef DISABLE_MUTHREADS
+static void worker_thread(void *arg)
{
worker_t *me = (worker_t *)arg;
do
{
DEBUG_THREADS(("Worker %d waiting\n", me->num));
- SEMAPHORE_WAIT(me->start);
+ mu_wait_semaphore(&me->start);
DEBUG_THREADS(("Worker %d woken for band_start %d\n", me->num, me->band_start));
me->status = RENDER_OK;
if (me->band_start >= 0)
me->status = drawband(me->ctx, NULL, me->list, &me->ctm, &me->tbounds, &me->cookie, me->band_start, me->pix, &me->bit);
DEBUG_THREADS(("Worker %d completed band_start %d (status=%d)\n", me->num, me->band_start, me->status));
- SEMAPHORE_TRIGGER(me->stop);
+ mu_trigger_semaphore(&me->stop);
}
while (me->band_start >= 0);
- THREAD_RETURN();
}
-static THREAD_RETURN_TYPE bgprint_worker(void *arg)
+static void bgprint_worker(void *arg)
{
fz_cookie cookie = { 0 };
int pagenum;
@@ -1514,7 +1321,7 @@ static THREAD_RETURN_TYPE bgprint_worker(void *arg)
do
{
DEBUG_THREADS(("BGPrint waiting\n"));
- SEMAPHORE_WAIT(bgprint.start);
+ mu_wait_semaphore(&bgprint.start);
pagenum = bgprint.pagenum;
DEBUG_THREADS(("BGPrint woken for pagenum %d\n", pagenum));
if (pagenum >= 0)
@@ -1524,10 +1331,9 @@ static THREAD_RETURN_TYPE bgprint_worker(void *arg)
bgprint.status = try_render_page(bgprint.ctx, pagenum, &cookie, start, bgprint.interptime, bgprint.filename, 1, bgprint.solo, &bgprint.render);
}
DEBUG_THREADS(("BGPrint completed page %d\n", pagenum));
- SEMAPHORE_TRIGGER(bgprint.stop);
+ mu_trigger_semaphore(&bgprint.stop);
}
while (pagenum >= 0);
- THREAD_RETURN();
}
#endif
@@ -1576,9 +1382,10 @@ int main(int argc, char **argv)
{
char *password = "";
fz_document *doc = NULL;
- int c, i;
+ int i, c;
fz_context *ctx;
fz_alloc_context alloc_ctx = { NULL, trace_malloc, trace_realloc, trace_free };
+ fz_locks_context *locks = NULL;
fz_var(doc);
@@ -1666,7 +1473,16 @@ int main(int argc, char **argv)
exit(1);
}
- ctx = fz_new_context((showmemory == 0 ? NULL : &alloc_ctx), LOCKS_INIT(), FZ_STORE_DEFAULT);
+#ifndef DISABLE_MUTHREADS
+ locks = init_muraster_locks();
+ if (locks == NULL)
+ {
+ fprintf(stderr, "cannot initialise mutexes\n");
+ exit(1);
+ }
+#endif
+
+ ctx = fz_new_context((showmemory == 0 ? NULL : &alloc_ctx), locks, FZ_STORE_DEFAULT);
if (!ctx)
{
fprintf(stderr, "cannot initialise context\n");
@@ -1676,26 +1492,40 @@ int main(int argc, char **argv)
fz_set_text_aa_level(ctx, alphabits_text);
fz_set_graphics_aa_level(ctx, alphabits_graphics);
+#ifndef DISABLE_MUTHREADS
if (bgprint.active)
{
+ int fail = 0;
bgprint.ctx = fz_clone_context(ctx);
- SEMAPHORE_INIT(bgprint.start);
- SEMAPHORE_INIT(bgprint.stop);
- THREAD_INIT(bgprint.thread, bgprint_worker, NULL);
+ fail |= mu_create_semaphore(&bgprint.start);
+ fail |= mu_create_semaphore(&bgprint.stop);
+ fail |= mu_create_thread(&bgprint.thread, bgprint_worker, NULL);
+ if (fail)
+ {
+ fprintf(stderr, "bgprint startup failed\n");
+ exit(1);
+ }
}
if (num_workers > 0)
{
+ int fail = 0;
workers = fz_calloc(ctx, num_workers, sizeof(*workers));
for (i = 0; i < num_workers; i++)
{
workers[i].ctx = fz_clone_context(ctx);
workers[i].num = i;
- SEMAPHORE_INIT(workers[i].start);
- SEMAPHORE_INIT(workers[i].stop);
- THREAD_INIT(workers[i].thread, worker_thread, &workers[i]);
+ fail |= mu_create_semaphore(&workers[i].start);
+ fail |= mu_create_semaphore(&workers[i].stop);
+ fail |= mu_create_thread(&workers[i].thread, worker_thread, &workers[i]);
+ }
+ if (fail)
+ {
+ fprintf(stderr, "worker startup failed\n");
+ exit(1);
}
}
+#endif /* DISABLE_MUTHREADS */
if (layoutput_css)
{
@@ -1830,16 +1660,17 @@ int main(int argc, char **argv)
fprintf(stderr, "slowest page %d: %dms\n", timing.maxpage, timing.max);
}
+#ifndef DISABLE_MUTHREADS
if (num_workers > 0)
{
for (i = 0; i < num_workers; i++)
{
workers[i].band_start = -1;
- SEMAPHORE_TRIGGER(workers[i].start);
- SEMAPHORE_WAIT(workers[i].stop);
- SEMAPHORE_FIN(workers[i].start);
- SEMAPHORE_FIN(workers[i].stop);
- THREAD_FIN(workers[i].thread);
+ mu_trigger_semaphore(&workers[i].start);
+ mu_wait_semaphore(&workers[i].stop);
+ mu_destroy_semaphore(&workers[i].start);
+ mu_destroy_semaphore(&workers[i].stop);
+ mu_destroy_thread(&workers[i].thread);
fz_drop_context(workers[i].ctx);
}
fz_free(ctx, workers);
@@ -1848,19 +1679,22 @@ int main(int argc, char **argv)
if (bgprint.active)
{
bgprint.pagenum = -1;
- SEMAPHORE_TRIGGER(bgprint.start);
- SEMAPHORE_WAIT(bgprint.stop);
- SEMAPHORE_FIN(bgprint.start);
- SEMAPHORE_FIN(bgprint.stop);
- THREAD_FIN(bgprint.thread);
+ mu_trigger_semaphore(&bgprint.start);
+ mu_wait_semaphore(&bgprint.stop);
+ mu_destroy_semaphore(&bgprint.start);
+ mu_destroy_semaphore(&bgprint.stop);
+ mu_destroy_thread(&bgprint.thread);
fz_drop_context(bgprint.ctx);
}
+#endif /* DISABLE_MUTHREADS */
fz_drop_output(ctx, out);
out = NULL;
fz_drop_context(ctx);
- LOCKS_FIN();
+#ifndef DISABLE_MUTHREADS
+ fin_muraster_locks();
+#endif /* DISABLE_MUTHREADS */
if (showmemory)
{