mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-10-31 11:53:42 +01:00 
			
		
		
		
	* fixed web bug #3387: if one called resume right after creating a
suspended thread, it was possible that resume was executed before
    that thread had completed its initialisation in BeginThread ->
    FInitialSuspended was set to false in resume and nevertheless a
    semafore was posted
  * second problem fixed: set FSuspended to false before waking up the
    thread, so that it doesn't get FSuspended = true right after waking
    up. This should be done atomically to be completely correct though.
			
			
This commit is contained in:
		
							parent
							
								
									d6eb620591
								
							
						
					
					
						commit
						92a2ba07ad
					
				| @ -133,7 +133,8 @@ begin | |||||||
|   try |   try | ||||||
|     if LThread.FInitialSuspended then begin |     if LThread.FInitialSuspended then begin | ||||||
|       SemaphoreWait(LThread.FSem); |       SemaphoreWait(LThread.FSem); | ||||||
|       if not LThread.FInitialSuspended then begin |       if not LThread.FSuspended then begin | ||||||
|  |         LThread.FInitialSuspended := false; | ||||||
|         WRITE_DEBUG('going into LThread.Execute'); |         WRITE_DEBUG('going into LThread.Execute'); | ||||||
|         LThread.Execute; |         LThread.Execute; | ||||||
|       end; |       end; | ||||||
| @ -231,13 +232,12 @@ procedure TThread.Resume; | |||||||
| begin | begin | ||||||
|   if (not FSuspendedExternal) then begin |   if (not FSuspendedExternal) then begin | ||||||
|     if FSuspended then begin |     if FSuspended then begin | ||||||
|       SemaphorePost(FSem); |  | ||||||
|       FInitialSuspended := false; |  | ||||||
|       FSuspended := False; |       FSuspended := False; | ||||||
|  |       SemaphorePost(FSem); | ||||||
|     end; |     end; | ||||||
|   end else begin |   end else begin | ||||||
|     ResumeThread(FHandle); |  | ||||||
|     FSuspendedExternal := false; |     FSuspendedExternal := false; | ||||||
|  |     ResumeThread(FHandle); | ||||||
|   end; |   end; | ||||||
| end; | end; | ||||||
| 
 | 
 | ||||||
| @ -287,7 +287,17 @@ end; | |||||||
| 
 | 
 | ||||||
