/* 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 "apr_thread_proc.h"
#include "apr_file_io.h"
#include "apr_thread_mutex.h"
#include "apr_thread_rwlock.h"
#include "apr_thread_cond.h"
#include "apr_errno.h"
#include "apr_general.h"
#include "apr_getopt.h"
#include "apr_atomic.h"
#include "testutil.h"

#if APR_HAS_THREADS

#define MAX_ITER 40000
#define MAX_COUNTER 100000
#define MAX_RETRY 5

static void *APR_THREAD_FUNC thread_rwlock_func(apr_thread_t *thd, void *data);
static void *APR_THREAD_FUNC thread_mutex_function(apr_thread_t *thd, void *data);
static void *APR_THREAD_FUNC thread_mutex_sleep_function(apr_thread_t *thd, void *data);
static void *APR_THREAD_FUNC thread_cond_producer(apr_thread_t *thd, void *data);
static void *APR_THREAD_FUNC thread_cond_consumer(apr_thread_t *thd, void *data);

static apr_thread_mutex_t *thread_mutex;
static apr_thread_rwlock_t *rwlock;
static int i = 0, x = 0;

static int buff[MAX_COUNTER];

struct {
    apr_thread_mutex_t *mutex;
    int                nput;
    int                nval;
} put;

struct {
    apr_thread_mutex_t *mutex;
    apr_thread_cond_t  *cond;
    int                nready;
} nready;

static apr_thread_mutex_t *timeout_mutex;
static apr_thread_cond_t *timeout_cond;

static void *APR_THREAD_FUNC thread_rwlock_func(apr_thread_t *thd, void *data)
{
    int exitLoop = 1;

    while (1)
    {
        apr_thread_rwlock_rdlock(rwlock);
        if (i == MAX_ITER)
            exitLoop = 0;
        apr_thread_rwlock_unlock(rwlock);

        if (!exitLoop)
            break;

        apr_thread_rwlock_wrlock(rwlock);
        if (i != MAX_ITER)
        {
            i++;
            x++;
        }
        apr_thread_rwlock_unlock(rwlock);
    }
    return NULL;
} 

static void *APR_THREAD_FUNC thread_mutex_function(apr_thread_t *thd, void *data)
{
    int exitLoop = 1;

    /* slight delay to allow things to settle */
    apr_sleep (1);
    
    while (1)
    {
        if (data) {
            apr_thread_mutex_timedlock(thread_mutex, *(apr_interval_time_t *)data);
        }
        else {
            apr_thread_mutex_lock(thread_mutex);
        }
        if (i == MAX_ITER)
            exitLoop = 0;
        else 
        {
            i++;
            x++;
        }
        apr_thread_mutex_unlock(thread_mutex);

        if (!exitLoop)
            break;
    }
    return NULL;
}

/* Sleepy-loop until f_ value matches val: */
#define wait_for_flag(f_, val) while (apr_atomic_read32(&(f_)) != val) apr_sleep(100000)

/* Helper function.  Passed (apr_uint32_t *) flag as data, sets flag
 * to one, locks the timeout_mutex, waits for *flag to be set to zero
 * and terminates.  The co-ordination could also be done via mutexes
 * but since we're timedlocking timeout_mutex it would look like a
 * deadlock to a mutex implementation which detects deadlocks. */
static void *APR_THREAD_FUNC thread_mutex_sleep_function(apr_thread_t *thd, void *data)
{
    apr_uint32_t *flag = data;
    apr_status_t rv;

    rv = apr_thread_mutex_lock(timeout_mutex);
    if (rv) {
        fprintf(stderr, "testlock: failed to lock timeout mutex, errno %d\n", rv);
        apr_thread_exit(thd, rv);
    }

    apr_atomic_set32(flag, 1);

    wait_for_flag(*flag, 0);

    rv = apr_thread_mutex_unlock(timeout_mutex);

    apr_thread_exit(thd, APR_SUCCESS);
} 

static void *APR_THREAD_FUNC thread_cond_producer(apr_thread_t *thd, void *data)
{
    for (;;) {
        apr_thread_mutex_lock(put.mutex);
        if (put.nput >= MAX_COUNTER) {
            apr_thread_mutex_unlock(put.mutex);
            return NULL;
        }
        buff[put.nput] = put.nval;
        put.nput++;
        put.nval++;
        apr_thread_mutex_unlock(put.mutex);

        apr_thread_mutex_lock(nready.mutex);
        if (nready.nready == 0)
            apr_thread_cond_signal(nready.cond);
        nready.nready++;
        apr_thread_mutex_unlock(nready.mutex);

        *((int *) data) += 1;
    }

    return NULL;
}

