1474484 change committed to support the not calling of safeRelease() on Variant constant objects.

This commit is contained in:
clay_shooter
2006-04-23 20:35:26 +00:00
parent 5b807839cd
commit 0db059858a
3 changed files with 210 additions and 36 deletions

View File

@@ -1,6 +1,46 @@
<HTML> <HTML>
<BODY> <BODY>
<h2>What's New in JACOB 1.10</h2> <h2>JACOB 1.10.1</h2>
<h3>What's New</h3>
<ul>
<li>
<b>Variants</b>
<ul>
<li>Static constnats are no longer released
</ul>
</li>
</ul>
<h3>Tracked Changes</h3>
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%">
<tr>
<td width="100%" colspan="2"><b>Bugs</b></td>
</tr>
<tr>
<td width="13%">1474474</td>
<td width="87%">Static constants in the Variant class can no longer have SafeRelease() called on them.</td>
</tr>
<tr>
<td width="13%">&nbsp;</td>
<td width="87%">&nbsp;</td>
</tr>
<tr>
<td width="100%" colspan="2"><b>Patches</b></td>
</tr>
<tr>
<td width="13%">&nbsp;</td>
<td width="87%">&nbsp;</td>
</tr>
<tr>
<td width="100%" colspan="2"><b>Feature Requests</b></td>
</tr>
</table>
</ul>
<!---------------------------------------/>
<h2>JACOB 1.10</h2>
<h3>What's New</h3>
<ul> <ul>
<li> <li>
<b>Windows Processes</b> <b>Windows Processes</b>
@@ -36,8 +76,9 @@
values should be backwards compatible with previous releases. values should be backwards compatible with previous releases.
</ul> </ul>
</li> </li>
</ul>
<h2>Tracked Changes</h2> <h3>Tracked Changes</h3>
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%"> <table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%">
<tr> <tr>
<td width="100%" colspan="2"><b>Bugs</b></td> <td width="100%" colspan="2"><b>Bugs</b></td>
@@ -89,7 +130,7 @@
<td width="87%">&nbsp;</td> <td width="87%">&nbsp;</td>
</tr> </tr>
<tr> <tr>
<td width="100%" colspan="2"><b>Feature Requests(pre1)</b></td> <td width="100%" colspan="2"><b>Feature Requests</b></td>
</tr> </tr>
<tr> <tr>
<td width="13%">1241037</td> <td width="13%">1241037</td>
@@ -118,7 +159,8 @@
<!---------------------------------------/> <!---------------------------------------/>
<h2>What's New in JACOB 1.9.1</h2> <h2>JACOB 1.9.1</h2>
<h3>What's New</h3>
<ul> <ul>
<li> <li>
<b>License</b> <b>License</b>
@@ -148,9 +190,9 @@
<li>Multi-dimensional (greater than 2) support <li>Multi-dimensional (greater than 2) support
</ul> </ul>
</li> </li>
</ul>
<h3>Tracked Changes</h3>
<h2>Tracked Changes</h2>
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%"> <table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%">
<tr> <tr>
<td width="100%" colspan="2"><b>Bugs</b></td> <td width="100%" colspan="2"><b>Bugs</b></td>
@@ -195,7 +237,8 @@
<!---------------------------------------/> <!---------------------------------------/>
<h2>What's New in JACOB 1.9</h2> <h2>JACOB 1.9</h2>
<h3>What's New</h3>
<ul> <ul>
<li> <li>
@@ -302,7 +345,7 @@ running this from inside of Eclipse</li>
<li>All makefiles have been purged</li> <li>All makefiles have been purged</li>
</ul> </ul>
<h2>Tracked Changes</h2> <h3>Tracked Changes</h3>
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%"> <table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%">
<tr> <tr>
<td width="100%" colspan="2"><b>Bugs</b></td> <td width="100%" colspan="2"><b>Bugs</b></td>
@@ -399,7 +442,8 @@ running this from inside of Eclipse</li>
</ul> </ul>
<h2>What's New in JACOB 1.8</h2> <h2>JACOB 1.8</h2>
<h3>What's New</h3>
<ul> <ul>
<li> <li>
@@ -430,7 +474,8 @@ people to start contributing to the project with this version.
</ul> </ul>
<li> <li>
<h2>What's New in JACOB 1.7</h2> <h2>JACOB 1.7</h2>
<h3>What's New</h3>
<ul> <ul>
<li> <li>

