Lock on object

 
Hello

I was wondering if MQL5 has anything similar to the 
lock(object)
{
   object.Update();
}
statement that would grant access to a common resource only to one process?

I'm working on a custom indicator that handles OnCalculate and OnTimer events. There is a list declared at the global scope. Elements are added to the list within OnCalculate and removed from the same list within OnTimer.

Question: It is likely that OnCalculate will be adding items to the list while OnTimer will be removing items withing the for loop, can there be a clash preventing execution of one of the methods? What if removing will occur on some condition that is determined within the OnCaluclate and while the OnTimer executes, this condition changes several times?

Such scenarios are usually handled by placing a lock on the list while adding or removing items. However, I cannot see any lock statements in MQL5 documentation. Could someone please describe how to handle this situation?

Below is the relevant section of code of my custom indicator:

CList *_times = new CList;

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
   datetime time = SymbolInfoInteger(Symbol(), SYMBOL_TIME);
   
   _times.Add(time);

   return(rates_total);
}

void OnTimer()
{
   datetime last = (datetime)_times.GetLastNode();
   for (int i=0;i<_times.Total();i++)
   {
      datetime time = (datetime)_times.GetNodeAtIndex(i);
      if (time < (last-60))
      {
          _times.Delete(i);
      }
   }
}
 
All indicators, EA and scripts are single threaded. OnCalculate and OnTimer can't run simultaneously.
 
Alain Verleyen:
All indicators, EA and scripts are single threaded. OnCalculate and OnTimer can't run simultaneously.

Thank you for your reply.

Does it mean that until OnTimer finishes OnCalculate will never be called? And visa versa if OnCalculate executes when timer event is raised, the OnTimer method will never be called? Since OnCalculate may be called several times a second, may it prevent OnTimer for an extended period of time?

If the timer is set for 30 seconds, when the timer event occurs OnCalculate blocks OnTimer and it is delayed for another 30 seconds, then another timer event occurs and OnCalculate blocks it again resulting in 1.5 minutes total delay of OnTimer and so on? Or will the events be queued in the background and OnTimer will be executed at the first opportunity after approximately 30 seconds + time of the blocking OnCalculate? If the latter it true, does it mean that while OnTimer executes, several OnCalculate may be queued for immediate consecutive execution after OnTimer finishes?

I'm sorry if I'm asking something stupid, I'm just trying to understand how events processing is happening and if data may be lost at some point because OnCalculate and OnTimer cannot execute simultaneously.

 

WOW, this seems to be a common theme this week (me included!)

From the link Alain posted:

A program receives only events from the chart it runs on. All events are processed one after another in the order they are received. If a queue already has a NewTick event, or this event is currently being processed, then the new NewTick event is not placed in the queue of the MQL5 program. Similarly, if ChartEvent is already enqueued, or this event is being processed, no new event of this kind is enqueued. The timer events are handled the same way — if the Timer event is in the queue or being handled, the new timer event is not enqueued.

Event queues have a limited but sufficient size, so that the queue overflow for well written programs is unlikely. In case of queue overflow, new events are discarded without queuing. 


 
Stuart Browne:

WOW, this seems to be a common theme this week (me included!)

From the link Alain posted:

A program receives only events from the chart it runs on. All events are processed one after another in the order they are received. If a queue already has a NewTick event, or this event is currently being processed, then the new NewTick event is not placed in the queue of the MQL5 program. Similarly, if ChartEvent is already enqueued, or this event is being processed, no new event of this kind is enqueued. The timer events are handled the same way — if the Timer event is in the queue or being handled, the new timer event is not enqueued.

Event queues have a limited but sufficient size, so that the queue overflow for well written programs is unlikely. In case of queue overflow, new events are discarded without queuing. 


Thank you, Stuart, that answers my question. So there will be a potential data loss since only one OnCalculate event will be enqueued while OnTimer is executing, even if several of them occur during this time. That's a bit sad.
 
fapadmin:
Thank you, Stuart, that answers my question.
Welcome :)
 
fapadmin:
Thank you, Stuart, that answers my question. So there will be a potential data loss since only one OnCalculate event will be enqueued while OnTimer is executing, even if several of them occur during this time. That's a bit sad.

Yes you can miss ticks or events.

I guess multi-threaded mql programs will be for MT6, but keep it for yourself, no need to frighten Stuart

 
Alain Verleyen:

Yes you can miss ticks or events.

I guess multi-threaded mql programs will be for MT6, but keep it for yourself, no need to frighten Stuart

HAHAHAHAHAHA :D
 
Alain Verleyen:

Yes you can miss ticks or events.

I guess multi-threaded mql programs will be for MT6, but keep it for yourself, no need to frighten Stuart

Ability to raise and handle your own events with delegates would also be quite handy. Something to consider for the MT6 release XD
Reason: