|
Packit |
875988 |
/*
|
|
Packit |
875988 |
This file is part of libmicrohttpd
|
|
Packit |
875988 |
Copyright (C) 2016 Karlson2k (Evgeny Grin)
|
|
Packit |
875988 |
|
|
Packit |
875988 |
This library is free software; you can redistribute it and/or
|
|
Packit |
875988 |
modify it under the terms of the GNU Lesser General Public
|
|
Packit |
875988 |
License as published by the Free Software Foundation; either
|
|
Packit |
875988 |
version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
875988 |
|
|
Packit |
875988 |
This library is distributed in the hope that it will be useful,
|
|
Packit |
875988 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
875988 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
875988 |
Lesser General Public License for more details.
|
|
Packit |
875988 |
|
|
Packit |
875988 |
You should have received a copy of the GNU Lesser General Public
|
|
Packit |
875988 |
License along with this library; if not, write to the Free Software
|
|
Packit |
875988 |
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
Packit |
875988 |
|
|
Packit |
875988 |
*/
|
|
Packit |
875988 |
|
|
Packit |
875988 |
/**
|
|
Packit |
875988 |
* @file microhttpd/mhd_threads.h
|
|
Packit |
875988 |
* @brief Header for platform-independent threads abstraction
|
|
Packit |
875988 |
* @author Karlson2k (Evgeny Grin)
|
|
Packit |
875988 |
*
|
|
Packit |
875988 |
* Provides basic abstraction for threads.
|
|
Packit |
875988 |
* Any functions can be implemented as macro on some platforms
|
|
Packit |
875988 |
* unless explicitly marked otherwise.
|
|
Packit |
875988 |
* Any function argument can be skipped in macro, so avoid
|
|
Packit |
875988 |
* variable modification in function parameters.
|
|
Packit |
875988 |
*
|
|
Packit |
875988 |
* @warning Unlike pthread functions, most of functions return
|
|
Packit |
875988 |
* nonzero on success.
|
|
Packit |
875988 |
*/
|
|
Packit |
875988 |
|
|
Packit |
875988 |
#ifndef MHD_THREADS_H
|
|
Packit |
875988 |
#define MHD_THREADS_H 1
|
|
Packit |
875988 |
|
|
Packit |
875988 |
#include "mhd_options.h"
|
|
Packit |
875988 |
#ifdef HAVE_STDDEF_H
|
|
Packit |
875988 |
# include <stddef.h> /* for size_t */
|
|
Packit |
875988 |
#else /* ! HAVE_STDDEF_H */
|
|
Packit |
875988 |
# include <stdlib.h> /* for size_t */
|
|
Packit |
875988 |
#endif /* ! HAVE_STDDEF_H */
|
|
Packit |
875988 |
|
|
Packit |
875988 |
#if defined(MHD_USE_POSIX_THREADS)
|
|
Packit |
875988 |
# undef HAVE_CONFIG_H
|
|
Packit |
875988 |
# include <pthread.h>
|
|
Packit |
875988 |
# define HAVE_CONFIG_H 1
|
|
Packit |
875988 |
#elif defined(MHD_USE_W32_THREADS)
|
|
Packit |
875988 |
# ifndef WIN32_LEAN_AND_MEAN
|
|
Packit |
875988 |
# define WIN32_LEAN_AND_MEAN 1
|
|
Packit |
875988 |
# endif /* !WIN32_LEAN_AND_MEAN */
|
|
Packit |
875988 |
# include <windows.h>
|
|
Packit |
875988 |
#else
|
|
Packit |
875988 |
# error No threading API is available.
|
|
Packit |
875988 |
#endif
|
|
Packit |
875988 |
|
|
Packit |
875988 |
#ifndef MHD_NO_THREAD_NAMES
|
|
Packit |
875988 |
# if defined(MHD_USE_POSIX_THREADS)
|
|
Packit |
875988 |
# if defined(HAVE_PTHREAD_SETNAME_NP_GNU) || defined(HAVE_PTHREAD_SET_NAME_NP_FREEBSD) || \
|
|
Packit |
875988 |
defined(HAVE_PTHREAD_SETNAME_NP_DARWIN) || defined(HAVE_PTHREAD_SETNAME_NP_NETBSD) || \
|
|
Packit |
875988 |
defined(HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD) || defined(HAVE_PTHREAD_ATTR_SETNAME_NP_IBMI)
|
|
Packit |
875988 |
# define MHD_USE_THREAD_NAME_
|
|
Packit |
875988 |
# endif /* HAVE_PTHREAD_SETNAME_NP */
|
|
Packit |
875988 |
# elif defined(MHD_USE_W32_THREADS)
|
|
Packit |
875988 |
# ifdef _MSC_FULL_VER
|
|
Packit |
875988 |
/* Thread names only available with VC compiler */
|
|
Packit |
875988 |
# define MHD_USE_THREAD_NAME_
|
|
Packit |
875988 |
# endif /* _MSC_FULL_VER */
|
|
Packit |
875988 |
# endif
|
|
Packit |
875988 |
#endif
|
|
Packit |
875988 |
|
|
Packit |
875988 |
#if defined(MHD_USE_POSIX_THREADS)
|
|
Packit |
875988 |
typedef pthread_t MHD_thread_handle_;
|
|
Packit |
875988 |
#elif defined(MHD_USE_W32_THREADS)
|
|
Packit |
875988 |
typedef HANDLE MHD_thread_handle_;
|
|
Packit |
875988 |
#endif
|
|
Packit |
875988 |
|
|
Packit |
875988 |
#if defined(MHD_USE_POSIX_THREADS)
|
|
Packit |
875988 |
# define MHD_THRD_RTRN_TYPE_ void*
|
|
Packit |
875988 |
# define MHD_THRD_CALL_SPEC_
|
|
Packit |
875988 |
#elif defined(MHD_USE_W32_THREADS)
|
|
Packit |
875988 |
# define MHD_THRD_RTRN_TYPE_ unsigned
|
|
Packit |
875988 |
# define MHD_THRD_CALL_SPEC_ __stdcall
|
|
Packit |
875988 |
#endif
|
|
Packit |
875988 |
|
|
Packit |
875988 |
#if defined(MHD_USE_POSIX_THREADS)
|
|
Packit |
875988 |
typedef pthread_t MHD_thread_ID_;
|
|
Packit |
875988 |
#elif defined(MHD_USE_W32_THREADS)
|
|
Packit |
875988 |
typedef DWORD MHD_thread_ID_;
|
|
Packit |
875988 |
#endif
|
|
Packit |
875988 |
|
|
Packit |
875988 |
/* Depending on implementation, pthread_create() MAY set thread ID into
|
|
Packit |
875988 |
* provided pointer and after it start thread OR start thread and after
|
|
Packit |
875988 |
* if set thread ID. In latter case, to avoid data races, additional
|
|
Packit |
875988 |
* pthread_self() call is required in thread routine. Is some platform
|
|
Packit |
875988 |
* is known for setting thread ID BEFORE starting thread macro
|
|
Packit |
875988 |
* MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD could be defined
|
|
Packit |
875988 |
* to save some resources. */
|
|
Packit |
875988 |
#if defined(MHD_USE_POSIX_THREADS)
|
|
Packit |
875988 |
# ifdef MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD
|
|
Packit |
875988 |
union _MHD_thread_handle_ID_
|
|
Packit |
875988 |
{
|
|
Packit |
875988 |
MHD_thread_handle_ handle; /**< To be used in other threads */
|
|
Packit |
875988 |
MHD_thread_ID_ ID; /**< To be used in thread itself */
|
|
Packit |
875988 |
};
|
|
Packit |
875988 |
typedef union _MHD_thread_handle_ID_ MHD_thread_handle_ID_;
|
|
Packit |
875988 |
# else /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */
|
|
Packit |
875988 |
struct _MHD_thread_handle_ID_
|
|
Packit |
875988 |
{
|
|
Packit |
875988 |
MHD_thread_handle_ handle; /**< To be used in other threads */
|
|
Packit |
875988 |
MHD_thread_ID_ ID; /**< To be used in thread itself */
|
|
Packit |
875988 |
};
|
|
Packit |
875988 |
typedef struct _MHD_thread_handle_ID_ MHD_thread_handle_ID_;
|
|
Packit |
875988 |
# endif /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */
|
|
Packit |
875988 |
#elif defined(MHD_USE_W32_THREADS)
|
|
Packit |
875988 |
struct _MHD_thread_handle_ID_
|
|
Packit |
875988 |
{
|
|
Packit |
875988 |
MHD_thread_handle_ handle; /**< To be used in other threads */
|
|
Packit |
875988 |
MHD_thread_ID_ ID; /**< To be used in thread itself */
|
|
Packit |
875988 |
};
|
|
Packit |
875988 |
typedef struct _MHD_thread_handle_ID_ MHD_thread_handle_ID_;
|
|
Packit |
875988 |
#endif
|
|
Packit |
875988 |
|
|
Packit |
875988 |
#if defined(MHD_USE_POSIX_THREADS)
|
|
Packit |
875988 |
/**
|
|
Packit |
875988 |
* Wait until specified thread is ended and free thread handle on success.
|
|
Packit |
875988 |
* @param thread handle to watch
|
|
Packit |
875988 |
* @return nonzero on success, zero otherwise
|
|
Packit |
875988 |
*/
|
|
Packit |
875988 |
#define MHD_join_thread_(thread) (!pthread_join((thread), NULL))
|
|
Packit |
875988 |
#elif defined(MHD_USE_W32_THREADS)
|
|
Packit |
875988 |
/**
|
|
Packit |
875988 |
* Wait until specified thread is ended and free thread handle on success.
|
|
Packit |
875988 |
* @param thread handle to watch
|
|
Packit |
875988 |
* @return nonzero on success, zero otherwise
|
|
Packit |
875988 |
*/
|
|
Packit |
875988 |
#define MHD_join_thread_(thread) (WAIT_OBJECT_0 == WaitForSingleObject((thread), INFINITE) ? (CloseHandle((thread)), !0) : 0)
|
|
Packit |
875988 |
#endif
|
|
Packit |
875988 |
|
|
Packit |
875988 |
#if defined(MHD_USE_POSIX_THREADS)
|
|
Packit |
875988 |
/**
|
|
Packit |
875988 |
* Check whether provided thread ID match current thread.
|
|
Packit |
875988 |
* @param ID thread ID to match
|
|
Packit |
875988 |
* @return nonzero on match, zero otherwise
|
|
Packit |
875988 |
*/
|
|
Packit |
875988 |
#define MHD_thread_ID_match_current_(ID) (pthread_equal((ID), pthread_self()))
|
|
Packit |
875988 |
#elif defined(MHD_USE_W32_THREADS)
|
|
Packit |
875988 |
/**
|
|
Packit |
875988 |
* Check whether provided thread ID match current thread.
|
|
Packit |
875988 |
* @param ID thread ID to match
|
|
Packit |
875988 |
* @return nonzero on match, zero otherwise
|
|
Packit |
875988 |
*/
|
|
Packit |
875988 |
#define MHD_thread_ID_match_current_(ID) (GetCurrentThreadId() == (ID))
|
|
Packit |
875988 |
#endif
|
|
Packit |
875988 |
|
|
Packit |
875988 |
#if defined(MHD_USE_POSIX_THREADS)
|
|
Packit |
875988 |
# ifdef MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD
|
|
Packit |
875988 |
/**
|
|
Packit |
875988 |
* Initialise thread ID.
|
|
Packit |
875988 |
* @param thread_handle_ID_ptr pointer to thread handle-ID
|
|
Packit |
875988 |
*/
|
|
Packit |
875988 |
#define MHD_thread_init_(thread_handle_ID_ptr) (void)0
|
|
Packit |
875988 |
# else /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */
|
|
Packit |
875988 |
/**
|
|
Packit |
875988 |
* Initialise thread ID.
|
|
Packit |
875988 |
* @param thread_handle_ID_ptr pointer to thread handle-ID
|
|
Packit |
875988 |
*/
|
|
Packit |
875988 |
#define MHD_thread_init_(thread_handle_ID_ptr) ((thread_handle_ID_ptr)->ID=pthread_self())
|
|
Packit |
875988 |
# endif /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */
|
|
Packit |
875988 |
#elif defined(MHD_USE_W32_THREADS)
|
|
Packit |
875988 |
/**
|
|
Packit |
875988 |
* Initialise thread ID.
|
|
Packit |
875988 |
* @param thread_handle_ID_ptr pointer to thread handle-ID
|
|
Packit |
875988 |
*/
|
|
Packit |
875988 |
#define MHD_thread_init_(thread_handle_ID_ptr) ((thread_handle_ID_ptr)->ID=GetCurrentThreadId())
|
|
Packit |
875988 |
#endif
|
|
Packit |
875988 |
|
|
Packit |
875988 |
/**
|
|
Packit |
875988 |
* Signature of main function for a thread.
|
|
Packit |
875988 |
*
|
|
Packit |
875988 |
* @param cls closure argument for the function
|
|
Packit |
875988 |
* @return termination code from the thread
|
|
Packit |
875988 |
*/
|
|
Packit |
875988 |
typedef MHD_THRD_RTRN_TYPE_
|
|
Packit |
875988 |
(MHD_THRD_CALL_SPEC_ *MHD_THREAD_START_ROUTINE_)(void *cls);
|
|
Packit |
875988 |
|
|
Packit |
875988 |
|
|
Packit |
875988 |
/**
|
|
Packit |
875988 |
* Create a thread and set the attributes according to our options.
|
|
Packit |
875988 |
*
|
|
Packit |
875988 |
* If thread is created, thread handle must be freed by MHD_join_thread_().
|
|
Packit |
875988 |
*
|
|
Packit |
875988 |
* @param thread handle to initialize
|
|
Packit |
875988 |
* @param stack_size size of stack for new thread, 0 for default
|
|
Packit |
875988 |
* @param start_routine main function of thread
|
|
Packit |
875988 |
* @param arg argument for start_routine
|
|
Packit |
875988 |
* @return non-zero on success; zero otherwise
|
|
Packit |
875988 |
*/
|
|
Packit |
875988 |
int
|
|
Packit |
875988 |
MHD_create_thread_ (MHD_thread_handle_ID_ *thread,
|
|
Packit |
875988 |
size_t stack_size,
|
|
Packit |
875988 |
MHD_THREAD_START_ROUTINE_ start_routine,
|
|
Packit |
875988 |
void *arg);
|
|
Packit |
875988 |
|
|
Packit |
875988 |
#ifndef MHD_USE_THREAD_NAME_
|
|
Packit |
875988 |
#define MHD_create_named_thread_(t,n,s,r,a) MHD_create_thread_((t),(s),(r),(a))
|
|
Packit |
875988 |
#else /* MHD_USE_THREAD_NAME_ */
|
|
Packit |
875988 |
/**
|
|
Packit |
875988 |
* Create a named thread and set the attributes according to our options.
|
|
Packit |
875988 |
*
|
|
Packit |
875988 |
* @param thread handle to initialize
|
|
Packit |
875988 |
* @param thread_name name for new thread
|
|
Packit |
875988 |
* @param stack_size size of stack for new thread, 0 for default
|
|
Packit |
875988 |
* @param start_routine main function of thread
|
|
Packit |
875988 |
* @param arg argument for start_routine
|
|
Packit |
875988 |
* @return non-zero on success; zero otherwise
|
|
Packit |
875988 |
*/
|
|
Packit |
875988 |
int
|
|
Packit |
875988 |
MHD_create_named_thread_ (MHD_thread_handle_ID_ *thread,
|
|
Packit |
875988 |
const char* thread_name,
|
|
Packit |
875988 |
size_t stack_size,
|
|
Packit |
875988 |
MHD_THREAD_START_ROUTINE_ start_routine,
|
|
Packit |
875988 |
void *arg);
|
|
Packit |
875988 |
|
|
Packit |
875988 |
#endif /* MHD_USE_THREAD_NAME_ */
|
|
Packit |
875988 |
|
|
Packit |
875988 |
#endif /* ! MHD_THREADS_H */
|