/* AUTORIGHTS
Copyright (C) 2007 Princeton University
      
This file is part of Ferret Toolkit.

Ferret Toolkit is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/*
 * tpool.c: A thread pool
 *
 * Functions to start, manage and terminate a thread pool
 */

#include <stdlib.h>
#include <assert.h>
#include <pthread.h>

#include "tpool.h"

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#ifdef ENABLE_PARSEC_UPTCPIP
#include <uptcp_socket.h>
#endif


/* Creates a new thread pool.
 * After the function terminates successfully, nthreads threads are running.
 *
 * opts:        Array with the start function and thread arguments for each thread
 * nthreads:    Number of threads to create (and number of entries in opts)
 *
 * return:      Pointer to the thread pool (or NULL if an error occurred)
 */
tpool_t *tpool_create(tdesc_t *opts, int nthreads) {
    int i;
    tpool_t *pool;
    const pthread_attr_t *attr;
    void *arg;
    int rv;
    
    /* Check arguments */
    if(opts == NULL || nthreads < 1) {
        return NULL;
    }
    for(i=0; i<nthreads; i++) {
        if(opts[i].start_routine == NULL) {
            return NULL;
        }
    }
    
    /* Create data structure */
    pool = (tpool_t *)malloc(sizeof(tpool_t));
    if(pool == NULL) {
        return NULL;
    }
    pool->threads = (pthread_t *)malloc(sizeof(pthread_t) * nthreads);
    if(pool->threads == NULL) {
        free(pool);
        return NULL;
    }
    
    /* Create threads and initialize data structures */
    for(i=0; i<nthreads; i++) {
        if(opts[i].attr == NULL) {
            attr = NULL;
        } else {
            attr = opts[i].attr;
        }
        if(opts[i].arg == NULL) {
            arg = NULL;
        } else {
            arg = opts[i].arg;
        }
#ifdef ENABLE_PARSEC_UPTCPIP 
        rv = uptcp_pthread_create(&(pool->threads[i]), attr, opts[i].start_routine, arg);
#else        
        rv = pthread_create(&(pool->threads[i]), attr, opts[i].start_routine, arg);
#endif
        if(rv != 0) {
            free(pool->threads);
            free(pool);
            return NULL;
        }
    }
    pool->nthreads = nthreads;
    pool->state = POOL_STATE_RUNNING;
    
    return pool;
}

/*
 * Destroys the thread pool.
 * The threads of the thread pool should already have been stopped when this function
 * is called.
 *
 * pool:        Pointer to the thread pool
 *
 */
void tpool_destroy(tpool_t *pool) {
    assert(pool!=NULL);
    assert(pool->state!=POOL_STATE_RUNNING);
    
    free(pool->threads);
    free(pool);
}

/*
 * Waits until all threads have joined.
 *
 * pool:        Pointer to the thread pool
 * value_ptrs:  Array for the return values of the thread functions (can be NULL)
 *
 * return:      -1 if an error occurred, 0 otherwise
 */
int tpool_join(tpool_t *pool, void **value_ptrs) {
    int i;
    void **value_ptr;
    int rv;
    
    assert(pool!=NULL);
    assert(pool->state==POOL_STATE_RUNNING);

    /* Join threads */
    for(i=0; i<pool->nthreads; i++) {
        if(value_ptrs != NULL) {
            value_ptr = &(value_ptrs[i]);
        } else {
            value_ptr = NULL;
        }
        
        rv = pthread_join(pool->threads[i], value_ptr);
        if(rv != 0) {
            pool->state = POOL_STATE_ERROR;
            return -1;
        }
    }
    
    pool->state = POOL_STATE_READY;
    return 0;
}

/*
 * Cancels all threads of the pool.
 *
 * pool:        Pointer to the thread pool
 *
 * return:      -1 if an error occurred, 0 otherwise
 */
int tpool_cancel(tpool_t *pool) {
    int i;
    int rv;
    
    assert(pool!=NULL);
    assert(pool->state==POOL_STATE_RUNNING);

    rv = 0;    
    for(i=0; i<pool->nthreads; i++) {
        rv += pthread_cancel(pool->threads[i]);
    }
    
    if(rv != 0) {
        pool->state = POOL_STATE_ERROR;
        return -1;
    }
    
    pool->state = POOL_STATE_READY;
    return 0;
}
