/**\file n_thread_pool.h
 *  Thread pool declaration
 *\author Castagnier Mickael
 *\version 1.0
 *\date 30/04/2014
 */
#ifndef NILOREA_THREAD_POOL_LIBRARY
#define NILOREA_THREAD_POOL_LIBRARY

#ifdef __cplusplus
extern "C"
{
#endif

/**\defgroup THREADS THREADS: tools to create and manage a thread pool
   \addtogroup THREADS 
  @{
*/

#include "n_log.h"
#include "n_common.h"
#include <pthread.h>
#include <semaphore.h>


/*! processing mode for added func, synced start */
#define SYNCED_PROC 1
/*! processing mode for added func, direct start */
#define DIRECT_PROC 2
/*! status of an idle thread */
#define IDLE_THREAD 1
/*! status of a busy thread  */
#define BUSY_THREAD 2
/*! status for a running thread */
#define RUNNING_THREAD 3
/*! status of an exiting thread */
#define EXITING_THREAD 4

/*! A thread pool node */
typedef struct THREAD_POOL_NODE
{
   /*! function to call in the thread */
   void *(*func)(void *param);
   /*! if not NULL , passed as argument */
   void *param ;
   /*! starting semaphore */
   sem_t th_start , 
         /*! ending semaphore */
         th_end ;
   /*! mutex to prevent mutual access */
   pthread_mutex_t lock ;
   /*! SYNCED or DIRECT process start */
   int type ;
   /*! state of the thread */
   int state ;
   /*! thread id */
   pthread_t thr ;

} THREAD_POOL_NODE ;


/*! Structure of a trhead pool */
typedef struct THREAD_POOL
{
   /*! Dynamically allocated but fixed size thread array */
   THREAD_POOL_NODE **thread_list ;
   /*! Maximum number of threads in the list */
   int max_threads ;
} THREAD_POOL ;

/* allocate a new thread pool */
THREAD_POOL *new_thread_pool( int nbmaxthr );
/* add a function to run in an available thread inside a pool */
int add_threaded_process( THREAD_POOL *thread_pool , void *(*func_ptr)(void *param) , void *param , int mode );
/* tell all the waiting threads to start their associated process */
int start_threaded_pool( THREAD_POOL *thread_pool );
/* wait for all busy thread to finish */
int wait_for_threaded_pool( THREAD_POOL *thread_pool );

/*@}*/

#ifdef __cplusplus
}
#endif

#endif