View File

@@ -20,6 +20,8 @@
package com.jacob.com; package com.jacob.com;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/** /**
* The multi-format data type used for all call backs and most communications * The multi-format data type used for all call backs and most communications
@@ -31,7 +33,13 @@ import java.util.Date;
* marshalling/unmarshalling code is broken in the JNI layer. * marshalling/unmarshalling code is broken in the JNI layer.
*/ */
public class Variant extends JacobObject { public class Variant extends JacobObject {
/**
/**
* holds the list Variants that should never be freed
*/
private static Map VARIANTS_THAT_ARE_CONSTANTS = new HashMap();
/**
* Use this constant for optional parameters * Use this constant for optional parameters
*/ */
public final static com.jacob.com.Variant DEFAULT; public final static com.jacob.com.Variant DEFAULT;
@@ -40,12 +48,6 @@ public class Variant extends JacobObject {
* Same than {@link #DEFAULT} * Same than {@link #DEFAULT}
*/ */
public final static com.jacob.com.Variant VT_MISSING; public final static com.jacob.com.Variant VT_MISSING;
static {
com.jacob.com.Variant vtMissing = new com.jacob.com.Variant();
vtMissing.noParam();
DEFAULT = vtMissing;
VT_MISSING = vtMissing;
}
/** /**
* Use for true/false variant parameters * Use for true/false variant parameters
@@ -59,6 +61,26 @@ public class Variant extends JacobObject {
public final static com.jacob.com.Variant VT_FALSE = new com.jacob.com.Variant( public final static com.jacob.com.Variant VT_FALSE = new com.jacob.com.Variant(
false); false);
/*
* do the run time definition of DEFAULT and MISSING
*/
static {
com.jacob.com.Variant vtMissing = new com.jacob.com.Variant();
vtMissing.noParam();
DEFAULT = vtMissing;
VT_MISSING = vtMissing;
}
/*
* adds all the constants to the list of those that should not be released
*/
static {
VARIANTS_THAT_ARE_CONSTANTS.put(VT_TRUE,VT_TRUE);
VARIANTS_THAT_ARE_CONSTANTS.put(VT_MISSING,VT_MISSING);
VARIANTS_THAT_ARE_CONSTANTS.put(VT_FALSE,VT_FALSE);
VARIANTS_THAT_ARE_CONSTANTS.put(DEFAULT,DEFAULT);
}
/** /**
* Pointer to MS struct. * Pointer to MS struct.
*/ */
@@ -800,31 +822,50 @@ public class Variant extends JacobObject {
* @see java.lang.Object#finalize() * @see java.lang.Object#finalize()
*/ */
protected void finalize() { protected void finalize() {
super.safeRelease(); safeRelease();
safeRelease();
} }
/* /**
* (non-Javadoc) * This will release the "C" memory for the Variant
* * unless this Variant is one of the constants in which case
* we don't want to release the memory.
* <p>
* @see com.jacob.com.JacobObject#safeRelease() * @see com.jacob.com.JacobObject#safeRelease()
*/ */
public void safeRelease() { public void safeRelease() {
super.safeRelease(); // The well known constants should not be released.
if (m_pVariant != 0) { // Unfortunately this doesn't fix any other classes that are
release(); // keeping constants around in their static ivars.
m_pVariant = 0; // those will still be busted.
} else { //
// looks like a double release // The only inconcistency here is that we leak
// this should almost always happen due to gc // when this class is unloaded because we won't
// after someone has called ComThread.Release // free the memory even if the constants are being
// finalized. this is not a big deal at all.
// another way around this would be to create the constants
// in their own thread so that they would never be released
if (!Variant.VARIANTS_THAT_ARE_CONSTANTS.containsValue(this)){
super.safeRelease();
if (m_pVariant != 0) {
release();
m_pVariant = 0;
} else {
// looks like a double release
// this should almost always happen due to gc
// after someone has called ComThread.Release
if (isDebugEnabled()) {
debug("Variant: " + this.hashCode()
+ " double release");
//Throwable x = new Throwable();
//x.printStackTrace();
}
}
} else {
if (isDebugEnabled()) { if (isDebugEnabled()) {
debug("Variant: " + this.hashCode() debug("Variant: " + this.hashCode()
+ " double release"); + " don't want to release a constant");
//Throwable x = new Throwable();
//x.printStackTrace();
} }
} }
} }
/** /**

View File

@@ -2,10 +2,99 @@ package com.jacob.com;
/** /**
* runs through some of the get and set methods on Variant * runs through some of the get and set methods on Variant
*
* -Djava.library.path=d:/jacob/release -Dcom.jacob.debug=false
*/ */
class VariantTest { class VariantTest {
public static void main(String[] args) { public static void main(String[] args) {
System.out.println("Testing Started"); System.out.println("Testing Started");
VariantTest testJig = new VariantTest();
testJig.testPutsAndGets();
testJig.testSafeReleaseBoolean();
testJig.testSafeReleaseConstant();
testJig.testSafeReleaseString();
System.out.println("Testing Complete");
}
/**
* dummy constructor
*
*/
public VariantTest(){
}
private void testSafeReleaseBoolean(){
Variant v = new Variant(true);
System.out.println("Newly created Variant ("+ v.getBoolean()+") "+
"trying to create access violation but it doesn't seem to be easy");
v.safeRelease();
if (v.getBoolean() != true){
System.out.println("Variant value ("+v.getBoolean()+") "
+"has been broken by SafeRelease()");
} else {
System.out.println("Variant value ("+v.getBoolean()+") "
+"has survived SafeRelease()");
}
for ( int i = 0 ; i < 20000; i ++){
new Variant ("xxx"+i);
new Variant(i);
new Variant ("yyy"+i);
}
ComThread.Release();
if (v.getBoolean() != true){
System.out.println("Variant value ("+v.getBoolean()+") "
+"has been broken by ComThread.Release()");
} else {
System.out.println("Variant value ("+v.getBoolean()+") "
+"has been survived by ComThread.Release()");
}
}
private void testSafeReleaseConstant(){
System.out.println("Using Static constant Variant - should never throw access violation");
Variant.VT_TRUE.safeRelease();
if (Variant.VT_TRUE.getBoolean() != true){
System.out.println("VT_TRUE has been broken by SafeRelease()");
} else {
System.out.println("VT_TRUE survived SafeRelease()");
}
for ( int i = 0 ; i < 20000; i ++){
new Variant ("xxx"+i);
new Variant(i);
new Variant ("yyy"+i);
}
ComThread.Release();
if (Variant.VT_TRUE.getBoolean() != true){
System.out.println("VT_TRUE has been broken by ComThread.Release()");
} else {
System.out.println("VT_TRUE survived ComThread.Release()");
}
}
private void testSafeReleaseString(){
String mTestString = "Guitar Hero";
Variant v = new Variant(mTestString);
System.out.println("Newly created Variant ("+ v.getString()+") "+
"trying to create access violation but it doesn't seem to be easy");
v.safeRelease();
if (v.getString() == null || !v.getString().equals(mTestString)){
System.out.println("Variant value ("+v.getString()+") "
+"has been broken by SafeRelease()");
} else {
System.out.println("Variant value ("+v.getString()+") "
+"has survived SafeRelease()");
}
}
/**
* tests put and get methods looking for obvious defects
*
*/
private void testPutsAndGets(){
Variant v = new Variant(); Variant v = new Variant();
v.putInt(10); v.putInt(10);
if (v.toInt() != 10){ if (v.toInt() != 10){
@@ -59,7 +148,6 @@ class VariantTest {
System.out.println("putNothing is supposed to cause isNull() to return true"); System.out.println("putNothing is supposed to cause isNull() to return true");
} }
System.out.println("Testing Complete");
} }
} }