Changeset 159 for MicroThreading/UMicroThreading.pas
- Timestamp:
- Jan 31, 2011, 2:16:21 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
MicroThreading/UMicroThreading.pas
r158 r159 18 18 cthreads, 19 19 {$ENDIF}{$ENDIF} 20 Classes, ExtCtrls, SysUtils, Contnrs, SyncObjs, DateUtils, Dialogs, Forms, UPlatform; 20 Classes, ExtCtrls, SysUtils, Contnrs, SyncObjs, DateUtils, Dialogs, Forms, 21 UPlatform, UMicroThreadList; 21 22 22 23 const 23 DefaultStackSize = $4000 ;24 DefaultStackSize = $40000; 24 25 25 26 type … … 191 192 procedure UpdateThreadPoolSize; 192 193 procedure MainThreadStart(Sender: TObject); 194 procedure MainThreadTick(Data: PtrInt); 193 195 public 194 196 function Add(MicroThread: TMicroThread): Integer; 195 197 function AddMethod(Method: TMicroThreadMethod): Integer; 196 procedure Remove(MicroThread: TMicroThread); 198 function FindCurrentThread: TThread; 199 procedure Remove(MicroThread: TMicroThread; Free: Boolean = True); 197 200 constructor Create; 198 201 destructor Destroy; override; … … 210 213 end; 211 214 215 TMicroThreadList = class(TComponent) 216 private 217 public 218 Form: TMicroThreadListForm; 219 constructor Create(AOwner: TComponent); 220 end; 221 222 TMicroThreadExceptionEvent = procedure(Sender: TObject; E: Exception) of object; 223 212 224 var 213 225 MainScheduler: TMicroThreadScheduler; 226 ExceptionHandler: TMicroThreadExceptionEvent; 214 227 215 228 const … … 223 236 function GetCurrentMicroThread: TMicroThread; 224 237 procedure MTSleep(Duration: TDateTime); 238 procedure MTSynchronize(Method: TThreadMethod); 225 239 function MTWaitForEvent(Event: TMicroThreadEvent; Duration: TDateTime): TWaitResult; 226 240 procedure Log(Text: string); 241 procedure Register; 227 242 228 243 const … … 235 250 // StaticManager: TMicroThreadManager; 236 251 // StaticMicroThread: TMicroThread; 252 253 procedure Register; 254 begin 255 RegisterComponents('MicroThreading', [TMicroThreadList]); 256 end; 237 257 238 258 function GetMicroThreadId: Integer; … … 267 287 with MainScheduler do 268 288 try 269 F ThreadPoolLock.Acquire;289 FMicroThreadsLock.Acquire; 270 290 if MainThreadID = ThreadID then Result := MainThreadManager.CurrentMicroThread 271 else begin 272 I := 0; 273 while (I < FThreadPool.Count) and (TMicroThreadThread(FThreadPool[I]).ThreadID <> ThreadID) do Inc(I); 274 if I < FThreadPool.Count then Result := TMicroThreadThread(FThreadPool[I]).Manager.CurrentMicroThread 275 else Result := nil; 276 end; 277 finally 278 FThreadPoolLock.Release; 291 else Result := TMicroThreadThread(MainScheduler.FindCurrentThread).Manager.CurrentMicroThread; 292 finally 293 FMicroThreadsLock.Release; 279 294 end; 280 295 end; … … 289 304 end; 290 305 306 procedure MTSynchronize(Method: TThreadMethod); 307 var 308 Thread: TThread; 309 begin 310 if GetCurrentThreadId <> MainThreadID then begin 311 Thread := MainScheduler.FindCurrentThread; 312 if Assigned(Thread) then TThread.Synchronize(Thread, Method) 313 else raise Exception.Create('Can''t determine thread for id ' + IntToStr(GetCurrentThreadId)); 314 end else Method; 315 end; 316 291 317 function MTWaitForEvent(Event: TMicroThreadEvent; Duration: TDateTime): TWaitResult; 292 318 var … … 294 320 begin 295 321 MT := GetCurrentMicroThread; 296 if Assigned(MT) then Result := MT.WaitForEvent(Event, Duration); 322 if Assigned(MT) then Result := MT.WaitForEvent(Event, Duration) 323 else raise Exception.Create('Not in thread'); 297 324 // else Result := Event.WaitFor(Trunc(Duration / OneMillisecond)); 298 325 end; … … 316 343 end; 317 344 end; 345 346 { TMicroThreadList } 347 348 constructor TMicroThreadList.Create(AOwner: TComponent); 349 begin 350 inherited; 351 Form := TMicroThreadListForm.Create(Self); 352 end; 353 354 318 355 319 356 { TMicroThreadMethod } … … 360 397 destructor TMicroThreadEvent.Destroy; 361 398 begin 362 MainScheduler.FEvents.Delete(MainScheduler.FEvents.IndexOf(Self)); 399 try 400 MainScheduler.FEvents.OwnsObjects := False; 401 MainScheduler.FEvents.Delete(MainScheduler.FEvents.IndexOf(Self)); 402 finally 403 MainScheduler.FEvents.OwnsObjects := True; 404 end; 363 405 FMicroThreadsLock.Free; 364 406 FMicroThreads.Free; … … 441 483 // but virtual methods can be called only statically 442 484 // Then static method CallExecute is calling virtual method Execute 443 call TMicroThread.CallExecute485 call TMicroThread.CallExecute 444 486 445 487 // Restore manager stack … … 522 564 until Terminated; 523 565 except 524 on E: Exception do ;525 //ExceptionHandler(E);566 on E: Exception do 567 if Assigned(ExceptionHandler) then ExceptionHandler(Self, E); 526 568 end; 527 569 end; … … 549 591 end; 550 592 551 552 593 { TMicroThread } 553 594 554 595 procedure TMicroThread.CallExecute; 555 596 begin 556 Execute; 597 try 598 Execute; 599 except 600 on E: Exception do 601 ExceptionHandler(Self, E); 602 end; 557 603 asm 558 604 mov ecx, Self … … 631 677 end; 632 678 Yield; 679 if FBlockTime < NowPrecise then 680 Result := wrTimeout else Result := wrSignaled; 681 633 682 try 634 683 Event.FMicroThreadsLock.Acquire; … … 669 718 destructor TMicroThread.Destroy; 670 719 begin 720 MainScheduler.Remove(Self, False); 671 721 //Terminate; 672 722 //WaitFor; … … 718 768 end; 719 769 720 procedure TMicroThreadScheduler.Remove(MicroThread: TMicroThread); 770 function TMicroThreadScheduler.FindCurrentThread: TThread; 771 var 772 I: Integer; 773 begin 774 try 775 FThreadPoolLock.Acquire; 776 I := 0; 777 while (I < FThreadPool.Count) and (TMicroThreadThread(FThreadPool[I]).ThreadID <> ThreadID) do Inc(I); 778 if I < FThreadPool.Count then Result := TMicroThreadThread(FThreadPool[I]) 779 else Result := nil; 780 finally 781 FThreadPoolLock.Release; 782 end; 783 end; 784 785 procedure TMicroThreadScheduler.Remove(MicroThread: TMicroThread; 786 Free: Boolean = True); 721 787 begin 722 788 try 723 789 FMicroThreadsLock.Acquire; 790 if not Free then FMicroThreads.OwnsObjects := False; 724 791 FMicroThreads.Remove(MicroThread); 792 FMicroThreads.OwnsObjects := True; 725 793 finally 726 794 FMicroThreadsLock.Release; … … 824 892 825 893 procedure TMicroThreadScheduler.MainThreadStart(Sender: TObject); 826 var827 Executed: Integer;828 894 begin 829 895 FMainThreadStarter.Enabled := False; 830 896 FMainThreadTerminated := False; 831 repeat 832 Executed := FMainThreadManager.Execute(1); 833 Application.ProcessMessages; 834 if Executed = 0 then Sleep(1); 835 until (FState <> ssRunning) or (not FUseMainThread); 836 FMainThreadTerminated := True; 897 Application.QueueAsyncCall(MainThreadTick, 0); 898 end; 899 900 procedure TMicroThreadScheduler.MainThreadTick(Data: PtrInt); 901 var 902 Executed: Integer; 903 begin 904 Executed := FMainThreadManager.Execute(1); 905 if Executed = 0 then Sleep(1); 906 // If not terminated then queue next tick else terminate 907 if (FState = ssRunning) and FUseMainThread then 908 Application.QueueAsyncCall(MainThreadTick, 0) 909 else FMainThreadTerminated := True; 837 910 end; 838 911
Note:
See TracChangeset
for help on using the changeset viewer.