Hello,
I hope someone can help me.
I'm using a mutex to protect critical areas of my AFL code. This is to ensure that AFL calls that invoke IBC functions are protected when called from different threads, eg when displaying multiple symbol charts.
I've written the following code to reserve and free the mutex, based on code written by Tomasz.
function _GetIbcMutex( mutexName )
{
_TRACE("_GetIbcMutex Entry " + mutexName);
global _ibcMutex;
_ibcMutex = "";
// Try obtaining mutex for ten second
for( i = 0; i < 10000; i++ )
{
if( StaticVarCompareExchange( mutexName, 1, 0 ) == 0 )
{
_ibcMutex = mutexName;
break;
}
else
ibc.Sleep( 10 );
}
if( _ibcMutex == "" )
_TRACE("ERROR: Cannot obtain mutex " + mutexName);
_TRACE("_GetIbcMutex Exit " + mutexName);
return _ibcMutex != "";
}
function _FreeIbcMutex()
{
_TRACE("_FreeIbcMutex Entry " + _ibcMutex);
global _ibcMutex;
if( _ibcMutex != "" )
{
StaticVarSet( _ibcMutex, 0 );
_ibcMutex = "";
}
_TRACE("_FreeIbcMutex Exit ");
}
To test this, I have written the following sample code:
ibc = GetTradingInterface("IB");
for ( i = 0; i < 10 && ( ibc.IsConnected() != 2 AND ibc.IsConnected() != 3 ); i++ )
{
ibc.Sleep( 200 );
}
SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Plot( C, "Close", ParamColor("Color", colorDefault ), styleNoTitle | ParamStyle("Style") | GetPriceStyle() );
_GetIbcMutex( "ibcMutex" );
_TRACE("Wait for 200ms");
ibc.Sleep( 200 );
_FreeIbcMutex();
I insert this code in a chart pane on Sheet 1.
On Sheet 2 I have another chart pane which displays volume.
In the test, I switch continuously from Sheet 1 to Sheet 2.
Eventually, a mutex deadlock ocurs, where the switch from Sheet 1 to Sheet 2 occurs while the mutex has been reserved and not yet released.
When I switch back to Sheet 1, the display is not updated, because the mutex is still reserved.
Here is the trace record for each refresh cycle of the AFL code
_GetIbcMutex Entry ibcMutex
_GetIbcMutex Exit ibcMutex
Wait for 200ms|F:\AmiBroker AFL\AFL\Basic Charts\Price.afl|55|8|20:21:25.64|
_FreeIbcMutex Entry ibcMutex
_FreeIbcMutex Exit
When the deadlock occurs, the Sheet switch occurred before _FreeIbcMutex is called.
This causes the next iteration of the code to block waiting for the mutex
_GetIbcMutex Entry ibcMutex
_GetIbcMutex Exit ibcMutex
Wait for 200ms
_GetIbcMutex Entry ibcMutex
Am I doing this correctly?
What can I do to solve it?
Polomora