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

#include <osl/mutex.hxx>
#include <osl/thread.h>
#include <osl/diagnose.h>

#include <rtl/process.h>
#include <rtl/byteseq.hxx>

#include <uno/threadpool.h>

#include "current.hxx"


using namespace ::std;
using namespace ::osl;
using namespace ::rtl;
using namespace ::cppu;


static inline void createLocalId( sal_Sequence **ppThreadId )
{
	rtl_byte_sequence_constructNoDefault( ppThreadId , 4 + 16 );
	*((sal_Int32*) ((*ppThreadId)->elements)) = osl_getThreadIdentifier(0);

	rtl_getGlobalProcessId( (sal_uInt8 * ) &( (*ppThreadId)->elements[4]) );
}


extern "C" void SAL_CALL
uno_getIdOfCurrentThread( sal_Sequence **ppThreadId )
	SAL_THROW_EXTERN_C()
{
	IdContainer * p = getIdContainer();
	if( ! p->bInit )
	{
		// first time, that the thread enters the bridge
		createLocalId( ppThreadId );

		// TODO
		// note : this is a leak !
		p->pLocalThreadId = *ppThreadId;
		p->pCurrentId = *ppThreadId;
		p->nRefCountOfCurrentId = 1;
		rtl_byte_sequence_acquire( p->pLocalThreadId );
		rtl_byte_sequence_acquire( p->pCurrentId );
		p->bInit = sal_True;
	}
	else
	{
		p->nRefCountOfCurrentId ++;
		if( *ppThreadId )
		{
			rtl_byte_sequence_release( *ppThreadId );
		}
		*ppThreadId = p->pCurrentId;
		rtl_byte_sequence_acquire( *ppThreadId );
	}
}


extern "C"   void SAL_CALL uno_releaseIdFromCurrentThread()
	SAL_THROW_EXTERN_C()
{
	IdContainer *p = getIdContainer();
	OSL_ASSERT( p );
	OSL_ASSERT( p->nRefCountOfCurrentId );

	p->nRefCountOfCurrentId --;
	if( ! p->nRefCountOfCurrentId && (p->pLocalThreadId != p->pCurrentId) )
	{
		rtl_byte_sequence_assign( &(p->pCurrentId) , p->pLocalThreadId );
	}
}

extern "C"  sal_Bool SAL_CALL uno_bindIdToCurrentThread( sal_Sequence *pThreadId )
	SAL_THROW_EXTERN_C()
{
	IdContainer *p = getIdContainer();
	if( ! p->bInit )
	{
		p->pLocalThreadId = 0;
		createLocalId( &(p->pLocalThreadId) );
		p->nRefCountOfCurrentId = 1;
		p->pCurrentId = pThreadId;
		rtl_byte_sequence_acquire( p->pCurrentId );
		p->bInit = sal_True;
	}
	else
	{
		OSL_ASSERT( 0 == p->nRefCountOfCurrentId );
		if( 0 == p->nRefCountOfCurrentId )
		{
			rtl_byte_sequence_assign(&( p->pCurrentId ), pThreadId );
			p->nRefCountOfCurrentId ++;
		}
		else
		{
			return sal_False;
		}

	}
	return sal_True;
}
