Changeset 166 for MicroThreading


Ignore:
Timestamp:
Feb 9, 2011, 1:35:28 PM (13 years ago)
Author:
george
Message:
  • Modified: Sync functions now not accept main thread context. Instead MainScheduler.AddMethod have to by used.
Location:
MicroThreading
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • MicroThreading/Demo/Demo.lpi

    r164 r166  
    5959        <ResourceBaseClass Value="Form"/>
    6060        <UnitName Value="UMainForm"/>
    61         <IsVisibleTab Value="True"/>
    6261        <EditorIndex Value="9"/>
    6362        <WindowIndex Value="0"/>
    64         <TopLine Value="332"/>
    65         <CursorPos X="23" Y="342"/>
     63        <TopLine Value="393"/>
     64        <CursorPos X="29" Y="406"/>
    6665        <UsageCount Value="270"/>
    6766        <Loaded Value="True"/>
     
    7170        <Filename Value="../UMicroThreading.pas"/>
    7271        <UnitName Value="UMicroThreading"/>
     72        <IsVisibleTab Value="True"/>
    7373        <EditorIndex Value="0"/>
    7474        <WindowIndex Value="0"/>
    75         <TopLine Value="986"/>
    76         <CursorPos X="19" Y="1000"/>
     75        <TopLine Value="914"/>
     76        <CursorPos X="11" Y="928"/>
    7777        <UsageCount Value="136"/>
    7878        <Loaded Value="True"/>
     
    130130        <TopLine Value="25"/>
    131131        <CursorPos X="41" Y="39"/>
    132         <UsageCount Value="37"/>
     132        <UsageCount Value="38"/>
    133133        <Loaded Value="True"/>
    134134      </Unit9>
     
    142142        <TopLine Value="53"/>
    143143        <CursorPos X="61" Y="61"/>
    144         <UsageCount Value="23"/>
     144        <UsageCount Value="24"/>
    145145        <Loaded Value="True"/>
    146146        <LoadedDesigner Value="True"/>
     
    245245        <TopLine Value="35"/>
    246246        <CursorPos X="18" Y="45"/>
    247         <UsageCount Value="12"/>
     247        <UsageCount Value="13"/>
    248248        <Loaded Value="True"/>
    249249      </Unit24>
     
    254254        <TopLine Value="548"/>
    255255        <CursorPos X="1" Y="561"/>
    256         <UsageCount Value="11"/>
     256        <UsageCount Value="12"/>
    257257        <Loaded Value="True"/>
    258258      </Unit25>
     
    263263        <TopLine Value="798"/>
    264264        <CursorPos X="1" Y="821"/>
    265         <UsageCount Value="11"/>
     265        <UsageCount Value="12"/>
    266266        <Loaded Value="True"/>
    267267      </Unit26>
     
    272272        <TopLine Value="65"/>
    273273        <CursorPos X="29" Y="75"/>
    274         <UsageCount Value="11"/>
     274        <UsageCount Value="12"/>
    275275        <Loaded Value="True"/>
    276276      </Unit27>
     
    282282        <TopLine Value="1398"/>
    283283        <CursorPos X="15" Y="1309"/>
    284         <UsageCount Value="10"/>
     284        <UsageCount Value="11"/>
    285285        <Loaded Value="True"/>
    286286      </Unit28>
     
    291291        <TopLine Value="2161"/>
    292292        <CursorPos X="33" Y="2161"/>
    293         <UsageCount Value="10"/>
     293        <UsageCount Value="11"/>
    294294        <Loaded Value="True"/>
    295295      </Unit29>
     
    297297    <JumpHistory Count="30" HistoryIndex="29">
    298298      <Position1>
    299         <Filename Value="UMainForm.pas"/>
    300         <Caret Line="374" Column="21" TopLine="368"/>
     299        <Filename Value="../UMicroThreading.pas"/>
     300        <Caret Line="939" Column="1" TopLine="932"/>
    301301      </Position1>
    302302      <Position2>
    303         <Filename Value="UMainForm.pas"/>
    304         <Caret Line="373" Column="21" TopLine="367"/>
     303        <Filename Value="../UMicroThreading.pas"/>
     304        <Caret Line="940" Column="1" TopLine="932"/>
    305305      </Position2>
    306306      <Position3>
    307         <Filename Value="UMainForm.pas"/>
    308         <Caret Line="372" Column="21" TopLine="366"/>
     307        <Filename Value="../UMicroThreading.pas"/>
     308        <Caret Line="941" Column="1" TopLine="932"/>
    309309      </Position3>
    310310      <Position4>
    311         <Filename Value="../UMicroThreadList.pas"/>
    312         <Caret Line="94" Column="84" TopLine="83"/>
     311        <Filename Value="../UMicroThreading.pas"/>
     312        <Caret Line="942" Column="1" TopLine="932"/>
    313313      </Position4>
    314314      <Position5>
    315         <Filename Value="../UMicroThreadList.pas"/>
    316         <Caret Line="17" Column="7" TopLine="4"/>
     315        <Filename Value="../UMicroThreading.pas"/>
     316        <Caret Line="944" Column="1" TopLine="932"/>
    317317      </Position5>
    318318      <Position6>
    319         <Filename Value="../UMicroThreadList.pas"/>
    320         <Caret Line="15" Column="38" TopLine="7"/>
     319        <Filename Value="../UMicroThreading.pas"/>
     320        <Caret Line="946" Column="1" TopLine="932"/>
    321321      </Position6>
    322322      <Position7>
    323         <Filename Value="../UMicroThreadList.pas"/>
    324         <Caret Line="17" Column="12" TopLine="4"/>
     323        <Filename Value="../UMicroThreading.pas"/>
     324        <Caret Line="937" Column="1" TopLine="932"/>
    325325      </Position7>
    326326      <Position8>
    327         <Filename Value="../UMicroThreadList.pas"/>
    328         <Caret Line="18" Column="12" TopLine="4"/>
     327        <Filename Value="../UMicroThreading.pas"/>
     328        <Caret Line="938" Column="1" TopLine="932"/>
    329329      </Position8>
    330330      <Position9>
    331         <Filename Value="../UMicroThreadList.pas"/>
    332         <Caret Line="19" Column="12" TopLine="4"/>
     331        <Filename Value="../UMicroThreading.pas"/>
     332        <Caret Line="846" Column="1" TopLine="833"/>
    333333      </Position9>
    334334      <Position10>
    335         <Filename Value="../UMicroThreadList.pas"/>
    336         <Caret Line="20" Column="12" TopLine="4"/>
     335        <Filename Value="../UMicroThreading.pas"/>
     336        <Caret Line="859" Column="1" TopLine="837"/>
    337337      </Position10>
    338338      <Position11>
    339         <Filename Value="../UMicroThreadList.pas"/>
    340         <Caret Line="21" Column="12" TopLine="4"/>
     339        <Filename Value="../UMicroThreading.pas"/>
     340        <Caret Line="847" Column="1" TopLine="837"/>
    341341      </Position11>
    342342      <Position12>
    343         <Filename Value="../UMicroThreadList.pas"/>
    344         <Caret Line="22" Column="12" TopLine="4"/>
     343        <Filename Value="../UMicroThreading.pas"/>
     344        <Caret Line="848" Column="1" TopLine="837"/>
    345345      </Position12>
    346346      <Position13>
    347         <Filename Value="UMainForm.pas"/>
    348         <Caret Line="372" Column="21" TopLine="26"/>
     347        <Filename Value="../UMicroThreading.pas"/>
     348        <Caret Line="849" Column="1" TopLine="837"/>
    349349      </Position13>
    350350      <Position14>
    351         <Filename Value="../UMicroThreadList.pas"/>
    352         <Caret Line="23" Column="12" TopLine="13"/>
     351        <Filename Value="../UMicroThreading.pas"/>
     352        <Caret Line="850" Column="1" TopLine="837"/>
    353353      </Position14>
    354354      <Position15>
    355         <Filename Value="../UMicroThreadList.pas"/>
    356         <Caret Line="68" Column="3" TopLine="53"/>
     355        <Filename Value="../UMicroThreading.pas"/>
     356        <Caret Line="851" Column="1" TopLine="837"/>
    357357      </Position15>
    358358      <Position16>
    359         <Filename Value="../UMicroThreadList.pas"/>
    360         <Caret Line="69" Column="1" TopLine="53"/>
     359        <Filename Value="../UMicroThreading.pas"/>
     360        <Caret Line="852" Column="1" TopLine="837"/>
    361361      </Position16>
    362362      <Position17>
    363         <Filename Value="UMainForm.pas"/>
    364         <Caret Line="85" Column="15" TopLine="69"/>
     363        <Filename Value="../UMicroThreading.pas"/>
     364        <Caret Line="853" Column="1" TopLine="837"/>
    365365      </Position17>
    366366      <Position18>
    367         <Filename Value="../UMicroThreadList.pas"/>
    368         <Caret Line="9" Column="43" TopLine="1"/>
     367        <Filename Value="../UMicroThreading.pas"/>
     368        <Caret Line="854" Column="1" TopLine="837"/>
    369369      </Position18>
    370370      <Position19>
    371         <Filename Value="../UMicroThreadList.pas"/>
    372         <Caret Line="72" Column="1" TopLine="53"/>
     371        <Filename Value="../UMicroThreading.pas"/>
     372        <Caret Line="857" Column="1" TopLine="837"/>
    373373      </Position19>
    374374      <Position20>
    375375        <Filename Value="../UMicroThreading.pas"/>
    376         <Caret Line="1006" Column="18" TopLine="991"/>
     376        <Caret Line="858" Column="1" TopLine="837"/>
    377377      </Position20>
    378378      <Position21>
    379379        <Filename Value="../UMicroThreading.pas"/>
    380         <Caret Line="1010" Column="26" TopLine="991"/>
     380        <Caret Line="859" Column="1" TopLine="837"/>
    381381      </Position21>
    382382      <Position22>
    383383        <Filename Value="../UMicroThreading.pas"/>
    384         <Caret Line="1009" Column="22" TopLine="991"/>
     384        <Caret Line="939" Column="1" TopLine="926"/>
    385385      </Position22>
    386386      <Position23>
    387387        <Filename Value="../UMicroThreading.pas"/>
    388         <Caret Line="1004" Column="43" TopLine="991"/>
     388        <Caret Line="940" Column="1" TopLine="926"/>
    389389      </Position23>
    390390      <Position24>
    391         <Filename Value="UMainForm.pas"/>
    392         <Caret Line="337" Column="23" TopLine="327"/>
     391        <Filename Value="../UMicroThreading.pas"/>
     392        <Caret Line="941" Column="1" TopLine="926"/>
    393393      </Position24>
    394394      <Position25>
    395         <Filename Value="UMainForm.pas"/>
    396         <Caret Line="338" Column="23" TopLine="328"/>
     395        <Filename Value="../UMicroThreading.pas"/>
     396        <Caret Line="942" Column="1" TopLine="926"/>
    397397      </Position25>
    398398      <Position26>
    399         <Filename Value="UMainForm.pas"/>
    400         <Caret Line="339" Column="23" TopLine="329"/>
     399        <Filename Value="../UMicroThreading.pas"/>
     400        <Caret Line="938" Column="45" TopLine="926"/>
    401401      </Position26>
    402402      <Position27>
    403         <Filename Value="UMainForm.pas"/>
    404         <Caret Line="338" Column="23" TopLine="328"/>
     403        <Filename Value="../UMicroThreading.pas"/>
     404        <Caret Line="940" Column="1" TopLine="914"/>
    405405      </Position27>
    406406      <Position28>
    407         <Filename Value="UMainForm.pas"/>
    408         <Caret Line="339" Column="23" TopLine="329"/>
     407        <Filename Value="../UMicroThreading.pas"/>
     408        <Caret Line="901" Column="32" TopLine="888"/>
    409409      </Position28>
    410410      <Position29>
    411         <Filename Value="UMainForm.pas"/>
    412         <Caret Line="340" Column="23" TopLine="330"/>
     411        <Filename Value="../UMicroThreading.pas"/>
     412        <Caret Line="236" Column="43" TopLine="236"/>
    413413      </Position29>
    414414      <Position30>
    415         <Filename Value="UMainForm.pas"/>
    416         <Caret Line="341" Column="23" TopLine="331"/>
     415        <Filename Value="../UMicroThreading.pas"/>
     416        <Caret Line="926" Column="22" TopLine="913"/>
    417417      </Position30>
    418418    </JumpHistory>
     
    455455  </CompilerOptions>
    456456  <Debugging>
    457     <BreakPoints Count="3">
    458       <Item1>
    459         <Source Value="../UMicroThreading.pas"/>
    460         <Line Value="280"/>
    461       </Item1>
    462       <Item2>
    463         <Source Value="../../../../Programy/Lazarus/0.9.31_2.4.3/fpc/2.4.3/source/rtl/win/sysutils.pp"/>
    464         <Line Value="1036"/>
    465       </Item2>
    466       <Item3>
    467         <Source Value="../UMicroThreading.pas"/>
    468         <Line Value="321"/>
    469       </Item3>
    470     </BreakPoints>
    471457    <Watches Count="2">
    472458      <Item1>
  • MicroThreading/Demo/UMainForm.lfm

    r164 r166  
    1717    Top = 8
    1818    Width = 802
    19     ActivePage = TabSheet2
     19    ActivePage = TabSheet1
    2020    Anchors = [akTop, akLeft, akRight, akBottom]
    21     TabIndex = 0
     21    TabIndex = 1
    2222    TabOrder = 0
    2323    object TabSheet2: TTabSheet
     
    107107    object TabSheet1: TTabSheet
    108108      Caption = 'Job control'
    109       ClientHeight = 493
     109      ClientHeight = 474
    110110      ClientWidth = 794
    111111      object ButtonAddWorkers: TButton
     
    113113        Height = 25
    114114        Top = 7
    115         Width = 104
     115        Width = 120
    116116        Caption = 'Add workers'
    117117        OnClick = ButtonAddWorkersClick
     
    128128      end
    129129      object Label4: TLabel
    130         Left = 124
     130        Left = 140
    131131        Height = 14
    132132        Top = 14
     
    148148      object Memo1: TMemo
    149149        Left = 316
    150         Height = 244
     150        Height = 225
    151151        Top = 14
    152152        Width = 294
     
    165165      end
    166166      object Label12: TLabel
    167         Left = 123
     167        Left = 140
    168168        Height = 14
    169169        Top = 38
     
    299299          ParentColor = False
    300300        end
     301      end
     302      object Button6: TButton
     303        Left = 9
     304        Height = 25
     305        Top = 38
     306        Width = 121
     307        Caption = 'Add method workers'
     308        OnClick = Button6Click
     309        TabOrder = 7
    301310      end
    302311    end
  • MicroThreading/Demo/UMainForm.pas

    r164 r166  
    3333    Button4: TButton;
    3434    Button5: TButton;
     35    Button6: TButton;
    3536    ButtonAddWorkers: TButton;
    3637    ButtonClearMicroThreads: TButton;
     
    7778    procedure Button4Click(Sender: TObject);
    7879    procedure Button5Click(Sender: TObject);
     80    procedure Button6Click(Sender: TObject);
    7981    procedure ButtonSchedulerStartStopClick(Sender: TObject);
    8082    procedure Button2Click(Sender: TObject);
     
    105107    procedure ShowException(Sender: TObject; E: Exception);
    106108    procedure DoShowException;
     109    procedure MethodWorker;
    107110  public
    108111    DoWriteToMemo: Boolean;
     
    171174begin
    172175  RaiseException := True;
     176end;
     177
     178procedure TMainForm.Button6Click(Sender: TObject);
     179var
     180  I: Integer;
     181begin
     182  //Scheduler.FMicroThreads.Clear;
     183  for I := 0 to SpinEdit1.Value - 1 do begin
     184    MainScheduler.AddMethod(MethodWorker, False);
     185  end;
    173186end;
    174187
     
    363376  ShowMessage('Exception "' + LastException.Message + '" in class "' +
    364377    LastExceptionSender.ClassName + '"')
     378end;
     379
     380procedure TMainForm.MethodWorker;
     381var
     382  I: Integer;
     383  Q: Integer;
     384begin
     385  for I := 0 to MainForm.Iterations - 1 do begin
     386    Q := 0;
     387    while Q < 100000 do Inc(Q);
     388    if MainForm.DoWriteToMemo then
     389      MainForm.Memo1.Lines.Add(IntToStr(GetCurrentMicroThread.Id) + ': ' + IntToStr(Trunc(GetCurrentMicroThread.Completion * 100)) + ' %');
     390    if MainForm.DoWaitForEvent then MainForm.Event.WaitFor(MainForm.WaitForEventDuration * OneMillisecond);
     391    if MainForm.DoSleep then MTSleep(MainForm.SleepDuration * OneMillisecond);
     392    if MainForm.RaiseException then begin
     393      MainForm.RaiseException := False;
     394      raise Exception.Create('Exception from microthread');
     395    end;
     396    if MainForm.DoCriticalSection then begin
     397      try
     398        MainForm.Lock.Acquire;
     399        MTSleep(MainForm.CriticalSectionSleepDuration * OneMillisecond);
     400      finally
     401        MainForm.Lock.Release;
     402      end;
     403    end;
     404    //WorkerSubRoutine;
     405    GetCurrentMicroThread.Completion := I / MainForm.Iterations;
     406    GetCurrentMicroThread.Yield;
     407  end;
    365408end;
    366409
  • MicroThreading/UMicroThreading.pas

    r164 r166  
    3232  SManagerReferenceLost = 'Reference to manager lost';
    3333  SCantDetermineThreadID = 'Can''t determine thread for id %d';
    34   SNotInThread = 'Not in thread';
    35   SReleaseNotAcquiredLock = 'Release not acquired lock';
     34  SNotInMicroThread = 'Not in microthread';
     35  SReleaseNotAcquiredLock = 'Release on not acquired lock';
     36  SMethodNotAssigned = 'Method for microthread not assigned';
    3637
    3738
    3839type
     40  EMicroThreadError = class(Exception);
     41
    3942  TMicroThread = class;
    4043  TMicroThreadScheduler = class;
     
    4346  TMicroThreadState = (tsNone, tsWaiting, tsRunning, tsBlocked, tsSuspended);
    4447  TMicroThreadBlockState = (tbsNone, tbsSleeping, tbsWaitFor, tbsTerminating,
    45     tbsTerminated);
     48    tbsTerminated, tbsCriticalSection);
    4649
    4750  { TMicroThreadCriticalSection }
    4851
    4952  TMicroThreadCriticalSection = class
     53  private
     54    FMicroThreads: TObjectList;
    5055    Lock: TCriticalSection;
    51     Counter: Integer;
     56    FCounter: Integer;
     57  public
    5258    procedure Acquire;
    5359    procedure Release;
     
    111117    procedure Yield;
    112118    procedure MTSleep(Duration: TDateTime); // No conflicting name to global Sleep procedure
     119    procedure WaitForCriticalSection(CriticalSection: TMicroThreadCriticalSection);
    113120    function WaitForEvent(Event: TMicroThreadEvent; Duration: TDateTime): TWaitResult;
    114121    procedure WaitFor;
     
    141148
    142149  TMicroThreadSimple = class(TMicroThread)
    143     Method: TMicroThreadMethod;
     150    Method: TProcedureOfObject;
    144151    procedure Execute; override;
    145152  end;
     
    228235    BurstCount: Integer;
    229236    function Add(MicroThread: TMicroThread): Integer;
    230     function AddMethod(Method: TMicroThreadMethod): Integer;
     237    function AddMethod(Method: TProcedureOfObject; WaitForFinish: Boolean = False): Integer;
    231238    procedure Remove(MicroThread: TMicroThread; Free: Boolean = True);
    232239    constructor Create;
     
    263270    'Running', 'Blocked', 'Suspended');
    264271  MicroThreadBlockStateText: array[TMicroThreadBlockState] of string = ('None',
    265     'Sleeping', 'WaitFor', 'Terminating', 'Terminated');
     272    'Sleeping', 'WaitFor', 'Terminating', 'Terminated', 'CriticalSection');
    266273  MicroThreadThreadStateText: array[TMicroThreadThreadState] of string = (
    267274    'Ready', 'Running', 'Terminated');
     
    294301begin
    295302  MT := GetCurrentMicroThread;
    296   if Assigned(MT) then Result := MT.Id else Result := -1;
     303  if Assigned(MT) then Result := MT.Id
     304    else Result := -1;
    297305end;
    298306
     
    322330  MT := GetCurrentMicroThread;
    323331  if Assigned(MT) then MT.MTSleep(Duration)
    324     else Sleep(Trunc(Duration / OneMillisecond));
     332    else raise EMicroThreadError.Create(SNotInMicroThread);
    325333end;
    326334
     
    332340    Thread := TThreadEx.CurrentThread;
    333341    if Assigned(Thread) then TThread.Synchronize(Thread, Method)
    334       else raise Exception.Create(Format(SCantDetermineThreadID, [GetCurrentThreadId]));
     342      else raise EMicroThreadError.Create(Format(SCantDetermineThreadID, [GetCurrentThreadId]));
    335343  end else Method;
    336344end;
     
    342350  MT := GetCurrentMicroThread;
    343351  if Assigned(MT) then Result := MT.WaitForEvent(Event, Duration)
    344     else begin
    345       while not Event.Signaled do begin
    346         Sleep(1);
    347         Application.ProcessMessages;
    348       end;
    349       //raise Exception.Create(SNotInThread);
    350 //    else Result := Event.WaitFor(Trunc(Duration / OneMillisecond));
    351     end;
     352    else raise EMicroThreadError.Create(SNotInMicroThread);
    352353end;
    353354
     
    374375
    375376procedure TMicroThreadCriticalSection.Acquire;
    376 begin
    377   try
     377var
     378  MT: TMicroThread;
     379  Event: TMicroThreadEvent;
     380begin
     381  MT := GetCurrentMicroThread;
     382  if Assigned(MT) then MT.WaitForCriticalSection(Self)
     383    else raise EMicroThreadError.Create(SNotInMicroThread);
     384end;
     385
     386procedure TMicroThreadCriticalSection.Release;
     387begin
     388  try
     389    MainScheduler.FMicroThreadsLock.Acquire;
    378390    Lock.Acquire;
    379     while Counter > 0 do begin
    380       try
    381         Lock.Release;
    382         MTSleep(1 * OneMillisecond);
    383       finally
    384         Lock.Acquire;
    385       end;
    386     end;
    387     Inc(Counter);
     391    Dec(FCounter);
     392    if FMicroThreads.Count > 0 then begin
     393      // Release one waiting micro thread and lower counter
     394      TMicroThread(FMicroThreads[0]).FState := tsWaiting;
     395      FMicroThreads.Delete(0);
     396    end;
    388397  finally
    389398    Lock.Release;
    390   end;
    391 end;
    392 
    393 procedure TMicroThreadCriticalSection.Release;
    394 begin
    395   try
     399    MainScheduler.FMicroThreadsLock.Release;
     400  end;
     401end;
     402
     403constructor TMicroThreadCriticalSection.Create;
     404begin
     405  Lock := TCriticalSection.Create;
     406  FMicroThreads := TObjectList.Create;
     407  FMicroThreads.OwnsObjects := False;
     408end;
     409
     410destructor TMicroThreadCriticalSection.Destroy;
     411begin
     412  try
     413    MainScheduler.FMicroThreadsLock.Acquire;
    396414    Lock.Acquire;
    397     if Counter > 0 then Dec(Counter)
    398       else raise Exception.Create(SReleaseNotAcquiredLock);
     415
     416    while FMicroThreads.Count > 0 do begin
     417      // Release one waiting micro thread and lower counter
     418      TMicroThread(FMicroThreads[0]).FState := tsWaiting;
     419      FMicroThreads.Delete(0);
     420    end;
    399421  finally
    400422    Lock.Release;
    401   end;
    402 end;
    403 
    404 constructor TMicroThreadCriticalSection.Create;
    405 begin
    406   Lock := TCriticalSection.Create;
    407 end;
    408 
    409 destructor TMicroThreadCriticalSection.Destroy;
    410 begin
    411   Acquire;
     423    MainScheduler.FMicroThreadsLock.Release;
     424  end;
     425  FMicroThreads.Free;
    412426  Lock.Free;
    413427  inherited Destroy;
     
    456470  MT := GetCurrentMicroThread;
    457471  if Assigned(MT) then Result := MT.WaitForEvent(Self, Duration)
    458     else Result := wrSignaled;
     472    else raise EMicroThreadError.Create(SNotInMicroThread);
    459473end;
    460474
     
    689703begin
    690704  inherited Execute;
    691   Method(Self);
     705  if Assigned(Method) then Method
     706    else raise EMicroThreadError.Create(SMethodNotAssigned);
    692707end;
    693708
     
    700715  except
    701716    on E: Exception do
    702       if Assigned(ExceptionHandler) then ExceptionHandler(Self, E);
     717      if Assigned(ExceptionHandler) then
     718        if GetCurrentThreadId = MainThreadID then ExceptionHandler(Self, E)
     719          else ExceptionHandler(TThreadEx.CurrentThread, E);
    703720  end;
    704721  asm
     
    745762procedure TMicroThread.Yield;
    746763begin
    747   if not Assigned(FManager) then
    748     raise Exception.Create(SManagerReferenceLost);
     764//  if not Assigned(FManager) then
     765//    raise EMicroThreadError.Create(SManagerReferenceLost);
    749766  if FStatePending = tsNone then
    750767    FStatePending := tsWaiting;
     
    774791  FStatePending := tsBlocked;
    775792  Yield;
     793end;
     794
     795procedure TMicroThread.WaitForCriticalSection(
     796  CriticalSection: TMicroThreadCriticalSection);
     797begin
     798  try
     799    CriticalSection.Lock.Acquire;
     800    Inc(CriticalSection.FCounter);
     801    if CriticalSection.FCounter > 1 then begin
     802      CriticalSection.FMicroThreads.Add(Self);
     803      FBlockState := tbsCriticalSection;
     804      FStatePending := tsBlocked;
     805      try
     806        CriticalSection.Lock.Release;
     807        Yield;
     808      finally
     809        CriticalSection.Lock.Acquire;
     810      end;
     811    end;
     812  finally
     813    CriticalSection.Lock.Release;
     814  end;
    776815end;
    777816
     
    862901function TMicroThreadScheduler.Add(MicroThread: TMicroThread): Integer;
    863902begin
    864   Inc(FLastId);
    865   MicroThread.FScheduler := Self;
    866   MicroThread.FId := FLastId;
    867903  try
    868904    FMicroThreadsLock.Acquire;
     905    Inc(FLastId);
     906    MicroThread.FScheduler := Self;
     907    MicroThread.FId := FLastId;
    869908    Result := FMicroThreads.Add(MicroThread);
    870909  finally
     
    873912end;
    874913
    875 function TMicroThreadScheduler.AddMethod(Method: TMicroThreadMethod): Integer;
     914function TMicroThreadScheduler.AddMethod(Method: TProcedureOfObject; WaitForFinish: Boolean): Integer;
    876915var
    877916  NewMicroThread: TMicroThreadSimple;
    878 begin
    879   NewMicroThread := TMicroThreadSimple.Create(False);
    880   NewMicroThread.Method := Method;
    881   NewMicroThread.FScheduler := Self;
    882   Result := Add(NewMicroThread);
     917  CurrentMT: TMicroThread;
     918begin
     919  try
     920    NewMicroThread := TMicroThreadSimple.Create(False);
     921    NewMicroThread.Method := Method;
     922    NewMicroThread.FScheduler := Self;
     923    NewMicroThread.FreeOnTerminate := not WaitForFinish;
     924    if WaitForFinish then begin
     925      CurrentMT := GetCurrentMicroThread;
     926      while not ((NewMicroThread.FState = tsBlocked) and
     927      (NewMicroThread.FBlockState = tbsTerminated)) do begin
     928        try
     929          FMicroThreadsLock.Release;
     930          if Assigned(CurrentMT) then CurrentMT.MTSleep(1 * OneMillisecond)
     931          else begin
     932            Sleep(1);
     933            Application.ProcessMessages;
     934          end;
     935        finally
     936          FMicroThreadsLock.Acquire;
     937        end;
     938      end;
     939    end;
     940  finally
     941    if WaitForFinish then NewMicroThread.Free;
     942  end;
    883943end;
    884944
     
    10661126    end;
    10671127    if I < FMicroThreads.Count then begin
    1068       if Assigned(Manager.FCurrentMicroThread) then
    1069         raise Exception.Create(SManagerMicroThreadRunning);
     1128//      if Assigned(Manager.FCurrentMicroThread) then
     1129//        raise EMicroThreadError.Create(SManagerMicroThreadRunning);
    10701130      Selected := TMicroThread(FMicroThreads[FRoundRobinIndex]);
    10711131      Selected.FState := tsRunning;
     
    10801140procedure TMicroThreadScheduler.ReleaseMicroThread(MicroThread: TMicroThread);
    10811141begin
    1082   if not Assigned(MicroThread) then
    1083     raise Exception.Create(SNilThreadReference);
     1142//  if not Assigned(MicroThread) then
     1143//    raise EMicroThreadError.Create(SNilThreadReference);
    10841144  try
    10851145    FMicroThreadsLock.Acquire;
Note: See TracChangeset for help on using the changeset viewer.