Blame src/microhttpd/mhd_threads.h

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 */