私はメモリリークを追跡しようとしてきた私は、元の歴史の中で、この変更に出くわしたジェダイVCLのJvHidControllerClass.pas
、:Delphi:スレッドを「中断しない」ように作成する必要がありますか?
古いリビジョン:
constructor TJvHidDeviceReadThread.CtlCreate(const Dev: TJvHidDevice);
begin
inherited Create(True);
Device := Dev;
NumBytesRead := 0;
SetLength(Report, Dev.Caps.InputReportByteLength);
end;
現在のリビジョン:
constructor TJvHidDeviceReadThread.CtlCreate(const Dev: TJvHidDevice);
begin
inherited Create(False);
Device := Dev;
NumBytesRead := 0;
SetLength(Report, Dev.Caps.InputReportByteLength);
end;
私が発見したのは、スレッドを作成すると、ではなく、中断:
inherited Create(False);
スレッドがすぐに実行を開始します。
procedure TJvHidDeviceReadThread.Execute;
begin
while not Terminated do
begin
FillChar(Report[0], Device.Caps.InputReportByteLength, #0);
if Device.ReadFileEx(Report[0], Device.Caps.InputReportByteLength, @DummyReadCompletion) then
すぐReport
を記入し、オブジェクトDevice
にアクセスしようとする。この場合、それはまだ初期化されていないオブジェクトにアクセスしようとします。問題はまだ初期化されていないことです。これらは、スレッドが開始された後次線です:私は実現
Device := Dev;
NumBytesRead := 0;
SetLength(Report, Dev.Caps.InputReportByteLength);
これは競合状態です。生産のクラッシュを経験するユーザーの確率はかなり低いので、レースクラッシュを離れることはおそらく無害です。
しかし、私はオフですか?何か不足していますか?電話をかける:
BeginThread(nil, 0, @ThreadProc, Pointer(Self), Flags, FThreadID);
スレッドをオフにしてすぐに実行しないでください。これは本当に(意図的に)JVCLに追加された競合状態回帰ですか?
CreateSuspended(True);
...
FDataThread.Resume;
:経由で正しいコードになり
CreateSuspended(False);
に関するいくつかの秘密がありますか?
誤っ
TMyThread.Create(False)
を呼び出すことによって焼かれた後、私は決して正しいと私の脳でそれを提出してきました。スレッドをすぐに開始させるための有効な使用はありますか(値を初期化する必要がある場合)?
うわー!!! JVCL on D5!私はそれを終了し、D5の互換性を維持することを止めた後、プラグが切られました。そんなノスタルジックな感じ... –
@ Arioch'Theあまりにも懐かしくはありません。 2009年のJVCL 3.xです。厳密に言えば、Richard MarquandのオリジナルのHidControllerクラスです(2005年)。私はそれを少し助けました。 JVCLが採用したバージョンは、巨大な "jcl-ifying" *を受けました。実際の違いはありません。技術的には私はリチャードのバージョンを使用しています。だから、私はFastMMがキャッチする* use-after-free *クラッシュを修正することができます。 –