
/*
 * 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_os400.h"

AXIS2_EXTERN axutil_threadattr_t *AXIS2_CALL
axutil_threadattr_create(
    axutil_allocator_t * allocator)
{
    int stat = 0;
    axutil_threadattr_t *new = NULL;

    new = AXIS2_MALLOC(allocator, sizeof(axutil_threadattr_t));
    if (!new)
        return NULL;

    stat = pthread_attr_init(&(new->attr));
    if (stat != 0)
    {
        AXIS2_FREE(allocator, new);
        return NULL;
    }
    return new;
}

/* Destroy the threadattr object */
AXIS2_EXTERN axis2_status_t AXIS2_CALL
threadattr_cleanup(
    void *data)
{
    axutil_threadattr_t *attr = data;
    int rv;

    rv = pthread_attr_destroy(&(attr->attr));

    if (0 != rv)
    {
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}

#define DETACH_ARG(v) ((v) ? PTHREAD_CREATE_DETACHED : PTHREAD_CREATE_JOINABLE)

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_threadattr_detach_set(
    axutil_threadattr_t * attr,
    axis2_bool_t detached)
{
    if (0 == pthread_attr_setdetachstate(&(attr->attr), DETACH_ARG(detached)))
    {
        return AXIS2_SUCCESS;
    }
    return AXIS2_FAILURE;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_threadattr_detach_get(
    axutil_threadattr_t * attr)
{
    int state = 0;
    pthread_attr_getdetachstate(&(attr->attr), &state);
    if (state == 1)
    {
        return AXIS2_TRUE;
    }
    return AXIS2_FALSE;
}

static void *
dummy_worker(
    void *opaque)
{
    axutil_thread_t *thread = (axutil_thread_t *) opaque;
    return thread->func(thread, thread->data);
}

AXIS2_EXTERN axutil_thread_t *AXIS2_CALL
axutil_thread_create(
    axutil_allocator_t * allocator,
    axutil_threadattr_t * attr,
    axutil_thread_start_t func,
    void *data)
{
    axis2_status_t stat;
    pthread_attr_t *temp = NULL;
    axutil_thread_t *new = NULL;

    new = (axutil_thread_t *) AXIS2_MALLOC(allocator, sizeof(axutil_thread_t));

    if (!new)
        return NULL;

    new->td = (pthread_t *) AXIS2_MALLOC(allocator, sizeof(pthread_t));
    if (!new->td)
    {
        AXIS2_FREE(allocator, new);
        return NULL;
    }

    new->data = data;
    new->func = func;
    new->try_exit = AXIS2_FALSE;

    if (attr)
        temp = &(attr->attr);

    if ((stat = pthread_create(new->td, temp, dummy_worker, new)) == 0)
    {
        return new;
    }

    AXIS2_FREE(allocator, new->td);
    AXIS2_FREE(allocator, new);
    return NULL;
}

AXIS2_EXTERN axis2_os_thread_t AXIS2_CALL
axis2_os_thread_current(
    void)
{
    return pthread_self();
}

AXIS2_EXTERN int AXIS2_CALL
axis2_os_thread_equal(
    axis2_os_thread_t tid1,
    axis2_os_thread_t tid2)
{
    return pthread_equal(tid1, tid2);
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_thread_exit(
    axutil_thread_t * thd,
    axutil_allocator_t * allocator)
{
    axis2_bool_t same_thread = AXIS2_TRUE;
    if (thd)
    {
        while (!thd->try_exit)
        {    
            sleep(1);
        }    
        
        if (thd->td)
        {
            same_thread = pthread_equal(pthread_self(), *thd->td);
            if(!same_thread)
            {
                pthread_kill(*(thd->td), 0);
                axutil_thread_join(thd);
            }
            AXIS2_FREE(allocator, thd->td);
        }
        AXIS2_FREE(allocator, thd);
    }
    if(same_thread)
    {
        pthread_exit(NULL);
    }
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_thread_join(
    axutil_thread_t * thd)
{
    void *thread_stat;
    if (0 == pthread_join(*(thd->td), (void *) (&thread_stat)))
    {
        return AXIS2_SUCCESS;
    }
    return AXIS2_FAILURE;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_thread_detach(
    axutil_thread_t * thd)
{
    if (0 == pthread_detach(*(thd->td)))
    {
        thd->try_exit = AXIS2_TRUE;
        return AXIS2_SUCCESS;
    }
    return AXIS2_FAILURE;
}

void
axutil_thread_yield(
    void)
{
    return;
}

/**
 * function is used to allocate a new key. This key now becomes valid for all threads in our process. 
 * When a key is created, the value it points to defaults to NULL. Later on each thread may change 
 * its copy of the value as it wishes.
 */
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_thread_key_create(
    axutil_threadkey_t * axis2_key)
{
    int rc = -1;
    pthread_key_t key = axis2_key->key;
    rc = pthread_key_create(&key, NULL);
    if (0 == rc)
        return AXIS2_SUCCESS;
    else
        return AXIS2_FAILURE;
}

/**
 * This function is used to get the value of a given key
 * @return void*. A key's value is simply a void pointer (void*)
 */
AXIS2_EXTERN void *AXIS2_CALL
axutil_thread_getspecific(
    axutil_threadkey_t * axis2_key)
{
    void *value = NULL;
    pthread_key_t key = axis2_key->key;
    value = pthread_getspecific(key);
    return value;
}

/**
 * This function is used to get the value of a given key
 * @param keys value. A key's value is simply a void pointer (void*), so we can 
 *        store in it anything that we want
 */
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_thread_setspecific(
    axutil_threadkey_t * axis2_key,
    void *value)
{
    int rc = -1;
    pthread_key_t key = axis2_key->key;
    rc = pthread_setspecific(key, value);
    if (0 == rc)
        return AXIS2_SUCCESS;
    else
        return AXIS2_FAILURE;
}

AXIS2_EXTERN void AXIS2_CALL
axutil_thread_key_free(
    axutil_threadkey_t * axis2_key)
{
    pthread_key_t key = axis2_key->key;
    pthread_key_delete(key);
}

AXIS2_EXTERN axis2_os_thread_t *AXIS2_CALL
axis2_os_thread_get(
    axutil_thread_t * thd)
{
    if (!thd)
    {
        return NULL;
    }
    return thd->td;
}

AXIS2_EXTERN axutil_thread_once_t *AXIS2_CALL
axutil_thread_once_init(
    axutil_allocator_t * allocator)
{
    static const pthread_once_t once_init = PTHREAD_ONCE_INIT;
    axutil_thread_once_t *control = AXIS2_MALLOC(allocator, sizeof(axutil_thread_once_t));
    if (!control)
    {
        return NULL;
    }
    (control)->once = once_init;
    return control;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_thread_once(
    axutil_thread_once_t * control,
    void
    (*func)(
        void))
{
    return pthread_once(&(control->once), func);
}

/*************************Thread locking functions*****************************/
AXIS2_EXTERN axutil_thread_mutex_t *AXIS2_CALL
axutil_thread_mutex_create(
    axutil_allocator_t * allocator,
    unsigned int flags)
{
    axutil_thread_mutex_t *new_mutex = NULL;

    new_mutex = AXIS2_MALLOC(allocator, sizeof(axutil_thread_mutex_t));
    new_mutex->allocator = allocator;

    if (pthread_mutex_init(&(new_mutex->mutex), NULL) != 0)
    {
        AXIS2_FREE(allocator, new_mutex);
        return NULL;
    }
    return new_mutex;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_thread_mutex_lock(
    axutil_thread_mutex_t * mutex)
{
    return pthread_mutex_lock(&(mutex->mutex));
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_thread_mutex_unlock(
    axutil_thread_mutex_t * mutex)
{
    if (pthread_mutex_unlock(&(mutex->mutex)) != 0)
    {
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_thread_mutex_destroy(
    axutil_thread_mutex_t * mutex)
{
    if (0 != pthread_mutex_destroy(&(mutex->mutex)))
    {
        return AXIS2_FAILURE;
    }
    AXIS2_FREE(mutex->allocator, mutex);
    return AXIS2_SUCCESS;
}
