1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_cppu.hxx"
30 #include <stdio.h>
31 
32 #include <list>
33 
34 #include <osl/mutex.hxx>
35 #include <osl/thread.h>
36 #include <osl/diagnose.h>
37 
38 #include <rtl/process.h>
39 #include <rtl/byteseq.hxx>
40 
41 #include <uno/threadpool.h>
42 
43 #include "current.hxx"
44 
45 
46 using namespace ::std;
47 using namespace ::osl;
48 using namespace ::rtl;
49 using namespace ::cppu;
50 
51 
52 static inline void createLocalId( sal_Sequence **ppThreadId )
53 {
54 	rtl_byte_sequence_constructNoDefault( ppThreadId , 4 + 16 );
55 	*((sal_Int32*) ((*ppThreadId)->elements)) = osl_getThreadIdentifier(0);
56 
57 	rtl_getGlobalProcessId( (sal_uInt8 * ) &( (*ppThreadId)->elements[4]) );
58 }
59 
60 
61 extern "C" void SAL_CALL
62 uno_getIdOfCurrentThread( sal_Sequence **ppThreadId )
63 	SAL_THROW_EXTERN_C()
64 {
65 	IdContainer * p = getIdContainer();
66 	if( ! p->bInit )
67 	{
68 		// first time, that the thread enters the bridge
69 		createLocalId( ppThreadId );
70 
71 		// TODO
72 		// note : this is a leak !
73 		p->pLocalThreadId = *ppThreadId;
74 		p->pCurrentId = *ppThreadId;
75 		p->nRefCountOfCurrentId = 1;
76 		rtl_byte_sequence_acquire( p->pLocalThreadId );
77 		rtl_byte_sequence_acquire( p->pCurrentId );
78 		p->bInit = sal_True;
79 	}
80 	else
81 	{
82 		p->nRefCountOfCurrentId ++;
83 		if( *ppThreadId )
84 		{
85 			rtl_byte_sequence_release( *ppThreadId );
86 		}
87 		*ppThreadId = p->pCurrentId;
88 		rtl_byte_sequence_acquire( *ppThreadId );
89 	}
90 }
91 
92 
93 extern "C"   void SAL_CALL uno_releaseIdFromCurrentThread()
94 	SAL_THROW_EXTERN_C()
95 {
96 	IdContainer *p = getIdContainer();
97 	OSL_ASSERT( p );
98 	OSL_ASSERT( p->nRefCountOfCurrentId );
99 
100 	p->nRefCountOfCurrentId --;
101 	if( ! p->nRefCountOfCurrentId && (p->pLocalThreadId != p->pCurrentId) )
102 	{
103 		rtl_byte_sequence_assign( &(p->pCurrentId) , p->pLocalThreadId );
104 	}
105 }
106 
107 extern "C"  sal_Bool SAL_CALL uno_bindIdToCurrentThread( sal_Sequence *pThreadId )
108 	SAL_THROW_EXTERN_C()
109 {
110 	IdContainer *p = getIdContainer();
111 	if( ! p->bInit )
112 	{
113 		p->pLocalThreadId = 0;
114 		createLocalId( &(p->pLocalThreadId) );
115 		p->nRefCountOfCurrentId = 1;
116 		p->pCurrentId = pThreadId;
117 		rtl_byte_sequence_acquire( p->pCurrentId );
118 		p->bInit = sal_True;
119 	}
120 	else
121 	{
122 		OSL_ASSERT( 0 == p->nRefCountOfCurrentId );
123 		if( 0 == p->nRefCountOfCurrentId )
124 		{
125 			rtl_byte_sequence_assign(&( p->pCurrentId ), pThreadId );
126 			p->nRefCountOfCurrentId ++;
127 		}
128 		else
129 		{
130 			return sal_False;
131 		}
132 
133 	}
134 	return sal_True;
135 }
136