Browse Source

* proper error handling in case of thread creation failure on windows, resolves #13768, no test case due because such a test is too sensitive regarding race conditions etc. and might cause false failures

git-svn-id: trunk@13222 -
florian 16 years ago
parent
commit
88f6b8854e
2 changed files with 26 additions and 13 deletions
  1. 15 6
      rtl/win/systhrd.inc
  2. 11 7
      rtl/win/tthread.inc

+ 15 - 6
rtl/win/systhrd.inc

@@ -160,17 +160,17 @@ CONST
         { Allocate local thread vars, this must be the first thing,
           because the exception management and io depends on threadvars }
         SysAllocateThreadVars;
+
         { Copy parameter to local data }
-{$ifdef DEBUG_MT}
-        writeln('New thread started, initialising ...');
-{$endif DEBUG_MT}
         ti:=pthreadinfo(param)^;
         dispose(pthreadinfo(param));
+
         { Initialize thread }
         InitThread(ti.stklen);
+
         { Start thread function }
 {$ifdef DEBUG_MT}
-        writeln('Jumping to thread function');
+        writeln('Jumping to thread function of thread ',Win32GetCurrentThreadId);
 {$endif DEBUG_MT}
         ThreadMain:=ti.f(ti.p);
       end;
@@ -181,7 +181,7 @@ CONST
                          creationFlags : dword;var ThreadId : TThreadID) : TThreadID;
       var
         ti : pthreadinfo;
-        _threadid : DWord;
+        _threadid : TThreadID;
       begin
 {$ifdef DEBUG_MT}
         writeln('Creating new thread');
@@ -200,12 +200,21 @@ CONST
         ti^.f:=ThreadFunction;
         ti^.p:=p;
         ti^.stklen:=stacksize;
-        { call pthread_create }
 {$ifdef DEBUG_MT}
         writeln('Starting new thread');
 {$endif DEBUG_MT}
         _threadid:=ThreadID;
         SysBeginThread:=CreateThread(sa,stacksize,@ThreadMain,ti,creationflags,_threadid);
+
+        { creation failed? if yes, we dispose the parameter record }
+        if SysBeginThread=0 then
+          begin
+{$ifdef DEBUG_MT}
+            writeln('Thread creation failed');
+{$endif DEBUG_MT}
+            dispose(ti);
+          end;
+
         ThreadID:=_threadid;
       end;
 

+ 11 - 7
rtl/win/tthread.inc

@@ -22,19 +22,23 @@ begin
                          FThreadID);
   if FHandle = TThreadID(0) then
     raise EThread.create('Failed to create new thread, code:'+inttostr(getlasterror));
-  
+
   FFatalException := nil;
 end;
 
 
 destructor TThread.Destroy;
 begin
-  if not FFinished and not Suspended then
-  begin
-    Terminate;
-    WaitFor;
-  end;
-  if FHandle <> 0 then CloseHandle(FHandle);
+  if FHandle<>0 then
+    begin
+      if not FFinished and not Suspended then
+        begin
+          Terminate;
+          WaitFor;
+        end;
+      CloseHandle(FHandle);
+    end;
+
   FFatalException.Free;
   FFatalException := nil;
   inherited Destroy;