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 #include "jvmaccess/virtualmachine.hxx"
25 
26 #include "osl/diagnose.h"
27 
28 using jvmaccess::VirtualMachine;
29 
CreationException()30 VirtualMachine::AttachGuard::CreationException::CreationException()
31 {}
32 
CreationException(CreationException const &)33 VirtualMachine::AttachGuard::CreationException::CreationException(
34     CreationException const &)
35 {}
36 
~CreationException()37 VirtualMachine::AttachGuard::CreationException::~CreationException()
38 {}
39 
40 VirtualMachine::AttachGuard::CreationException &
operator =(CreationException const &)41 VirtualMachine::AttachGuard::CreationException::operator =(
42     CreationException const &)
43 {
44     return *this;
45 }
46 
AttachGuard(rtl::Reference<VirtualMachine> const & rMachine)47 VirtualMachine::AttachGuard::AttachGuard(
48     rtl::Reference< VirtualMachine > const & rMachine):
49     m_xMachine(rMachine)
50 {
51     OSL_ENSURE(m_xMachine.is(), "bad parameter");
52     m_pEnvironment = m_xMachine->attachThread(&m_bDetach);
53     if (m_pEnvironment == 0)
54         throw CreationException();
55 }
56 
~AttachGuard()57 VirtualMachine::AttachGuard::~AttachGuard()
58 {
59     if (m_bDetach)
60         m_xMachine->detachThread();
61 }
62 
VirtualMachine(JavaVM * pVm,int nVersion,bool bDestroy,JNIEnv * pMainThreadEnv)63 VirtualMachine::VirtualMachine(JavaVM * pVm, int nVersion, bool bDestroy,
64                                JNIEnv * pMainThreadEnv):
65     m_pVm(pVm), m_nVersion(nVersion), m_bDestroy(bDestroy)
66 {
67     (void) pMainThreadEnv; // avoid warnings
68 #ifdef SOLAR_JAVA
69     OSL_ENSURE(pVm != 0 && nVersion >= JNI_VERSION_1_2 && pMainThreadEnv != 0,
70                "bad parameter");
71 #endif
72 }
73 
~VirtualMachine()74 VirtualMachine::~VirtualMachine()
75 {
76     if (m_bDestroy)
77     {
78         // Do not destroy the VM.  Under Java 1.3, the AWT event loop thread is
79         // not a daemon thread and is never terminated, so that calling
80         // DestroyJavaVM (waiting for all non-daemon threads to terminate) hangs
81         // forever.
82 /*
83         jint n = m_pVm->DestroyJavaVM();
84         OSL_ENSURE(n == JNI_OK, "JNI: DestroyJavaVM failed");
85 */
86     }
87 }
88 
attachThread(bool * pAttached) const89 JNIEnv * VirtualMachine::attachThread(bool * pAttached) const
90 {
91 #ifndef SOLAR_JAVA
92     return 0;
93 #else
94     OSL_ENSURE(pAttached != 0, "bad parameter");
95     JNIEnv * pEnv;
96     jint n = m_pVm->GetEnv(reinterpret_cast< void ** >(&pEnv), m_nVersion);
97     if (n != JNI_OK && n != JNI_EDETACHED) {
98         OSL_ENSURE(false, "JNI: GetEnv failed");
99     }
100     if (pEnv == 0)
101     {
102         if (m_pVm->AttachCurrentThread(reinterpret_cast< void ** >(&pEnv), 0)
103             != JNI_OK)
104             return 0;
105         *pAttached = true;
106     }
107     else
108         *pAttached = false;
109     return pEnv;
110 #endif
111 }
112 
detachThread() const113 void VirtualMachine::detachThread() const
114 {
115 #ifdef SOLAR_JAVA
116     if (m_pVm->DetachCurrentThread() != JNI_OK) {
117         OSL_ENSURE(false, "JNI: DetachCurrentThread failed");
118     }
119 #endif
120 }
121