static void *APR_THREAD_FUNC thread_cond_consumer(apr_thread_t *thd, void *data)
{
    int i;

    for (i = 0; i < MAX_COUNTER; i++) {
        apr_thread_mutex_lock(nready.mutex);
        while (nready.nready == 0)
            apr_thread_cond_wait(nready.cond, nready.mutex);
        nready.nready--;
        apr_thread_mutex_unlock(nready.mutex);

        if (buff[i] != i)
            printf("buff[%d] = %d\n", i, buff[i]);
    }

    return NULL;
}

static void test_thread_mutex(abts_case *tc, void *data)
{
    apr_thread_t *t1, *t2, *t3, *t4;
    apr_status_t s1, s2, s3, s4;

    s1 = apr_thread_mutex_create(&thread_mutex, APR_THREAD_MUTEX_DEFAULT, p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, s1);
    ABTS_PTR_NOTNULL(tc, thread_mutex);

    i = 0;
    x = 0;

    s1 = apr_thread_create(&t1, NULL, thread_mutex_function, NULL, p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, s1);
    s2 = apr_thread_create(&t2, NULL, thread_mutex_function, NULL, p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, s2);
    s3 = apr_thread_create(&t3, NULL, thread_mutex_function, NULL, p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, s3);
    s4 = apr_thread_create(&t4, NULL, thread_mutex_function, NULL, p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, s4);

    apr_thread_join(&s1, t1);
    apr_thread_join(&s2, t2);
    apr_thread_join(&s3, t3);
    apr_thread_join(&s4, t4);

    ABTS_INT_EQUAL(tc, MAX_ITER, x);
}

static void test_thread_timedmutex(abts_case *tc, void *data)
{
    apr_thread_t *t1, *t2, *t3, *t4;
    apr_status_t s1, s2, s3, s4;
    apr_interval_time_t timeout;

    s1 = apr_thread_mutex_create(&thread_mutex, APR_THREAD_MUTEX_TIMED, p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, s1);
    ABTS_PTR_NOTNULL(tc, thread_mutex);

    i = 0;
    x = 0;

    timeout = apr_time_from_sec(5);

    s1 = apr_thread_create(&t1, NULL, thread_mutex_function, &timeout, p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, s1);
    s2 = apr_thread_create(&t2, NULL, thread_mutex_function, &timeout, p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, s2);
    s3 = apr_thread_create(&t3, NULL, thread_mutex_function, &timeout, p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, s3);
    s4 = apr_thread_create(&t4, NULL, thread_mutex_function, &timeout, p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, s4);

    apr_thread_join(&s1, t1);
    apr_thread_join(&s2, t2);
    apr_thread_join(&s3, t3);
    apr_thread_join(&s4, t4);

    ABTS_INT_EQUAL(tc, MAX_ITER, x);
}

static void test_thread_rwlock(abts_case *tc, void *data)
{
    apr_thread_t *t1, *t2, *t3, *t4;
    apr_status_t s1, s2, s3, s4;

    s1 = apr_thread_rwlock_create(&rwlock, p);
    if (s1 == APR_ENOTIMPL) {
        ABTS_NOT_IMPL(tc, "rwlocks not implemented");
        return;
    }
    APR_ASSERT_SUCCESS(tc, "rwlock_create", s1);
    ABTS_PTR_NOTNULL(tc, rwlock);

    i = 0;
    x = 0;

    s1 = apr_thread_create(&t1, NULL, thread_rwlock_func, NULL, p);
    APR_ASSERT_SUCCESS(tc, "create thread 1", s1);
    s2 = apr_thread_create(&t2, NULL, thread_rwlock_func, NULL, p);
    APR_ASSERT_SUCCESS(tc, "create thread 2", s2);
    s3 = apr_thread_create(&t3, NULL, thread_rwlock_func, NULL, p);
    APR_ASSERT_SUCCESS(tc, "create thread 3", s3);
    s4 = apr_thread_create(&t4, NULL, thread_rwlock_func, NULL, p);
    APR_ASSERT_SUCCESS(tc, "create thread 4", s4);

    apr_thread_join(&s1, t1);
    apr_thread_join(&s2, t2);
    apr_thread_join(&s3, t3);
    apr_thread_join(&s4, t4);

    ABTS_INT_EQUAL(tc, MAX_ITER, x);

    apr_thread_rwlock_destroy(rwlock);
}

