1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_cppu.hxx"
26 #include <stdio.h>
27 #include <string.h>
28
29 #include <list>
30
31 #include <osl/mutex.hxx>
32 #include <osl/thread.h>
33 #include <osl/diagnose.h>
34
35 #include <rtl/process.h>
36 #include <rtl/byteseq.hxx>
37
38 #include <uno/threadpool.h>
39
40 #include "current.hxx"
41
42
43 using namespace ::std;
44 using namespace ::osl;
45 using namespace ::rtl;
46 using namespace ::cppu;
47
48
createLocalId(sal_Sequence ** ppThreadId)49 static inline void createLocalId( sal_Sequence **ppThreadId )
50 {
51 rtl_byte_sequence_constructNoDefault( ppThreadId , sizeof(oslThreadIdentifier) + 16 );
52
53 oslThreadIdentifier hIdent = osl_getThreadIdentifier(0);
54 memcpy((*ppThreadId)->elements, &hIdent, sizeof(oslThreadIdentifier));
55
56 rtl_getGlobalProcessId( (sal_uInt8 * ) &( (*ppThreadId)->elements[sizeof(oslThreadIdentifier)]) );
57 }
58
59
60 extern "C" void SAL_CALL
uno_getIdOfCurrentThread(sal_Sequence ** ppThreadId)61 uno_getIdOfCurrentThread( sal_Sequence **ppThreadId )
62 SAL_THROW_EXTERN_C()
63 {
64 IdContainer * p = getIdContainer();
65 if( ! p->bInit )
66 {
67 // first time, that the thread enters the bridge
68 createLocalId( ppThreadId );
69
70 // TODO
71 // note : this is a leak !
72 p->pLocalThreadId = *ppThreadId;
73 p->pCurrentId = *ppThreadId;
74 p->nRefCountOfCurrentId = 1;
75 rtl_byte_sequence_acquire( p->pLocalThreadId );
76 rtl_byte_sequence_acquire( p->pCurrentId );
77 p->bInit = sal_True;
78 }
79 else
80 {
81 p->nRefCountOfCurrentId ++;
82 if( *ppThreadId )
83 {
84 rtl_byte_sequence_release( *ppThreadId );
85 }
86 *ppThreadId = p->pCurrentId;
87 rtl_byte_sequence_acquire( *ppThreadId );
88 }
89 }
90
91
uno_releaseIdFromCurrentThread()92 extern "C" void SAL_CALL uno_releaseIdFromCurrentThread()
93 SAL_THROW_EXTERN_C()
94 {
95 IdContainer *p = getIdContainer();
96 OSL_ASSERT( p );
97 OSL_ASSERT( p->nRefCountOfCurrentId );
98
99 p->nRefCountOfCurrentId --;
100 if( ! p->nRefCountOfCurrentId && (p->pLocalThreadId != p->pCurrentId) )
101 {
102 rtl_byte_sequence_assign( &(p->pCurrentId) , p->pLocalThreadId );
103 }
104 }
105
uno_bindIdToCurrentThread(sal_Sequence * pThreadId)106 extern "C" sal_Bool SAL_CALL uno_bindIdToCurrentThread( sal_Sequence *pThreadId )
107 SAL_THROW_EXTERN_C()
108 {
109 IdContainer *p = getIdContainer();
110 if( ! p->bInit )
111 {
112 p->pLocalThreadId = 0;
113 createLocalId( &(p->pLocalThreadId) );
114 p->nRefCountOfCurrentId = 1;
115 p->pCurrentId = pThreadId;
116 rtl_byte_sequence_acquire( p->pCurrentId );
117 p->bInit = sal_True;
118 }
119 else
120 {
121 OSL_ASSERT( 0 == p->nRefCountOfCurrentId );
122 if( 0 == p->nRefCountOfCurrentId )
123 {
124 rtl_byte_sequence_assign(&( p->pCurrentId ), pThreadId );
125 p->nRefCountOfCurrentId ++;
126 }
127 else
128 {
129 return sal_False;
130 }
131
132 }
133 return sal_True;
134 }
135