4

First of all, I am not sure that it is a good design to allow worker thread to disable controls. However, I am curious can I do it safely without synchronization with GUI?

The code in TDataSet looks like this:

procedure TDataSet.DisableControls;
begin
  if FDisableCount = 0 then
  begin
    FDisableState := FState;
    FEnableEvent := deDataSetChange;
  end;
  Inc(FDisableCount);
end;

So it looks safe to do. The situation would be different in case of EnableControls. But DisableControls seems to only increase lock counter and assigning event which is fired up during EnableControls.

What do you think?

LU RD
  • 34,438
  • 5
  • 88
  • 296
Wodzu
  • 6,932
  • 10
  • 65
  • 105
  • Even `Inc`by itself is not threadsafe if you don't compile with data alignment. I would strongly advice against using **any control** linked somehow to GUI controls. – Lieven Keersmaekers Nov 27 '11 at 23:00
  • 1
    Further, consider following scenario: Thread enters, FDisableCount = 0, FDisableState = FState. A context switch happens, your main thread decrements FDisableCount and changes FDisableState (I suppose that is what would happen in EnableControls, haven't looked). A context switch happens and your thread is running again but now working with a wrong FDisableState. – Lieven Keersmaekers Nov 27 '11 at 23:06
  • Thanks for pointing that out Lieven. – Wodzu Nov 30 '11 at 08:55

2 Answers2

0

It looks safe to do so, but things may go wrong because these flags are used in code that may be in the middle of being executed at the moment you call this method from your thread.

I would Synchronise the call to DisableControls, because you want your thread to start using this dataset only if no controls are using it. The call to EnableControls can be synchronised too, or you can post a message to the form using PostMessage. That way, the thread doesn't have to wait for the main thread.

But my gut feelings tells me that is may be better to not use the same dataset for the GUI and the thread at all.

dummzeuch
  • 10,975
  • 4
  • 51
  • 158
GolezTrol
  • 114,394
  • 18
  • 182
  • 210
0

Without having looked up the actual code: It might be safe, as long as you can be sure that the main thread currently does not access FDisableCount, FDisableState and FEnableEvent. There is the possibility of a race condition here.

I would still recommend that you call DisableControls from within the main thread.

dummzeuch
  • 10,975
  • 4
  • 51
  • 158