static void test_cond(abts_case *tc, void *data)
{
    apr_thread_t *p1, *p2, *p3, *p4, *c1;
    apr_status_t s0, s1, s2, s3, s4;
    int count1, count2, count3, count4;
    int sum;
    
    APR_ASSERT_SUCCESS(tc, "create put mutex",
                       apr_thread_mutex_create(&put.mutex, 
                                               APR_THREAD_MUTEX_DEFAULT, p));
    ABTS_PTR_NOTNULL(tc, put.mutex);

    APR_ASSERT_SUCCESS(tc, "create nready mutex",
                       apr_thread_mutex_create(&nready.mutex, 
                                               APR_THREAD_MUTEX_DEFAULT, p));
    ABTS_PTR_NOTNULL(tc, nready.mutex);

    APR_ASSERT_SUCCESS(tc, "create condvar",
                       apr_thread_cond_create(&nready.cond, p));
    ABTS_PTR_NOTNULL(tc, nready.cond);

    count1 = count2 = count3 = count4 = 0;
    put.nput = put.nval = 0;
    nready.nready = 0;
    i = 0;
    x = 0;

    s0 = apr_thread_create(&p1, NULL, thread_cond_producer, &count1, p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, s0);
    s1 = apr_thread_create(&p2, NULL, thread_cond_producer, &count2, p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, s1);
    s2 = apr_thread_create(&p3, NULL, thread_cond_producer, &count3, p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, s2);
    s3 = apr_thread_create(&p4, NULL, thread_cond_producer, &count4, p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, s3);
    s4 = apr_thread_create(&c1, NULL, thread_cond_consumer, NULL, p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, s4);

    apr_thread_join(&s0, p1);
    apr_thread_join(&s1, p2);
    apr_thread_join(&s2, p3);
    apr_thread_join(&s3, p4);
    apr_thread_join(&s4, c1);

    APR_ASSERT_SUCCESS(tc, "destroy condvar", 
                       apr_thread_cond_destroy(nready.cond));

    sum = count1 + count2 + count3 + count4;
    /*
    printf("count1 = %d count2 = %d count3 = %d count4 = %d\n",
            count1, count2, count3, count4);
    */
    ABTS_INT_EQUAL(tc, MAX_COUNTER, sum);
}

static void test_timeoutcond(abts_case *tc, void *data)
{
    apr_status_t s;
    apr_interval_time_t timeout;
    apr_time_t begin, end;
    int i;

    s = apr_thread_mutex_create(&timeout_mutex, APR_THREAD_MUTEX_DEFAULT, p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, s);
    ABTS_PTR_NOTNULL(tc, timeout_mutex);

    s = apr_thread_cond_create(&timeout_cond, p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, s);
    ABTS_PTR_NOTNULL(tc, timeout_cond);

    timeout = apr_time_from_sec(5);

    for (i = 0; i < MAX_RETRY; i++) {
        apr_thread_mutex_lock(timeout_mutex);

        begin = apr_time_now();
        s = apr_thread_cond_timedwait(timeout_cond, timeout_mutex, timeout);
        end = apr_time_now();
        apr_thread_mutex_unlock(timeout_mutex);
        
        if (s != APR_SUCCESS && !APR_STATUS_IS_TIMEUP(s)) {
            continue;
        }
        ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(s));
        ABTS_ASSERT(tc, "Timer returned too late", end - begin - timeout < 500000);
        break;
    }
    ABTS_ASSERT(tc, "Too many retries", i < MAX_RETRY);
    APR_ASSERT_SUCCESS(tc, "Unable to destroy the conditional",
                       apr_thread_cond_destroy(timeout_cond));
}

/* Test whether _timedlock times out appropriately.  Since
 * double-locking a non-recursive mutex has undefined behaviour, and
 * double-locking a recursive mutex succeeds immediately, a thread is
 * spawned to hold the lock while this thread tests whether _timedlock
 * times out. */
