mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-14 21:09:11 +02:00
* fix crash in case of main thread exiting simultaneously with other threads (issue #11006)
git-svn-id: trunk@10492 -
This commit is contained in:
parent
f1bd686065
commit
ae8289f9f7
@ -190,9 +190,9 @@ const
|
|||||||
{$endif}
|
{$endif}
|
||||||
|
|
||||||
var
|
var
|
||||||
main_relo_freelists : pfreelists;
|
|
||||||
orphaned_freelists : tfreelists;
|
orphaned_freelists : tfreelists;
|
||||||
heap_lock : trtlcriticalsection;
|
heap_lock : trtlcriticalsection;
|
||||||
|
heap_lock_use : integer;
|
||||||
threadvar
|
threadvar
|
||||||
freelists : tfreelists;
|
freelists : tfreelists;
|
||||||
|
|
||||||
@ -1392,6 +1392,12 @@ procedure InitHeapThread;
|
|||||||
var
|
var
|
||||||
loc_freelists: pfreelists;
|
loc_freelists: pfreelists;
|
||||||
begin
|
begin
|
||||||
|
if heap_lock_use > 0 then
|
||||||
|
begin
|
||||||
|
entercriticalsection(heap_lock);
|
||||||
|
inc(heap_lock_use);
|
||||||
|
leavecriticalsection(heap_lock);
|
||||||
|
end;
|
||||||
loc_freelists := @freelists;
|
loc_freelists := @freelists;
|
||||||
fillchar(loc_freelists^,sizeof(tfreelists),0);
|
fillchar(loc_freelists^,sizeof(tfreelists),0);
|
||||||
{$ifdef DUMP_MEM_USAGE}
|
{$ifdef DUMP_MEM_USAGE}
|
||||||
@ -1406,6 +1412,7 @@ var
|
|||||||
begin
|
begin
|
||||||
{ we cannot initialize the locks here yet, thread support is
|
{ we cannot initialize the locks here yet, thread support is
|
||||||
not loaded yet }
|
not loaded yet }
|
||||||
|
heap_lock_use := 0;
|
||||||
loc_freelists := @freelists;
|
loc_freelists := @freelists;
|
||||||
fillchar(loc_freelists^,sizeof(tfreelists),0);
|
fillchar(loc_freelists^,sizeof(tfreelists),0);
|
||||||
fillchar(orphaned_freelists,sizeof(orphaned_freelists),0);
|
fillchar(orphaned_freelists,sizeof(orphaned_freelists),0);
|
||||||
@ -1417,9 +1424,12 @@ var
|
|||||||
begin
|
begin
|
||||||
{ this function should be called in main thread context }
|
{ this function should be called in main thread context }
|
||||||
loc_freelists := @freelists;
|
loc_freelists := @freelists;
|
||||||
main_relo_freelists := loc_freelists;
|
heap_lock_use := 1;
|
||||||
initcriticalsection(heap_lock);
|
initcriticalsection(heap_lock);
|
||||||
modify_freelists(loc_freelists, main_relo_freelists);
|
{ loc_freelists still points to main thread's freelists, but they
|
||||||
|
have a reference to the global main freelists, fix them to point
|
||||||
|
to the main thread specific variable }
|
||||||
|
modify_freelists(loc_freelists, loc_freelists);
|
||||||
if MemoryManager.RelocateHeap <> nil then
|
if MemoryManager.RelocateHeap <> nil then
|
||||||
MemoryManager.RelocateHeap();
|
MemoryManager.RelocateHeap();
|
||||||
end;
|
end;
|
||||||
@ -1428,12 +1438,13 @@ procedure FinalizeHeap;
|
|||||||
var
|
var
|
||||||
poc, poc_next: poschunk;
|
poc, poc_next: poschunk;
|
||||||
loc_freelists: pfreelists;
|
loc_freelists: pfreelists;
|
||||||
|
last_thread: boolean;
|
||||||
{$ifdef DUMP_MEM_USAGE}
|
{$ifdef DUMP_MEM_USAGE}
|
||||||
i : longint;
|
i : longint;
|
||||||
{$endif}
|
{$endif}
|
||||||
begin
|
begin
|
||||||
loc_freelists := @freelists;
|
loc_freelists := @freelists;
|
||||||
if main_relo_freelists <> nil then
|
if heap_lock_use > 0 then
|
||||||
begin
|
begin
|
||||||
entercriticalsection(heap_lock);
|
entercriticalsection(heap_lock);
|
||||||
finish_waitfixedlist(loc_freelists);
|
finish_waitfixedlist(loc_freelists);
|
||||||
@ -1453,11 +1464,9 @@ begin
|
|||||||
end;
|
end;
|
||||||
loc_freelists^.oslist := nil;
|
loc_freelists^.oslist := nil;
|
||||||
loc_freelists^.oscount := 0;
|
loc_freelists^.oscount := 0;
|
||||||
if main_relo_freelists <> nil then
|
if heap_lock_use > 0 then
|
||||||
begin
|
begin
|
||||||
{$endif HAS_SYSOSFREE}
|
{$endif HAS_SYSOSFREE}
|
||||||
if main_relo_freelists <> loc_freelists then
|
|
||||||
begin
|
|
||||||
poc := modify_freelists(loc_freelists, @orphaned_freelists);
|
poc := modify_freelists(loc_freelists, @orphaned_freelists);
|
||||||
if assigned(poc) then
|
if assigned(poc) then
|
||||||
begin
|
begin
|
||||||
@ -1466,9 +1475,10 @@ begin
|
|||||||
orphaned_freelists.oslist_all^.prev_any := poc;
|
orphaned_freelists.oslist_all^.prev_any := poc;
|
||||||
orphaned_freelists.oslist_all := loc_freelists^.oslist_all;
|
orphaned_freelists.oslist_all := loc_freelists^.oslist_all;
|
||||||
end;
|
end;
|
||||||
end;
|
dec(heap_lock_use);
|
||||||
|
last_thread := heap_lock_use = 0;
|
||||||
leavecriticalsection(heap_lock);
|
leavecriticalsection(heap_lock);
|
||||||
if main_relo_freelists = loc_freelists then
|
if last_thread then
|
||||||
donecriticalsection(heap_lock);
|
donecriticalsection(heap_lock);
|
||||||
end;
|
end;
|
||||||
{$ifdef SHOW_MEM_USAGE}
|
{$ifdef SHOW_MEM_USAGE}
|
||||||
|
Loading…
Reference in New Issue
Block a user