I have registered my application for ARR. Assume that my application has a IdTCPServer
which reads data from the serial port using VSPE
and adds it to a ClientDataSet
. If the main thread freezes, ARR will call my ApplicationRecoveryCallback(). Can I access the IdTCPServer
in the recovery callback function safely? I want it to stop so that I can save my ClientDataSet
to the disk before restarting. Can I simply write my function this way?
function RecoveryFunction(pvParameter: Pointer): DWORD; stdcall;
var
ContinueRecovery: Boolean;
begin
Result := 0; // happy compiler ;-)
repeat
ApplicationRecoveryInProgress(ContinueRecovery);
if not ContinueRecovery then
ApplicationRecoveryFinished(False);
until frmInstrument.CriticalSection.TryEnter;
frmInstrument.IdTCPServer.Active := False;
frmInstrument.CDS.SaveToFile(RecoveryFile);
ApplicationRecoveryFinished(True);
end;
I wouldn't write it like that. This function is called when your program has stopped responding. For all you know, it's stopped responding because something else is already stuck waiting for that same critical section.
If you want to be able to access your data even when your program is hung, then you need a lock-free way of detecting when you're allowed to read your data. Use a transaction-log model. Atomically update something that indicates how much of your data is valid. When you enter the recovery function, read that value, and save as much as it says is available. Don't bother reading beyond that point because you can't be certain that it's not corrupt and the reason for your program's crash in the first place.