While developing our GUI development environment here at SAS Institute
we found that we consistently crashed the VM when creating our own
version of the java.awt.Checkbox component. The only difference between
our checkbox and the java checkbox is that the constructor also sets the
label of the checkbox.
Here is our Checkbox constructor:
public CheckBox()
{
initializeComponent();
setLabel("checkbox");
enableEvents(java.awt.AWTEvent.ITEM_EVENT_MASK);
}
public void initializeComponent ()
{
// Set the component's default values
setDefaultValues();
getComponentSupportInfo().m_DesignTime =
COM.sas.Component.beansIsDesignTime();
// TO-DO: Add run time only code here
}
protected void setDefaultValues()
{
setOwner( null );
setComponentName( null );
setServerName("");
setComponentDescription("Component");
Vector requiredInterfaces = new Vector();
setRequiredInterfaces(requiredInterfaces);
getComponentSupportInfo().m_DesignTime = false;
setDefaultSourceAttribute("");
setDefaultTargetAttribute("");
} // setDefaultValues
The crash occurrs during the initial display of the Checkbox and is very
flaky. Most of the times it happens but sometimes it does not. However,
I was able to trace it down to this code in awt_Font.cpp:
long /*boolean*/
sun_awt_windows_WDefaultFontCharset_canConvert(
Hsun_awt_windows_WDefaultFontCharset* self, unicode ch)
{
static CCombinedSegTableManager tableManager;
CCombinedSegTable* pTable =
tableManager.GetTable(GET_WSTRING(unhand(self)->fontName));
return (pTable->In((USHORT) ch) ? 1 : 0);
}
The In() function was crashing with an unintialized pointer. When it
crashed I found that 2 different threads were running through this code
at the same time. It therefore appears that this code is not exactly
thread-safe. I was able to fix the problem by modifying the code as
follows:
long /*boolean*/
sun_awt_windows_WDefaultFontCharset_canConvert(
Hsun_awt_windows_WDefaultFontCharset* self, unicode ch)
{
static CCombinedSegTableManager tableManager;
monitorEnter(obj_monitor(self)); // only let one thread in at a
time
CCombinedSegTable* pTable =
tableManager.GetTable(GET_WSTRING(unhand(self)->fontName));
monitorExit(obj_monitor(self)); // ok, go for it!
return (pTable->In((USHORT) ch) ? 1 : 0);
}
This fix is very important to us as we really do not want our users to
crash while running our (and your) code.
we found that we consistently crashed the VM when creating our own
version of the java.awt.Checkbox component. The only difference between
our checkbox and the java checkbox is that the constructor also sets the
label of the checkbox.
Here is our Checkbox constructor:
public CheckBox()
{
initializeComponent();
setLabel("checkbox");
enableEvents(java.awt.AWTEvent.ITEM_EVENT_MASK);
}
public void initializeComponent ()
{
// Set the component's default values
setDefaultValues();
getComponentSupportInfo().m_DesignTime =
COM.sas.Component.beansIsDesignTime();
// TO-DO: Add run time only code here
}
protected void setDefaultValues()
{
setOwner( null );
setComponentName( null );
setServerName("");
setComponentDescription("Component");
Vector requiredInterfaces = new Vector();
setRequiredInterfaces(requiredInterfaces);
getComponentSupportInfo().m_DesignTime = false;
setDefaultSourceAttribute("");
setDefaultTargetAttribute("");
} // setDefaultValues
The crash occurrs during the initial display of the Checkbox and is very
flaky. Most of the times it happens but sometimes it does not. However,
I was able to trace it down to this code in awt_Font.cpp:
long /*boolean*/
sun_awt_windows_WDefaultFontCharset_canConvert(
Hsun_awt_windows_WDefaultFontCharset* self, unicode ch)
{
static CCombinedSegTableManager tableManager;
CCombinedSegTable* pTable =
tableManager.GetTable(GET_WSTRING(unhand(self)->fontName));
return (pTable->In((USHORT) ch) ? 1 : 0);
}
The In() function was crashing with an unintialized pointer. When it
crashed I found that 2 different threads were running through this code
at the same time. It therefore appears that this code is not exactly
thread-safe. I was able to fix the problem by modifying the code as
follows:
long /*boolean*/
sun_awt_windows_WDefaultFontCharset_canConvert(
Hsun_awt_windows_WDefaultFontCharset* self, unicode ch)
{
static CCombinedSegTableManager tableManager;
monitorEnter(obj_monitor(self)); // only let one thread in at a
time
CCombinedSegTable* pTable =
tableManager.GetTable(GET_WSTRING(unhand(self)->fontName));
monitorExit(obj_monitor(self)); // ok, go for it!
return (pTable->In((USHORT) ch) ? 1 : 0);
}
This fix is very important to us as we really do not want our users to
crash while running our (and your) code.