Log On
Embarcadero Home
Watch, Follow, &
Connect with Us
Share This
QualityCentral
Communities
Articles
Blogs
Resources
Downloads
Help
QualityCentral
Delphi-BCB
RTL
Delphi
Arithmetic
ConvUtils
Date - Time
DateUtils
File Management
Format + Float
Input/Output
Math Unit
Memory, Pointer, Address
Null-terminated strings
Other Classes
Other RTL
Pascal Strings
Regular Expressions
RTL Exceptions
Text Files
Thread support
Typed/Untyped Files
WinAPI
You are not logged in.
Help
Print
Public Report
Report From:
Delphi-BCB/RTL/Delphi/Thread support
[ Add a report in this area ]
Report #:
111795
Status:
Open
Race-condition in TMonitor code causing application to hang on exit
Project:
Delphi
Build #:
XE2, XE3
Version:
17.1
Submitted By:
Cosmin Prund
Report Type:
Basic functionality failure
Date Reported:
1/8/2013 11:25:12 AM
Severity:
Serious / Highly visible problem
Last Updated:
1/23/2013 4:50:54 AM
Platform:
All versions
Internal Tracking #:
35304
Resolution:
None
(Resolution Comments)
Resolved in Build:
:
None
Duplicate of:
None
Voting and Rating
Overall Rating:
(1 Total Rating)
5.00 out of 5
Total Votes:
1
Description
There's a race condition in TMonitor code causing the application to hang when terminating.
Note:
I can confirm the issue is resolved by freeing SyncObj.
None the less I still consider this a serious bug. The penalty for not freeing a small object should be a small memory leak, not an application that hangs for ever.
Steps to Reproduce:
program Project29;
{$APPTYPE CONSOLE}
uses SysUtils, Windows, Classes;
// Thread declaration, because Delphi 2010 doesn't have an anonymous way of creating a small thread.
type
TTestThread = class(TThread)
public
procedure Execute;override;
end;
// Those constants control the test
const TestLenSeconds = 1;
ThreadCount = 4;
var
SyncObj: TObject; // ALL threads will use this object to sync, because I want them to clash!
Handles: array [1..ThreadCount] of Cardinal;
i: Integer;
// The thread-routine. Very simple: Loops until the specified number of seconds passes,
// inside the loop doesn an empty try-finally Enter-Exit using TMonitor. Technically
// nothing should go wrong in there!
procedure TTestThread.Execute;
var
StopAt: TDateTime;
begin
StopAt := Now + EncodeTime(0, TestLenSeconds div 60, TestLenSeconds mod 60, 0);
while Now < StopAt do
begin
TMonitor.Enter(SyncObj);
try
finally
TMonitor.Exit(SyncObj);
end;
end;
end;
// Main
begin
try
try
// Preapre the object that we'll synchronize on
SyncObj := TObject.Create;
// Start ThreadCount threads threads
for i:=1 to 4 do
with TTestThread.Create(False) do
begin
Handles[i] := Handle;
end;
WriteLn('All ', ThreadCount, ' threads are started, please wait ', TestLenSeconds, ' seconds for the threads to finish.');
// Wait for all the threads to finish
WaitForMultipleObjects(ThreadCount, @Handles, True, INFINITE);
// Wait until they're all done
WriteLn('All threads are done.');
except on E: Exception do Writeln(E.ClassName, ': ', E.Message);
end;
finally
WriteLn('Press ENTER to Exit');
ReadLn;
WriteLn('ENTER received, application exiting.');
WriteLn('If you get to read this, the application is now stuck and will never finish.');
end;
end.
Workarounds
The problem is solved by calling SyncObj.Free after all threads are done.
Attachment
None
Comments
Leif Uneus at 1/8/2013 11:40:49 AM
-
I can confirm this behavior in XE3 Version 17.0.4723.55752.
It gets stuck in SysUtils DoneMonitorSupport when calling CleanEventList
Paul Thornton at 1/8/2013 2:27:58 PM
-
I am also experiencing the same issue in XE2. My application is very thread intensive and hangs in the same place when shutting down the app.
Uwe Raabe at 1/8/2013 4:23:54 PM
-
The problem is solved by calling SyncObj.Free after all threads are done.
Cosmin Prund at 1/22/2013 2:24:01 AM
-
I can confirm the issue is resolved by freeing SyncObj.
None the less I still consider this a serious bug. The penalty for not freeing a small object should be a small memory leak, not an application that hangs for ever.
Besides, I might have chosen to intentionally never free that object: We're talking about the shutdown of the application, all memory is about to be reclaimed by the operating system anyhow.
Leif Uneus at 1/31/2013 3:04:42 PM
-
The QC 99324 "Process hangs on shutdown after using TMonitor to wait on an object that isn't freed" seems to be related.
View Your Reports
Search
Server Response from: ETNACODE01
Developer Tools
Blackfish SQL
C++Builder
Delphi
FireMonkey
Prism
InterBase
JBuilder
J Optimizer
HTML5 Builder
3rdRail & TurboRuby
Database Tools
Change Manager
DBArtisan
DB Optimizer
ER/Studio
Performance Center
Rapid SQL
Technical Articles
Tutorials
White Papers
Press Releases
Newsletters
Add Content (GetPublished)
Audio
Audio & Video
Video
Bugs & Suggestions (QualityCentral)
Discussion Forums
Examples (CodeCentral)
Tags
Technology Partners
Downloads
Free Trials
Registered User Downloads
Beta Programs
Add Content (GetPublished)
Articles
Blogs
Bugs & Suggestions (QualityCentral)
Discussion Forums
Examples (CodeCentral)
Member Services
About
Connect with Us