static void test_timeoutmutex(abts_case *tc, void *data)
{
    apr_status_t s;
    apr_interval_time_t timeout;
    apr_time_t begin, end;
    apr_thread_t *th;
    apr_uint32_t flag = 0;
    int i;

    s = apr_thread_mutex_create(&timeout_mutex,
                                APR_THREAD_MUTEX_TIMED |
                                APR_THREAD_MUTEX_UNNESTED, p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, s);
    ABTS_PTR_NOTNULL(tc, timeout_mutex);

    s = apr_thread_create(&th, NULL, thread_mutex_sleep_function, &flag, p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, s);

    wait_for_flag(flag, 1); /* the thread will set flag to 1 once the
                             * timeout_mutex is locked. */
    
    timeout = apr_time_from_sec(5);

    for (i = 0; i < MAX_RETRY; i++) {
        begin = apr_time_now();
        s = apr_thread_mutex_timedlock(timeout_mutex, timeout);
        end = apr_time_now();

        if (s != APR_SUCCESS && !APR_STATUS_IS_TIMEUP(s)) {
            continue;
        }
        ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(s));
        ABTS_ASSERT(tc, "Timer returned too late", end - begin - timeout < 1000000);
        break;
    }

    apr_atomic_set32(&flag, 0); /* tell the thread to exit.  */

    APR_ASSERT_SUCCESS(tc, "join spawned thread", apr_thread_join(&s, th));
    APR_ASSERT_SUCCESS(tc, "spawned thread terminated", s);

    ABTS_ASSERT(tc, "Too many retries", i < MAX_RETRY);
    APR_ASSERT_SUCCESS(tc, "Unable to destroy the timeout mutex",
                       apr_thread_mutex_destroy(timeout_mutex));
}

static void test_thread_nestedmutex(abts_case *tc, void *data)
{
    apr_thread_mutex_t *m;
    apr_status_t rv;

    rv = apr_thread_mutex_create(&m, APR_THREAD_MUTEX_NESTED, p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
    ABTS_PTR_NOTNULL(tc, m);

    rv = apr_thread_mutex_lock(m);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);

    rv = apr_thread_mutex_trylock(m);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
    if (rv == APR_SUCCESS)
    {
        rv = apr_thread_mutex_unlock(m);
        ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
    }

    rv = apr_thread_mutex_unlock(m);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
}

static void test_thread_unnestedmutex(abts_case *tc, void *data)
{
    apr_thread_mutex_t *m;
    apr_status_t rv;

    rv = apr_thread_mutex_create(&m, APR_THREAD_MUTEX_UNNESTED, p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
    ABTS_PTR_NOTNULL(tc, m);

    rv = apr_thread_mutex_lock(m);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);

    rv = apr_thread_mutex_trylock(m);
    ABTS_INT_EQUAL(tc, APR_EBUSY, rv);
    if (rv == APR_SUCCESS)
    {
        rv = apr_thread_mutex_unlock(m);
        ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
    }

    rv = apr_thread_mutex_unlock(m);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
}

#ifdef WIN32
static void *APR_THREAD_FUNC
thread_win32_abandoned_mutex_function(apr_thread_t *thd, void *data)
{
    apr_thread_mutex_t *mutex = data;
    apr_status_t rv;

    rv = apr_thread_mutex_lock(mutex);

    /* exit from thread without unlocking mutex. */
    apr_thread_exit(thd, rv);

    return NULL;
}

static void test_win32_abandoned_mutex(abts_case *tc, void *data)
{
    apr_status_t rv;
    apr_thread_t *thread;
    apr_thread_mutex_t *mutex;

    /* Create timed mutex: APR will create Win32 mutex object in this case. */
    rv = apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_TIMED, p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);

    rv = apr_thread_create(&thread, NULL, thread_win32_abandoned_mutex_function,
                           mutex, p);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);

    apr_thread_join(&rv, thread);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);

    rv = apr_thread_mutex_trylock(mutex);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);

    rv = apr_thread_mutex_unlock (mutex);
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
}

#endif

#endif /* !APR_HAS_THREADS */

#if !APR_HAS_THREADS
static void threads_not_impl(abts_case *tc, void *data)
{
    ABTS_NOT_IMPL(tc, "Threads not implemented on this platform");
}
#endif


abts_suite *testlock(abts_suite *suite)
{
    suite = ADD_SUITE(suite)

#if !APR_HAS_THREADS
    abts_run_test(suite, threads_not_impl, NULL);
#else
    abts_run_test(suite, test_thread_mutex, NULL);
    abts_run_test(suite, test_thread_timedmutex, NULL);
    abts_run_test(suite, test_thread_nestedmutex, NULL);
    abts_run_test(suite, test_thread_unnestedmutex, NULL);
    abts_run_test(suite, test_thread_rwlock, NULL);
    abts_run_test(suite, test_cond, NULL);
    abts_run_test(suite, test_timeoutcond, NULL);
    abts_run_test(suite, test_timeoutmutex, NULL);
#ifdef WIN32
    abts_run_test(suite, test_win32_abandoned_mutex, NULL);
#endif
#endif

    return suite;
}

