/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <axutil_thread_pool.h>
#include <axutil_env.h>
#include <axutil_error_default.h>

struct axutil_thread_pool
{
    axutil_allocator_t *allocator;
};

AXIS2_EXTERN axutil_thread_pool_t *AXIS2_CALL
axutil_thread_pool_init(
    axutil_allocator_t *allocator)
{
    axutil_thread_pool_t *pool = NULL;

    pool = (axutil_thread_pool_t *)AXIS2_MALLOC(allocator, sizeof(axutil_thread_pool_t));

    if(!pool)
    {
        return NULL;
    }
    pool->allocator = allocator;

    return pool;
}

AXIS2_EXTERN void AXIS2_CALL
axutil_thread_pool_free(
    axutil_thread_pool_t *pool)
{
    if(!pool)
    {
        return;
    }
    if(!pool->allocator)
    {
        return;
    }
    AXIS2_FREE(pool->allocator, pool);
    return;
}

AXIS2_EXTERN axutil_thread_t *AXIS2_CALL
axutil_thread_pool_get_thread(
    axutil_thread_pool_t *pool,
    axutil_thread_start_t func,
    void *data)
{
    if(!pool)
    {
        return NULL;
    }
    if(!pool->allocator)
    {
        return NULL;
    }
    return axutil_thread_create(pool->allocator, NULL, func, data);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_thread_pool_join_thread(
    axutil_thread_pool_t *pool,
    axutil_thread_t *thd)
{
    if(!pool || !thd)
    {
        return AXIS2_FAILURE;
    }
    return axutil_thread_join(thd);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_thread_pool_exit_thread(
    axutil_thread_pool_t *pool,
    axutil_thread_t *thd)
{
    if(!pool || !thd)
    {
        return AXIS2_FAILURE;
    }
    return axutil_thread_exit(thd, pool->allocator);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_thread_pool_thread_detach(
    axutil_thread_pool_t *pool,
    axutil_thread_t *thd)
{
    if(!pool || !thd)
    {
        return AXIS2_FAILURE;
    }
    return axutil_thread_detach(thd);
}

AXIS2_EXTERN axutil_env_t *AXIS2_CALL
axutil_init_thread_env(
    const axutil_env_t *system_env)
{
    axutil_allocator_t * allocator = NULL;
    axutil_error_t *error = NULL;
    allocator = axutil_allocator_clone(system_env->allocator);
    error = axutil_error_create(allocator);
    return axutil_env_create_with_error_log_thread_pool(allocator, error, system_env->log,
        system_env-> thread_pool);
}

AXIS2_EXTERN void AXIS2_CALL
axutil_free_thread_env(
    struct axutil_env *thread_env)
{
	axutil_allocator_t * allocator;
    if(!thread_env)
    {
        return;
    }

    if(--(thread_env->ref) > 0)
    {
        return;
    }

    /* log, thread_pool and allocator are shared, so do not free them */
    thread_env->log = NULL;
    thread_env->thread_pool = NULL;
    if(thread_env->error)
    {
        AXIS2_ERROR_FREE(thread_env->error);
    }
	allocator = thread_env->allocator;
    AXIS2_FREE(allocator, thread_env);
	axutil_allocator_free(allocator);
}
