/* * Copyright (c) 2008-2024 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License version 3.0 only, * as published by the Free Software Foundation. * * This program 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 Lesser General Public License * version 3.0 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3.0 along with this program. If not, see * <https://www.gnu.org/licenses/>. */ #include "objfw-defs.h" #include "platform.h" #if !defined(OF_HAVE_THREADS) || \ (!defined(OF_HAVE_PTHREADS) && !defined(OF_WINDOWS) && !defined(OF_AMIGAOS)) # error No threads available! #endif #import "OFObject.h" /** @file */ #if defined(OF_HAVE_PTHREADS) # include <pthread.h> typedef pthread_t OFPlainThread; #elif defined(OF_WINDOWS) # include <windows.h> typedef HANDLE OFPlainThread; #elif defined(OF_AMIGAOS) # include <exec/tasks.h> # include <exec/semaphores.h> typedef struct { struct Task *task; void (*function)(id); id object; struct SignalSemaphore semaphore; struct Task *joinTask; unsigned char joinSigBit; bool detached, done; } *OFPlainThread; #endif typedef struct { float priority; size_t stackSize; } OFPlainThreadAttributes; #if defined(OF_HAVE_PTHREADS) || defined(DOXYGEN) /** * @brief Returns the current plain thread. * * @return The current plain thread */ static OF_INLINE OFPlainThread OFCurrentPlainThread(void) { return pthread_self(); } /** * @brief Returns whether the specified plain thread is the current thread. * * @param thread The thread to check * @return Whether the specified plain thread is the current thread */ static OF_INLINE bool OFPlainThreadIsCurrent(OFPlainThread thread) { return pthread_equal(thread, pthread_self()); } #elif defined(OF_WINDOWS) static OF_INLINE OFPlainThread OFCurrentPlainThread(void) { return GetCurrentThread(); } static OF_INLINE bool OFPlainThreadIsCurrent(OFPlainThread thread) { return (thread == GetCurrentThread()); } #elif defined(OF_AMIGAOS) extern OFPlainThread OFCurrentPlainThread(void); extern bool OFPlainThreadIsCurrent(OFPlainThread); #endif #ifdef __cplusplus extern "C" { #endif /** * @brief Initializes the specified thread attributes. * * @param attr A pointer to the thread attributes to initialize * @return 0 on success, or an error number from `<errno.h>` on error */ extern int OFPlainThreadAttributesInit(OFPlainThreadAttributes *attr); /** * @brief Creates a new plain thread. * * A plain thread is similar to @ref OFThread, but does not use exceptions and * is just a lightweight wrapper around the system's thread implementation. * * @param thread A pointer to the thread to create * @param name A name for the thread * @param function The function the thread should execute * @param object The object to pass to the thread as an argument * @param attr Thread attributes * @return 0 on success, or an error number from `<errno.h>` on error */ extern int OFPlainThreadNew(OFPlainThread *thread, const char *name, void (*function)(id), id object, const OFPlainThreadAttributes *attr); /** * @brief Sets the name of the current thread. * * @param name The name for the current thread */ extern void OFSetThreadName(const char *name); /** * @brief Joins the specified thread. * * @param thread The thread to join * @return 0 on success, or an error number from `<errno.h>` on error */ extern int OFPlainThreadJoin(OFPlainThread thread); /** * @brief Detaches the specified thread. * * @param thread The thread to detach * @return 0 on success, or an error number from `<errno.h>` on error */ extern int OFPlainThreadDetach(OFPlainThread thread); #ifdef __cplusplus } #endif