Browse Source

* fix for Mantis #34640: don't access the thread queue entry directly after it was added to the queue if it's a Queue()d entry instead of a Synchronize()d one

git-svn-id: trunk@40651 -
svenbarth 6 years ago
parent
commit
3e0da1ef1c
1 changed files with 13 additions and 2 deletions
  1. 13 2
      rtl/objpas/classes/classes.inc

+ 13 - 2
rtl/objpas/classes/classes.inc

@@ -299,6 +299,9 @@ end;
 
 
 
 
 procedure ThreadQueueAppend(aEntry: TThread.PThreadQueueEntry; aQueueIfMain: Boolean);
 procedure ThreadQueueAppend(aEntry: TThread.PThreadQueueEntry; aQueueIfMain: Boolean);
+var
+  thd: TThread;
+  issync: Boolean;
 begin
 begin
   { do we really need a synchronized call? }
   { do we really need a synchronized call? }
 {$ifdef FPC_HAS_FEATURE_THREADING}
 {$ifdef FPC_HAS_FEATURE_THREADING}
@@ -310,6 +313,14 @@ begin
       Dispose(aEntry);
       Dispose(aEntry);
 {$ifdef FPC_HAS_FEATURE_THREADING}
 {$ifdef FPC_HAS_FEATURE_THREADING}
   end else begin
   end else begin
+    { store thread and whether we're dealing with a synchronized event; the
+      event record itself might already be freed after the ThreadQueueLock is
+      released (in case of a Queue() call; for a Synchronize() call the record
+      will stay valid, thus accessing SyncEvent later on (if issync is true) is
+      okay) }
+    thd := aEntry^.Thread;
+    issync := Assigned(aEntry^.SyncEvent);
+
     System.EnterCriticalSection(ThreadQueueLock);
     System.EnterCriticalSection(ThreadQueueLock);
     try
     try
       { add the entry to the thread queue }
       { add the entry to the thread queue }
@@ -325,10 +336,10 @@ begin
     { ensure that the main thread knows that something awaits }
     { ensure that the main thread knows that something awaits }
     RtlEventSetEvent(SynchronizeTimeoutEvent);
     RtlEventSetEvent(SynchronizeTimeoutEvent);
     if assigned(WakeMainThread) then
     if assigned(WakeMainThread) then
-      WakeMainThread(aEntry^.Thread);
+      WakeMainThread(thd);
 
 
     { is this a Synchronize or Queue entry? }
     { is this a Synchronize or Queue entry? }
-    if Assigned(aEntry^.SyncEvent) then begin
+    if issync then begin
       RtlEventWaitFor(aEntry^.SyncEvent);
       RtlEventWaitFor(aEntry^.SyncEvent);
       if Assigned(aEntry^.Exception) then
       if Assigned(aEntry^.Exception) then
         raise aEntry^.Exception;
         raise aEntry^.Exception;