summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mupdf/helpers/mu-threads.h259
-rw-r--r--platform/win32/libmuthreads.vcproj810
-rw-r--r--platform/win32/mupdf.sln41
-rw-r--r--source/helpers/mu-threads/mu-threads.c283
4 files changed, 1393 insertions, 0 deletions
diff --git a/include/mupdf/helpers/mu-threads.h b/include/mupdf/helpers/mu-threads.h
new file mode 100644
index 00000000..7cdd817b
--- /dev/null
+++ b/include/mupdf/helpers/mu-threads.h
@@ -0,0 +1,259 @@
+#ifndef MUPDF_HELPERS_MU_THREADS_H
+#define MUPDF_HELPERS_MU_THREADS_H
+
+/*
+ Simple threading helper library.
+ Includes implementations for Windows, pthreads,
+ and "no threads".
+
+ The "no threads" implementation simply provides types
+ and stub functions so that things will build, but abort
+ if we try to call them. This simplifies the job for
+ calling functions.
+
+ To build this library on a platform with no threading,
+ define DISABLE_MUTHREADS (or extend the ifdeffery below
+ so that it does so).
+
+ To build this library on a platform that uses a
+ threading model other than windows threads or pthreads,
+ extend the #ifdeffery below to set MUTHREAD_IMPL_TYPE
+ to an unused value, and modify mu-threads.c
+ appropriately.
+*/
+
+#if !defined(DISABLE_MUTHREADS)
+#if defined(_WIN32) || defined(_WIN64)
+#define MU_THREAD_IMPL_TYPE 1
+#elif defined(HAVE_PTHREADS)
+#define MU_THREAD_IMPL_TYPE 2
+#else
+#define DISABLE_MUTHREADS
+#endif
+#endif
+
+/*
+ Types
+*/
+typedef struct mu_thread_s mu_thread;
+typedef struct mu_semaphore_s mu_semaphore;
+typedef struct mu_mutex_s mu_mutex;
+
+/*
+ Semaphores
+
+ Created with a value of 0. Triggering a semaphore
+ increments the value. Waiting on a semaphore reduces
+ the value, blocking if it would become negative.
+
+ Never increment the value of a semaphore above 1, as
+ this has undefined meaning in this implementation.
+*/
+
+/*
+ mu_create_semaphore: Create a semaphore.
+
+ sem: Pointer to a mu_semaphore to populate.
+
+ Returns non-zero for error.
+*/
+int mu_create_semaphore(mu_semaphore *sem);
+
+/*
+ mu_destroy_semaphore: Destroy a semaphore.
+ Semaphores may safely be destroyed multiple
+ times. Any semaphore initialised to zeros is
+ safe to destroy.
+
+ Never destroy a semaphore that may be being waited
+ upon, as this has undefined meaning in this
+ implementation.
+
+ sem: Pointer to a mu_semaphore to destroy.
+*/
+void mu_destroy_semaphore(mu_semaphore *sem);
+
+/*
+ mu_trigger_semaphore: Increment the value of the
+ semaphore. Never blocks.
+
+ sem: The semaphore to increment.
+
+ Returns non-zero on error.
+*/
+int mu_trigger_semaphore(mu_semaphore *sem);
+
+/*
+ mu_wait_semaphore: Decrement the value of the
+ semaphore, blocking if this would involve making
+ the value negative.
+
+ sem: The semaphore to decrement.
+
+ Returns non-zero on error.
+*/
+int mu_wait_semaphore(mu_semaphore *sem);
+
+/*
+ Threads
+*/
+
+/*
+ The type for the function that a thread runs.
+
+ arg: User supplied data.
+*/
+typedef void (mu_thread_fn)(void *arg);
+
+/*
+ mu_create_thread: Create a thread to run the
+ supplied function with the supplied argument.
+
+ th: Pointer to mu_thread to populate with created
+ threads information.
+
+ fn: The function for the thread to run.
+
+ arg: The argument to pass to fn.
+*/
+int mu_create_thread(mu_thread *th, mu_thread_fn *fn, void *arg);
+
+/*
+ mu_destroy_thread: Destroy a thread. This function
+ blocks until a thread has terminated normally, and
+ destroys its storage. A mu_thread may safely be destroyed
+ multiple times, as may any mu_thread initialised with
+ zeros.
+
+ th: Pointer to mu_thread to destroy.
+*/
+void mu_destroy_thread(mu_thread *th);
+
+/*
+ Mutexes
+
+ This implementation does not specify whether
+ mutexes are recursive or not.
+*/
+
+/*
+ mu_create_mutex: Create a mutex.
+
+ mutex: pointer to a mu_mutex to populate.
+
+ Returns non-zero on error.
+*/
+int mu_create_mutex(mu_mutex *mutex);
+
+/*
+ mu_destroy_mutex: Destroy a mutex. A mu_mutex may
+ safely be destroyed several times, as may a mu_mutex
+ initialised with zeros. Never destroy locked mu_mutex.
+
+ mutex: Pointer to mu_mutex to destroy.
+*/
+void mu_destroy_mutex(mu_mutex *mutex);
+
+/*
+ mu_lock_mutex: Lock a mutex.
+
+ mutex: Mutex to lock.
+*/
+void mu_lock_mutex(mu_mutex *mutex);
+
+/*
+ mu_unlock_mutex: Unlock a mutex.
+
+ mutex: Mutex to unlock.
+*/
+void mu_unlock_mutex(mu_mutex *mutex);
+
+
+/*
+ Everything under this point is implementation specific.
+ Only people looking to extend the capabilities of this
+ helper module should need to look below here.
+*/
+
+#ifdef DISABLE_MUTHREADS
+
+/* Null implementation */
+struct mu_semaphore_s
+{
+ int dummy;
+};
+
+struct mu_thread_s
+{
+ int dummy;
+};
+
+struct mu_mutex_s
+{
+ int dummy;
+};
+
+#elif MU_THREAD_IMPL_TYPE == 1
+
+#include <windows.h>
+
+/* Windows threads */
+struct mu_semaphore_s
+{
+ HANDLE handle;
+};
+
+struct mu_thread_s
+{
+ HANDLE handle;
+ mu_thread_fn *fn;
+ void *arg;
+};
+
+struct mu_mutex_s
+{
+ CRITICAL_SECTION mutex;
+};
+
+#elif MU_THREAD_IMPL_TYPE == 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.
+*/
+
+#include <pthread.h>
+
+struct mu_semaphore_s
+{
+ int count;
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+};
+
+struct mu_thread_s
+{
+ pthread_t thread;
+ mu_thread_fn *fn;
+ void *arg;
+};
+
+struct mu_mutex_s
+{
+ pthread_mutex_t mutex;
+};
+
+/*
+ Add new threading implementations here, with
+ #elif MU_THREAD_IMPL_TYPE == 3... etc.
+*/
+
+#else
+#error Unknown MU_THREAD_IMPL_TYPE setting
+#endif
+
+#endif /* MUPDF_HELPERS_MU_THREADS_H */
diff --git a/platform/win32/libmuthreads.vcproj b/platform/win32/libmuthreads.vcproj
new file mode 100644
index 00000000..2ad84a38
--- /dev/null
+++ b/platform/win32/libmuthreads.vcproj
@@ -0,0 +1,810 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="libmuthreads"
+ ProjectGUID="{DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}"
+ RootNamespace="libmuthreads"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\include\mupdf\mu-office-lib;..\..\include"
+ PreprocessorDefinitions="WIN32;MEMENTO=1;_CRT_SECURE_NO_WARNINGS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)\$(ProjectName).lib"
+ IgnoreAllDefaultLibraries="false"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\include\mupdf\mu-office-lib;..\..\include"
+ PreprocessorDefinitions="WIN64;_CRT_SECURE_NO_WARNINGS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile=" "
+ IgnoreAllDefaultLibraries="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Memento|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\include\mupdf\mu-office-lib;..\..\include"
+ PreprocessorDefinitions="WIN32;MEMENTO=1"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)\$(ProjectName).lib"
+ IgnoreAllDefaultLibraries="false"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Memento|x64"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\include\mupdf\mu-office-lib;..\..\include"
+ PreprocessorDefinitions="WIN64;MEMENTO=1;_CRT_SECURE_NO_WARNINGS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile=" "
+ IgnoreAllDefaultLibraries="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ WholeProgramOptimization="0"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\..\include\mupdf\mu-office-lib;..\..\include"
+ PreprocessorDefinitions="WIN32"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)\$(ProjectName).lib"
+ IgnoreAllDefaultLibraries="false"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ WholeProgramOptimization="0"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\..\include\mupdf\mu-office-lib;..\..\include"
+ PreprocessorDefinitions="WIN64;_CRT_SECURE_NO_WARNINGS"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile=" "
+ IgnoreAllDefaultLibraries="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="ReleaseCommercial|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ WholeProgramOptimization="0"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\..\include\mupdf\mu-office-lib;..\..\include"
+ PreprocessorDefinitions="WIN32"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)\$(ProjectName).lib"
+ IgnoreAllDefaultLibraries="false"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="ReleaseCommercial|x64"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ WholeProgramOptimization="0"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\..\include\mupdf\mu-office-lib;..\..\include"
+ PreprocessorDefinitions="WIN64;_CRT_SECURE_NO_WARNINGS"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ IgnoreAllDefaultLibraries="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="DebugCommercial|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\include\mupdf\mu-office-lib;..\..\include"
+ PreprocessorDefinitions="WIN32"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)\$(ProjectName).lib"
+ IgnoreAllDefaultLibraries="false"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="DebugCommercial|x64"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\include\mupdf\mu-office-lib;..\..\include"
+ PreprocessorDefinitions="WIN64;_CRT_SECURE_NO_WARNINGS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ IgnoreAllDefaultLibraries="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="MementoCommercial|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\include\mupdf\mu-office-lib;..\..\include"
+ PreprocessorDefinitions="WIN32;MEMENTO=1"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)\$(ProjectName).lib"
+ IgnoreAllDefaultLibraries="false"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="MementoCommercial|x64"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\$(ProjectName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\include\mupdf\mu-office-lib;..\..\include"
+ PreprocessorDefinitions="WIN64;MEMENTO=1;_CRT_SECURE_NO_WARNINGS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ IgnoreAllDefaultLibraries="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="include"
+ >
+ <File
+ RelativePath="..\..\include\mupdf\helpers\mu-threads.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="source"
+ >
+ <File
+ RelativePath="..\..\source\helpers\mu-threads\mu-threads.c"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/platform/win32/mupdf.sln b/platform/win32/mupdf.sln
index 4525a0ae..cccd611a 100644
--- a/platform/win32/mupdf.sln
+++ b/platform/win32/mupdf.sln
@@ -75,6 +75,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "javaviewer", "javaviewer.vc
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libluratech", "libluratech.vcproj", "{B0091365-C9BA-4F40-AE2B-EF93702871B2}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmuthreads", "libmuthreads.vcproj", "{DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -667,6 +669,45 @@ Global
{B0091365-C9BA-4F40-AE2B-EF93702871B2}.ReleaseJava|x64.ActiveCfg = Release|x64
{B0091365-C9BA-4F40-AE2B-EF93702871B2}.ReleaseOpenssl|Win32.ActiveCfg = Release|Win32
{B0091365-C9BA-4F40-AE2B-EF93702871B2}.ReleaseOpenssl|x64.ActiveCfg = Release|x64
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.Debug|Win32.ActiveCfg = Debug|Win32
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.Debug|Win32.Build.0 = Debug|Win32
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.Debug|x64.ActiveCfg = Debug|x64
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.Debug|x64.Build.0 = Debug|x64
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.DebugCommercial|Win32.ActiveCfg = DebugCommercial|Win32
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.DebugCommercial|Win32.Build.0 = DebugCommercial|Win32
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.DebugCommercial|x64.ActiveCfg = DebugCommercial|x64
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.DebugCommercial|x64.Build.0 = DebugCommercial|x64
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.DebugGProof|Win32.ActiveCfg = DebugCommercial|x64
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.DebugGProof|x64.ActiveCfg = DebugCommercial|x64
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.DebugGProof|x64.Build.0 = DebugCommercial|x64
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.DebugJava|Win32.ActiveCfg = DebugCommercial|x64
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.DebugJava|x64.ActiveCfg = DebugCommercial|x64
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.DebugJava|x64.Build.0 = DebugCommercial|x64
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.DebugOpenssl|Win32.ActiveCfg = DebugCommercial|x64
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.DebugOpenssl|x64.ActiveCfg = DebugCommercial|x64
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.DebugOpenssl|x64.Build.0 = DebugCommercial|x64
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.Memento|Win32.ActiveCfg = Memento|Win32
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.Memento|Win32.Build.0 = Memento|Win32
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.Memento|x64.ActiveCfg = Memento|x64
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.Memento|x64.Build.0 = Memento|x64
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.MementoCommercial|Win32.ActiveCfg = MementoCommercial|Win32
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.MementoCommercial|Win32.Build.0 = MementoCommercial|Win32
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.MementoCommercial|x64.ActiveCfg = MementoCommercial|x64
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.MementoCommercial|x64.Build.0 = MementoCommercial|x64
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.Release|Win32.ActiveCfg = Release|Win32
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.Release|Win32.Build.0 = Release|Win32
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.Release|x64.ActiveCfg = Release|x64
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.Release|x64.Build.0 = Release|x64
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.ReleaseCommercial|Win32.ActiveCfg = ReleaseCommercial|Win32
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.ReleaseCommercial|Win32.Build.0 = ReleaseCommercial|Win32
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.ReleaseCommercial|x64.ActiveCfg = ReleaseCommercial|x64
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.ReleaseCommercial|x64.Build.0 = ReleaseCommercial|x64
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.ReleaseJava|Win32.ActiveCfg = ReleaseCommercial|x64
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.ReleaseJava|x64.ActiveCfg = ReleaseCommercial|x64
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.ReleaseJava|x64.Build.0 = ReleaseCommercial|x64
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.ReleaseOpenssl|Win32.ActiveCfg = ReleaseCommercial|x64
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.ReleaseOpenssl|x64.ActiveCfg = ReleaseCommercial|x64
+ {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B}.ReleaseOpenssl|x64.Build.0 = ReleaseCommercial|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/source/helpers/mu-threads/mu-threads.c b/source/helpers/mu-threads/mu-threads.c
new file mode 100644
index 00000000..bbc87d1a
--- /dev/null
+++ b/source/helpers/mu-threads/mu-threads.c
@@ -0,0 +1,283 @@
+#include "mupdf/helpers/mu-threads.h"
+
+#ifdef DISABLE_MUTHREADS
+
+#include <stdlib.h>
+
+/* Null implementation. Just error out. */
+
+int mu_create_semaphore(mu_semaphore *sem)
+{
+ return 1; /* Just Error */
+}
+
+void mu_destroy_semaphore(mu_semaphore *sem)
+{
+}
+
+int mu_trigger_semaphore(mu_semaphore *sem)
+{
+ abort();
+ return 1;
+}
+
+int mu_wait_semaphore(mu_semaphore *sem)
+{
+ abort();
+ return 1;
+}
+
+int mu_create_thread(mu_thread *th, mu_thread_fn *fn, void *arg)
+{
+ return 1;
+}
+
+void mu_destroy_thread(mu_thread *th)
+{
+}
+
+int mu_create_mutex(mu_mutex *mutex)
+{
+ return 1;
+}
+
+void mu_destroy_mutex(mu_mutex *mutex)
+{
+}
+
+void mu_lock_mutex(mu_mutex *mutex)
+{
+ abort();
+}
+
+void mu_unlock_mutex(mu_mutex *mutex)
+{
+ abort();
+}
+
+#elif MU_THREAD_IMPL_TYPE == 1
+
+/* Windows threads */
+int mu_create_semaphore(mu_semaphore *sem)
+{
+ sem->handle = CreateSemaphore(NULL, 0, 1, NULL);
+ return (sem->handle != NULL);
+}
+
+void mu_destroy_semaphore(mu_semaphore *sem)
+{
+ if (sem->handle == NULL)
+ return;
+ /* We can't sensibly handle this failing */
+ (void)CloseHandle(sem->handle);
+}
+
+int mu_trigger_semaphore(mu_semaphore *sem)
+{
+ if (sem->handle == NULL)
+ return 0;
+ /* We can't sensibly handle this failing */
+ return !ReleaseSemaphore(sem->handle, 1, NULL);
+}
+
+int mu_wait_semaphore(mu_semaphore *sem)
+{
+ if (sem->handle == NULL)
+ return 0;
+ /* We can't sensibly handle this failing */
+ return !WaitForSingleObject(sem->handle, INFINITE);
+}
+
+static DWORD WINAPI thread_starter(LPVOID arg)
+{
+ mu_thread *th = (mu_thread *)arg;
+
+ th->fn(th->arg);
+
+ return 0;
+}
+
+int mu_create_thread(mu_thread *th, mu_thread_fn *fn, void *arg)
+{
+ th->fn = fn;
+ th->arg = arg;
+ th->handle = CreateThread(NULL, 0, thread_starter, th, 0, NULL);
+
+ return (th->handle != NULL);
+}
+
+void mu_destroy_thread(mu_thread *th)
+{
+ if (th->handle == NULL)
+ return;
+ /* We can't sensibly handle this failing */
+ (void)WaitForSingleObject(th->handle, INFINITE);
+ (void)CloseHandle(th->handle);
+}
+
+int mu_create_mutex(mu_mutex *mutex)
+{
+ InitializeCriticalSection(&mutex->mutex);
+ return 0; /* Magic function, never fails */
+}
+
+void mu_destroy_mutex(mu_mutex *mutex)
+{
+ const static CRITICAL_SECTION empty = { 0 };
+ if (memcmp(&mutex->mutex, &empty, sizeof(empty)) == 0)
+ return;
+ DeleteCriticalSection(&mutex->mutex);
+ mutex->mutex = empty;
+}
+
+void mu_lock_mutex(mu_mutex *mutex)
+{
+ EnterCriticalSection(&mutex->mutex);
+}
+
+void mu_unlock_mutex(mu_mutex *mutex)
+{
+ LeaveCriticalSection(&mutex->mutex);
+}
+
+#elif MU_THREAD_IMPL_TYPE == 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.
+*/
+
+#include <string.h>
+
+struct mu_sempahore
+{
+ int count;
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+};
+
+int
+mu_create_semaphore(mu_semaphore *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;
+}
+
+void
+mu_destroy_semaphore(mu_semaphore *sem)
+{
+ const static mu_semaphore empty = { 0 };
+
+ if (memcmp(sem, &empty, sizeof(empty)) == 0)
+ return;
+ (void)pthread_cond_destroy(&sem->cond);
+ (void)pthread_mutex_destroy(&sem->mutex);
+ *sem = empty;
+}
+
+int
+mu_wait_semaphore(mu_semaphore *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
+mu_trigger_semaphore(mu_semaphore * 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;
+}
+
+static void *thread_starter(void *arg)
+{
+ mu_thread *th = (mu_thread *)arg;
+
+ th->fn(th->arg);
+
+ return NULL;
+}
+
+int mu_create_thread(mu_thread *th, mu_thread_fn *fn, void *arg)
+{
+ th->fn = fn;
+ th->arg = arg;
+ return pthread_create(&th->thread, NULL, thread_starter, th);
+}
+
+void mu_destroy_thread(mu_thread *th)
+{
+ const static mu_thread empty = { 0 };
+
+ if (memcmp(th, &empty, sizeof(empty)) == 0)
+ return;
+
+ (void)pthread_join(th->thread, NULL);
+ *th = empty;
+}
+
+int mu_create_mutex(mu_mutex *mutex)
+{
+ return pthread_mutex_init(&mutex->mutex, NULL);
+}
+
+void mu_destroy_mutex(mu_mutex *mutex)
+{
+ const static mu_mutex empty = { 0 };
+ if (memcmp(mutex, &empty, sizeof(empty)) == 0)
+ return;
+ (void)pthread_mutex_destroy(&mutex->mutex);
+ *mutex = empty;
+}
+
+void mu_lock_mutex(mu_mutex *mutex)
+{
+ (void)pthread_mutex_lock(&mutex->mutex);
+}
+
+void mu_unlock_mutex(mu_mutex *mutex)
+{
+ (void)pthread_mutex_unlock(&mutex->mutex);
+}
+
+#else
+#error Unknown MU_THREAD_IMPL_TYPE setting
+#endif