/*
 * 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.
 */

#ifndef _LOG4CXX_HELPERS_THREAD_H
#define _LOG4CXX_HELPERS_THREAD_H

#include <log4cxx/log4cxx.h>
#include <log4cxx/helpers/pool.h>

#if !defined(LOG4CXX_THREAD_FUNC)
#if defined(_WIN32)
  #if defined(__MINGW32__)
    #define LOG4CXX_THREAD_FUNC
  #else
    #define LOG4CXX_THREAD_FUNC __stdcall
  #endif
#else
  #define LOG4CXX_THREAD_FUNC
#endif
#endif

extern "C" {
    typedef struct apr_thread_t apr_thread_t;
    typedef struct apr_thread_cond_t apr_thread_cond_t;
    typedef struct apr_thread_mutex_t apr_thread_mutex_t;
}


namespace log4cxx
{
        namespace helpers
        {
                class Pool;
                class ThreadLocal;

                typedef void* (LOG4CXX_THREAD_FUNC *Runnable)(apr_thread_t* thread, void* data);
                namespace ThreadLaunch {
		    extern "C" void* LOG4CXX_THREAD_FUNC launcher(apr_thread_t* thread, void* data);
                }

                /**
                 *  This class implements an approximation of java.util.Thread.
                 */
                class LOG4CXX_EXPORT Thread
                {
                public:
                        /**
                         *  Create new instance.
                         */
                        Thread();
                        /**
                         *  Destructor.
                         */
                        ~Thread();

                        /**
                         *  Runs the specified method on a newly created thread.
                         */
                        void run(Runnable start, void* data);
                        void join();

                        inline bool isActive() { return thread != 0; }

                        /**
                         * Causes the currently executing thread to sleep for the
                         * specified number of milliseconds.
                         * @param millis milliseconds.
                         * @throws Interrupted Exception if the thread is interrupted.
                         */
                        static void sleep(int millis);
                        /**
                         *  Sets interrupted status for current thread to true.
                         */
                        static void currentThreadInterrupt();
                        /**
                         *  Sets interrupted status to true.
                         */
                        void interrupt();
                        /**
                         *  Tests if the current thread has been interrupted and
                         *  sets the interrupted status to false.
                         */
                        static bool interrupted();

                        bool isAlive();
                        bool isCurrentThread() const;
                        void ending();


                private:
                        Pool p;
                        apr_thread_t* thread;
                        volatile unsigned int alive;
                        volatile unsigned int interruptedStatus;
                        apr_thread_mutex_t* interruptedMutex;
                        apr_thread_cond_t* interruptedCondition;
                        Thread(const Thread&);
                        Thread& operator=(const Thread&);
                        friend void* LOG4CXX_THREAD_FUNC ThreadLaunch::launcher(apr_thread_t* thread, void* data);
                };
        } // namespace helpers
} // namespace log4cxx

#endif //_LOG4CXX_HELPERS_THREAD_H
