I'm trying to track down an issue that I believe exists with an object's global TCriticalSection. Example code:
TMyObject = class
private
FCS: TCriticalSection;
FInternalObject: TSomeInternalObject;
public
constructor Create;
destructor Destroy; override;
procedure WorkWithObjectA(Data: TDataTypeA);
procedure WorkWithObjectB(Data: TDataTypeB);
end;
constructor TMyObject.Create;
begin
FCS := TCriticalSection.Create;
FInternalObject := TSomeInternalObject.Create;
end;
destructor TMyObject.Destroy;
begin
FInternalObject.Free;
FCS.Free;
inherited;
end;
procedure TMyObject.WorkWithObjectA(Data: TDataTypeA);
begin
FCS.Enter;
try
FInternalObject.DoProcessA(Data);
finally
FCS.Leave;
end;
procedure TMyObject.WorkWithObjectB(Data: TDataTypeB);
begin
FCS.Enter;
try
FInternalObject.DoProcessB(Data);
finally
FCS.Leave;
end;
Question: If multiple threads are calling both procedures, will the TCriticalSection block WorkWithObjectB() if WorkWithObjectA() is blocking? This is a simplified version of a much more complex situation. The two procedures use greatly different structures, and thus cannot be easily combined into one blocking method... thoughts?
CodePudding user response:
Yes, if multiple threads are calling both procedures, the TCriticalSection will block both WorkWithObjectB() and WorkWithObjectA().
Note that in a complex situation, where WorkWithObjectB() will call WorkWithObjectA(), then there will be no deadlock. The lock occurs only when the call is in the context of a thread not already owning the lock.