File-Sharing ... my next "Sometimes-Bug" in MT5?

 

FILE_SHARE_READ and FILE_SHARE_WRITE do not work proper. MQL creates buffers with different contents for the same file. 

Please watch the example. It´s one of these "Sometimes bugs". If you cannot provoke the shown output, play around with the lines, add more FILE_SEEKs or change the filename. If you suspect the macro FILE_WRITE_STRING ... it´s ok, I can provoke the error also without it. But I had to play around with the code until the error was shown. Once the error occurs, you will never get rid of it until the filename is changed. This is really not funny. 

This is the output, which it should never be, but which is it in almost all cases 

It can only be fixed, when the file-handle, which is used for reading, is closed and reopened. In other words, FILE_SHARE_WRITE seems to work, but FILE_SHARE_READ does not. 

//+------------------------------------------------------------------+
//| File macros                                                      |
//+------------------------------------------------------------------+
#define FILE_ISEXIST(filename) FileIsExist(filename,0)
#define FILE_ISEXIST_COMMON(filename) FileIsExist(filename,FILE_COMMON)
#define FILE_OPEN(filename) FileOpen(filename,FILE_READ|FILE_WRITE|FILE_BIN)
#define FILE_OPEN_COMMON(filename) FileOpen(filename,FILE_READ|FILE_WRITE|FILE_BIN|FILE_COMMON)
#define FILE_OPEN_SHARED(filename) FileOpen(filename,FILE_READ|FILE_WRITE|FILE_BIN|FILE_SHARE_READ|FILE_SHARE_WRITE)
#define FILE_OPEN_COMMON_SHARED(filename) FileOpen(filename,FILE_READ|FILE_WRITE|FILE_BIN|FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_COMMON)
#define FILE_OPEN_TEXT(filename) FileOpen(filename,FILE_READ|FILE_WRITE|FILE_TXT|FILE_COMMON)
#define FILE_OPEN_TEXT_COMMON(filename) FileOpen(filename,FILE_READ|FILE_WRITE|FILE_TXT|FILE_COMMON)
#define FILE_CLOSE(handle) FileClose(handle)
#define FILE_WRITE_DOUBLE(handle,value) FileWriteDouble(handle,value)
#define FILE_READ_DOUBLE(handle) FileReadDouble(handle)
#define FILE_WRITE_INT(handle,value) FileWriteInteger(handle,value)
#define FILE_READ_INT(handle) FileReadInteger(handle)
#define FILE_WRITE_BOOL(handle,value) FileWriteInteger(handle,(int)value)
#define FILE_READ_BOOL(handle) (bool)FileReadInteger(handle)
#define FILE_WRITE_LONG(handle,value) FileWriteLong(handle,value)
#define FILE_READ_LONG(handle) FileReadLong(handle)
#define FILE_READ_DATETIME(handle) (datetime)FileReadLong(handle)
#define FILE_WRITE_DATETIME(handle,value) FileWriteLong(handle,(long)value)
#define FILE_WRITE_STRING(handle,value) { FileWriteInteger(handle,StringLen(value)); FileWriteString(handle,value,StringLen(value)); } 
#define FILE_READ_STRING(handle) FileReadString(handle,FileReadInteger(handle))
#define FILE_FLUSH(handle) FileFlush(handle)
#define FILE_SEEK_ABS(handle,pos) FileSeek(handle,pos,SEEK_SET)
#define FILE_SEEK_END(handle,pos) FileSeek(handle,0,SEEK_END)

int handle1, handle2;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Open file twice
      handle1=FILE_OPEN_SHARED("fileshare.bin");
      handle2=FILE_OPEN_SHARED("fileshare.bin");
//--- create timer
   EventSetMillisecondTimer(25);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
      FILE_CLOSE(handle1);
      FILE_CLOSE(handle2);