| { | { | ||||||
|   $Log$ |   $Log$ | ||||||
|   Revision 1.5  2005-02-25 21:41:09  florian |   Revision 1.6  2005-03-01 20:38:49  jonas | ||||||
|  |     * fixed web bug 3387: if one called resume right after creating a | ||||||
|  |       suspended thread, it was possible that resume was executed before | ||||||
|  |       that thread had completed its initialisation in BeginThread -> | ||||||
|  |       FInitialSuspended was set to false in resume and nevertheless a | ||||||
|  |       semafore was posted | ||||||
|  |     * second problem fixed: set FSuspended to false before waking up the | ||||||
|  |       thread, so that it doesn't get FSuspended = true right after waking | ||||||
|  |       up. This should be done atomically to be completely correct though. | ||||||
|  | 
 | ||||||
|  |   Revision 1.5  2005/02/25 21:41:09  florian | ||||||
|     * generic tthread.synchronize |     * generic tthread.synchronize | ||||||
|     * delphi compatible wakemainthread |     * delphi compatible wakemainthread | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -414,7 +414,8 @@ begin | |||||||
|   try |   try | ||||||
|     if LThread.FInitialSuspended then begin |     if LThread.FInitialSuspended then begin | ||||||
|       SemaphoreWait(LThread.FSem); |       SemaphoreWait(LThread.FSem); | ||||||
|       if not LThread.FInitialSuspended then begin |       if not LThread.FSuspended then begin | ||||||
|  |         LThread.FInitialSuspended := false; | ||||||
|         WRITE_DEBUG('going into LThread.Execute'); |         WRITE_DEBUG('going into LThread.Execute'); | ||||||
|         LThread.Execute; |         LThread.Execute; | ||||||
|       end; |       end; | ||||||
| @ -527,21 +528,12 @@ procedure TThread.Resume; | |||||||
| begin | begin | ||||||
|   if (not FSuspendedExternal) then begin |   if (not FSuspendedExternal) then begin | ||||||
|     if FSuspended then begin |     if FSuspended then begin | ||||||
|       SemaphorePost(FSem); |  | ||||||
|       FInitialSuspended := false; |  | ||||||
|       FSuspended := False; |       FSuspended := False; | ||||||
|  |       SemaphorePost(FSem); | ||||||
|     end; |     end; | ||||||
|   end else begin |   end else begin | ||||||
| {$IFDEF LINUX} |  | ||||||
|     // see .Suspend
 |  | ||||||
|     if FPid <> GMainPID then begin |  | ||||||
|       fpkill(FPid, SIGCONT); |  | ||||||
|       FSuspended := False; |  | ||||||
|     end; |  | ||||||
| {$ELSE} |  | ||||||
|     ResumeThread(FHandle); |  | ||||||
| {$ENDIF} |  | ||||||
|     FSuspendedExternal := false; |     FSuspendedExternal := false; | ||||||
|  |     ResumeThread(FHandle); | ||||||
|   end; |   end; | ||||||
| end; | end; | ||||||
| 
 | 
 | ||||||
| @ -592,7 +584,17 @@ end; | |||||||
| 
 | 
 | ||||||
| { | { | ||||||
|   $Log$ |   $Log$ | ||||||
|   Revision 1.14  2005-02-25 21:41:09  florian |   Revision 1.15  2005-03-01 20:38:49  jonas | ||||||
|  |     * fixed web bug 3387: if one called resume right after creating a | ||||||
|  |       suspended thread, it was possible that resume was executed before | ||||||
|  |       that thread had completed its initialisation in BeginThread -> | ||||||
|  |       FInitialSuspended was set to false in resume and nevertheless a | ||||||
|  |       semafore was posted | ||||||
|  |     * second problem fixed: set FSuspended to false before waking up the | ||||||
|  |       thread, so that it doesn't get FSuspended = true right after waking | ||||||
|  |       up. This should be done atomically to be completely correct though. | ||||||
|  | 
 | ||||||
|  |   Revision 1.14  2005/02/25 21:41:09  florian | ||||||
|     * generic tthread.synchronize |     * generic tthread.synchronize | ||||||
|     * delphi compatible wakemainthread |     * delphi compatible wakemainthread | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -144,7 +144,8 @@ begin | |||||||
|   try |   try | ||||||
|     if LThread.FInitialSuspended then begin |     if LThread.FInitialSuspended then begin | ||||||
|       SemaphoreWait(LThread.FSem); |       SemaphoreWait(LThread.FSem); | ||||||
|       if not LThread.FInitialSuspended then begin |       if not LThread.FSuspended then begin | ||||||
|  |         LThread.FInitialSuspended := false; | ||||||
|         WRITE_DEBUG('going into LThread.Execute'); |         WRITE_DEBUG('going into LThread.Execute'); | ||||||
|         LThread.Execute; |         LThread.Execute; | ||||||
|       end; |       end; | ||||||
| @ -257,21 +258,20 @@ procedure TThread.Resume; | |||||||
| begin | begin | ||||||
|   if (not FSuspendedExternal) then begin |   if (not FSuspendedExternal) then begin | ||||||
|     if FSuspended then begin |     if FSuspended then begin | ||||||
|       SemaphorePost(FSem); |  | ||||||
|       FInitialSuspended := false; |  | ||||||
|       FSuspended := False; |       FSuspended := False; | ||||||
|  |       SemaphorePost(FSem); | ||||||
|     end; |     end; | ||||||
|   end else begin |   end else begin | ||||||
|  |     FSuspendedExternal := false; | ||||||
| {$IFDEF LINUX} | {$IFDEF LINUX} | ||||||
|     // see .Suspend
 |     // see .Suspend
 | ||||||
|     if FPid <> GMainPID then begin |     if FPid <> GMainPID then begin | ||||||
|       fpkill(FPid, SIGCONT); |  | ||||||
|       FSuspended := False; |       FSuspended := False; | ||||||
|  |       fpkill(FPid, SIGCONT); | ||||||
|     end; |     end; | ||||||
| {$ELSE} | {$ELSE} | ||||||
|     ResumeThread(FHandle); |     ResumeThread(FHandle); | ||||||
| {$ENDIF} | {$ENDIF} | ||||||
|     FSuspendedExternal := false; |  | ||||||
|   end; |   end; | ||||||
| end; | end; | ||||||
| 
 | 
 | ||||||
| @ -321,7 +321,17 @@ end; | |||||||
| 
 | 
 | ||||||
| { | { | ||||||
|   $Log$ |   $Log$ | ||||||
|   Revision 1.13  2005-02-25 21:41:09  florian |   Revision 1.14  2005-03-01 20:38:49  jonas | ||||||
|  |     * fixed web bug 3387: if one called resume right after creating a | ||||||
|  |       suspended thread, it was possible that resume was executed before | ||||||
|  |       that thread had completed its initialisation in BeginThread -> | ||||||
|  |       FInitialSuspended was set to false in resume and nevertheless a | ||||||
|  |       semafore was posted | ||||||
|  |     * second problem fixed: set FSuspended to false before waking up the | ||||||
|  |       thread, so that it doesn't get FSuspended = true right after waking | ||||||
|  |       up. This should be done atomically to be completely correct though. | ||||||
|  | 
 | ||||||
|  |   Revision 1.13  2005/02/25 21:41:09  florian | ||||||
|     * generic tthread.synchronize |     * generic tthread.synchronize | ||||||
|     * delphi compatible wakemainthread |     * delphi compatible wakemainthread | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -414,7 +414,8 @@ begin | |||||||
|   try |   try | ||||||
|     if LThread.FInitialSuspended then begin |     if LThread.FInitialSuspended then begin | ||||||
|       SemaphoreWait(LThread.FSem); |       SemaphoreWait(LThread.FSem); | ||||||
|       if not LThread.FInitialSuspended then begin |       if not LThread.FSuspended then begin | ||||||
|  |         LThread.FInitialSuspended := false; | ||||||
|         WRITE_DEBUG('going into LThread.Execute'); |         WRITE_DEBUG('going into LThread.Execute'); | ||||||
|         LThread.Execute; |         LThread.Execute; | ||||||
|       end; |       end; | ||||||
| @ -527,21 +528,12 @@ procedure TThread.Resume; | |||||||
| begin | begin | ||||||
|   if (not FSuspendedExternal) then begin |   if (not FSuspendedExternal) then begin | ||||||
|     if FSuspended then begin |     if FSuspended then begin | ||||||
|       SemaphorePost(FSem); |  | ||||||
|       FInitialSuspended := false; |  | ||||||
|       FSuspended := False; |       FSuspended := False; | ||||||
|  |       SemaphorePost(FSem); | ||||||
|     end; |     end; | ||||||
|   end else begin |   end else begin | ||||||
| {$IFDEF LINUX} |  | ||||||
|     // see .Suspend
 |  | ||||||
|     if FPid <> GMainPID then begin |  | ||||||
|       fpkill(FPid, SIGCONT); |  | ||||||
|       FSuspended := False; |  | ||||||
|     end; |  | ||||||
| {$ELSE} |  | ||||||
|     ResumeThread(FHandle); |  | ||||||
| {$ENDIF} |  | ||||||
|     FSuspendedExternal := false; |     FSuspendedExternal := false; | ||||||
|  |     ResumeThread(FHandle); | ||||||
|   end; |   end; | ||||||
| end; | end; | ||||||
| 
 | 
 | ||||||
| @ -592,7 +584,17 @@ end; | |||||||
| 
 | 
 | ||||||
| { | { | ||||||
|   $Log$ |   $Log$ | ||||||
|   Revision 1.4  2005-02-25 21:41:09  florian |   Revision 1.5  2005-03-01 20:38:49  jonas | ||||||
|  |     * fixed web bug 3387: if one called resume right after creating a | ||||||
|  |       suspended thread, it was possible that resume was executed before | ||||||
|  |       that thread had completed its initialisation in BeginThread -> | ||||||
|  |       FInitialSuspended was set to false in resume and nevertheless a | ||||||
|  |       semafore was posted | ||||||
|  |     * second problem fixed: set FSuspended to false before waking up the | ||||||
|  |       thread, so that it doesn't get FSuspended = true right after waking | ||||||
|  |       up. This should be done atomically to be completely correct though. | ||||||
|  | 
 | ||||||
|  |   Revision 1.4  2005/02/25 21:41:09  florian | ||||||
|     * generic tthread.synchronize |     * generic tthread.synchronize | ||||||
|     * delphi compatible wakemainthread |     * delphi compatible wakemainthread | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -414,7 +414,8 @@ begin | |||||||
|   try |   try | ||||||
|     if LThread.FInitialSuspended then begin |     if LThread.FInitialSuspended then begin | ||||||
|       SemaphoreWait(LThread.FSem); |       SemaphoreWait(LThread.FSem); | ||||||
|       if not LThread.FInitialSuspended then begin |       if not LThread.FSuspended then begin | ||||||
|  |         LThread.FInitialSuspended := false; | ||||||
|         WRITE_DEBUG('going into LThread.Execute'); |         WRITE_DEBUG('going into LThread.Execute'); | ||||||
|         LThread.Execute; |         LThread.Execute; | ||||||
|       end; |       end; | ||||||
| @ -527,21 +528,12 @@ procedure TThread.Resume; | |||||||
| begin | begin | ||||||
|   if (not FSuspendedExternal) then begin |   if (not FSuspendedExternal) then begin | ||||||
|     if FSuspended then begin |     if FSuspended then begin | ||||||
|       SemaphorePost(FSem); |  | ||||||
|       FInitialSuspended := false; |  | ||||||
|       FSuspended := False; |       FSuspended := False; | ||||||
|  |       SemaphorePost(FSem); | ||||||
|     end; |     end; | ||||||
|   end else begin |   end else begin | ||||||
| {$IFDEF LINUX} |  | ||||||
|     // see .Suspend
 |  | ||||||
|     if FPid <> GMainPID then begin |  | ||||||
|       fpkill(FPid, SIGCONT); |  | ||||||
|       FSuspended := False; |  | ||||||
|     end; |  | ||||||
| {$ELSE} |  | ||||||
|     ResumeThread(FHandle); |  | ||||||
| {$ENDIF} |  | ||||||
|     FSuspendedExternal := false; |     FSuspendedExternal := false; | ||||||
|  |     ResumeThread(FHandle); | ||||||
|   end; |   end; | ||||||
| end; | end; | ||||||
| 
 | 
 | ||||||
| @ -592,7 +584,17 @@ end; | |||||||
| 
 | 
 | ||||||
| { | { | ||||||
|   $Log$ |   $Log$ | ||||||
|   Revision 1.4  2005-02-25 21:41:09  florian |   Revision 1.5  2005-03-01 20:38:49  jonas | ||||||
|  |     * fixed web bug 3387: if one called resume right after creating a | ||||||
|  |       suspended thread, it was possible that resume was executed before | ||||||
|  |       that thread had completed its initialisation in BeginThread -> | ||||||
|  |       FInitialSuspended was set to false in resume and nevertheless a | ||||||
|  |       semafore was posted | ||||||
|  |     * second problem fixed: set FSuspended to false before waking up the | ||||||
|  |       thread, so that it doesn't get FSuspended = true right after waking | ||||||
|  |       up. This should be done atomically to be completely correct though. | ||||||
|  | 
 | ||||||
|  |   Revision 1.4  2005/02/25 21:41:09  florian | ||||||
|     * generic tthread.synchronize |     * generic tthread.synchronize | ||||||
|     * delphi compatible wakemainthread |     * delphi compatible wakemainthread | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Jonas Maebe
						Jonas Maebe