Mercurial > hgrepos > Python2 > PyMuPDF
view mupdf-source/source/helpers/mu-threads/mu-threads.c @ 21:2f43e400f144
Provide an "all" target to build both the sdist and the wheel
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Fri, 19 Sep 2025 10:28:53 +0200 |
| parents | b50eed0cc0ef |
| children |
line wrap: on
line source
// Copyright (C) 2004-2021 Artifex Software, Inc. // // This file is part of MuPDF. // // MuPDF is free software: you can redistribute it and/or modify it under the // terms of the GNU Affero General Public License as published by the Free // Software Foundation, either version 3 of the License, or (at your option) // any later version. // // MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more // details. // // You should have received a copy of the GNU Affero General Public License // along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html> // // Alternative licensing terms are available from the licensor. // For commercial licensing, see <https://www.artifex.com/> or contact // Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco, // CA 94129, USA, for further information. #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); th->handle = NULL; } 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 semaphores using condition variables and mutexes. */ #include <string.h> 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; /* static objects are always initialized to zero */ 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; /* static objects are always initialized to zero */ 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
