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



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_cppu.hxx"
#include <stdio.h>
#include <osl/diagnose.h>
#include <uno/threadpool.h>

#include <rtl/instance.hxx>

#include "thread.hxx"
#include "jobqueue.hxx"
#include "threadpool.hxx"


using namespace osl;
extern "C" {

void SAL_CALL cppu_requestThreadWorker( void *pVoid )
{
	::cppu_threadpool::ORequestThread *pThread = ( ::cppu_threadpool::ORequestThread * ) pVoid;

	pThread->run();
	pThread->onTerminated();
}

}

namespace cppu_threadpool {

// ----------------------------------------------------------------------------------
	ThreadAdmin::~ThreadAdmin()
	{
#if OSL_DEBUG_LEVEL > 1
		if( m_lst.size() )
		{
			fprintf( stderr, "%lu Threads left\n" , static_cast<unsigned long>(m_lst.size()) );
		}
#endif
	}

	void ThreadAdmin::add( ORequestThread *p )
	{
		MutexGuard aGuard( m_mutex );
		m_lst.push_back( p );
	}

	void ThreadAdmin::remove( ORequestThread * p )
	{
		MutexGuard aGuard( m_mutex );
		::std::list< ORequestThread * >::iterator ii = ::std::find( m_lst.begin(), m_lst.end(), p );
		OSL_ASSERT( ii != m_lst.end() );
		m_lst.erase( ii );
	}

	void ThreadAdmin::join()
	{
		ORequestThread *pCurrent;
		do
		{
			pCurrent = 0;
			{
				MutexGuard aGuard( m_mutex );
				if( ! m_lst.empty() )
				{
					pCurrent = m_lst.front();
					pCurrent->setDeleteSelf( sal_False );
				}
			}
			if ( pCurrent )
			{
				pCurrent->join();
				delete pCurrent;
			}
		} while( pCurrent );
	}

	struct theThreadAdmin : public rtl::StaticWithInit< ThreadAdminHolder, theThreadAdmin >
	{
		ThreadAdminHolder operator () () {
			ThreadAdminHolder aRet(new ThreadAdmin());
			return aRet;
		}
	};

	ThreadAdminHolder& ThreadAdmin::getInstance()
	{
		return theThreadAdmin::get();
	}

// ----------------------------------------------------------------------------------
	ORequestThread::ORequestThread( JobQueue *pQueue,
									const ByteSequence &aThreadId,
									sal_Bool bAsynchron )
		: m_thread( 0 )
		, m_aThreadAdmin( ThreadAdmin::getInstance() )
		, m_pQueue( pQueue )
		, m_aThreadId( aThreadId )
		, m_bAsynchron( bAsynchron )
		, m_bDeleteSelf( sal_True )
	{
		m_aThreadAdmin->add( this );
	}


	ORequestThread::~ORequestThread()
	{
		if (m_thread != 0)
		{
			osl_destroyThread(m_thread);
		}
	}


	void ORequestThread::setTask( JobQueue *pQueue,
								  const ByteSequence &aThreadId,
								  sal_Bool bAsynchron )
	{
		m_pQueue = pQueue;
		m_aThreadId = aThreadId;
		m_bAsynchron = bAsynchron;
	}

	sal_Bool ORequestThread::create()
	{
		OSL_ASSERT(m_thread == 0);	// only one running thread per instance

		m_thread = osl_createSuspendedThread( cppu_requestThreadWorker, (void*)this);
		if ( m_thread )
		{
			osl_resumeThread( m_thread );
		}

		return m_thread != 0;
	}

	void ORequestThread::join()
	{
		osl_joinWithThread( m_thread );
	}

	void ORequestThread::onTerminated()
	{
		m_aThreadAdmin->remove( this );
		if( m_bDeleteSelf )
		{
			delete this;
		}
	}

	void ORequestThread::run()
	{
		ThreadPoolHolder theThreadPool = cppu_threadpool::ThreadPool::getInstance();

		while ( m_pQueue )
		{
			if( ! m_bAsynchron )
			{
                if ( !uno_bindIdToCurrentThread( m_aThreadId.getHandle() ) )
                {
                    OSL_ASSERT( false );
                }
			}

			while( ! m_pQueue->isEmpty() )
			{
				// Note : Oneways should not get a disposable disposeid,
				//        It does not make sense to dispose a call in this state.
				//        That's way we put it an disposeid, that can't be used otherwise.
				m_pQueue->enter(
                    sal::static_int_cast< sal_Int64 >(
                        reinterpret_cast< sal_IntPtr >(this)),
                    sal_True );

				if( m_pQueue->isEmpty() )
				{
					theThreadPool->revokeQueue( m_aThreadId , m_bAsynchron );
					// Note : revokeQueue might have failed because m_pQueue.isEmpty()
					//        may be false (race).
				}
			}

			delete m_pQueue;
			m_pQueue = 0;

			if( ! m_bAsynchron )
			{
				uno_releaseIdFromCurrentThread();
			}

			theThreadPool->waitInPool( this );
		}
	}
}