//--- destroy timer
   EventKillTimer();
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
  
  //---
  //--- Write data to file (#1)
  //---
  static int count_write=0;
  count_write ++;

  //--- Read, for whatever reason 
  FILE_SEEK_ABS(handle1,0);
  FILE_READ_STRING(handle1);     // <--- This line mainly provokes the error

  //--- Write
  FILE_SEEK_ABS(handle1,0);
  FILE_WRITE_STRING(handle1,"This is count number #"+(string)count_write);
  FILE_WRITE_INT(handle1,count_write);
  FILE_FLUSH(handle1);
  
  //---
  //--- Read data from file (#2)
  //---
  string text=NULL;
  FILE_SEEK_ABS(handle2,0);
  text=FILE_READ_STRING(handle2);
  int count_read=FILE_READ_INT(handle2);
  
  if (count_read!=count_write)
      {
      Print("Detected read/share error (value written: ",count_write," / value readed: ", count_read, " )");
      ExpertRemove();
      }
  else   
      Print(text);
  
  
//---
   
  }
 
#Update - it´s the same thing in MT4. And in view of some weird issues I have - since years - which I cannot explain, this bug must be present since years as well. 
 
Doerk Hilger:

FILE_SHARE_READ and FILE_SHARE_WRITE do not work proper. MQL creates buffers with different contents for the same file. 

Please watch the example. It´s one of these "Sometimes bugs". If you cannot provoke the shown output, play around with the lines, add more FILE_SEEKs or change the filename. If you suspect the macro FILE_WRITE_STRING ... it´s ok, I can provoke the error also without it. But I had to play around with the code until the error was shown. Once the error occurs, you will never get rid of it until the filename is changed. This is really not funny. 

This is the output, which it should never be, but which is it in almost all cases 

It can only be fixed, when the file-handle, which is used for reading, is closed and reopened. In other words, FILE_SHARE_WRITE seems to work, but FILE_SHARE_READ does not. 

Is your real use case really using 2 handles on the same file from 1 running EA ?

Why are you opening both handles with READ and WRITE when you only write from 1 handle ?

And by the way I can't reproduce the issue. If you don't provide a way to reproduce I doubt it will ever be fixed.

 
For me the error happens as well. First run of the EA / indicator with the sample code above was fine but the error started with the second run and could only be resolved by deleting the file.
 
Alain Verleyen:

Is your real use case really using 2 handles on the same file from 1 running EA ?

Why are you opening both handles with READ and WRITE when you only write from 1 handle ?

And by the way I can't reproduce the issue. If you don't provide a way to reproduce I doubt it will ever be fixed.

- Of course its not designed to work with two handles in one EA, its rather for sharing data between several instances of one EA and for sharing data between indicators and EAs. 

- I open both RW just to simulate the reality. The final EAs/indicators etc. do write and read

- But as you see, others could also reproduce it. 

btw thx @ comeero for trying this out too. 

 
comeero:
For me the error happens as well. First run of the EA / indicator with the sample code above was fine but the error started with the second run and could only be resolved by deleting the file.

Same here, it works if the file didn't exist, but as soon as the sample is run on an existing file I get this error:

Detected read/share error (value written: 2 / value read: 1 )
Looks like the FileFlush does not cause an update at the second handle.
 

So this was finally discussed on the Russian forum after an other user reported the same issue.

They will NOT fix it, we have to deal with it. They just propose an (obvious) workaround.

Forum on trading, automated trading systems and testing trading strategies

Errors, bugs, questions

Slava , 2020.04.24 08:37

I understand the problem you described.

1st Expert Advisor writes a file. It may not close this file, but in this case should call FileFlush

The 2nd Expert Advisor reads the file. It must open the file every time, then close it.

Opening and closing a file is only for the second adviser!


 
Alain Verleyen:

So this was finally discussed on the Russian forum after an other user reported the same issue.

They will NOT fix it, we have to deal with it. They just propose an (obvious) workaround.


Great. Especially in duplex mode where none of them knows who is first or second. This is not really a working workaround, it´s a performance killer, cause you can only deal with it, when the file is permanently opened and closed by all EAs and indicators which access it. 

The only true workaround is: Do it with Windows functions and activate DLL. 

 
Doerk Hilger:

Great. Especially in duplex mode where none of them knows who is first or second. This is not really a working workaround, it´s a performance killer, cause you can only deal with it, when the file is permanently opened and closed by all EAs and indicators which access it. 

The only true workaround is: Do it with Windows functions and activate DLL. 

I know but I will not waste more time trying to convince them. Next one...
Reason: