Ignore:
Timestamp:
Aug 20, 2008, 3:37:44 AM (16 years ago)
Author:
イグトランス (egtra)
Message:

ThreadPoolの実装、WaitHandle.WaitAny/WaitAllのまともな実装、ほか。

Location:
trunk/ab5.0/ablib/src/Classes/System/Threading
Files:
1 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/ab5.0/ablib/src/Classes/System/Threading/EventWaitHandle.ab

    r494 r599  
    1111Class EventWaitHandle
    1212    Inherits System.Threading.WaitHandle
    13 
     13Private
     14    Sub EventWaitHandle()
     15    End Sub
    1416Public
    1517    Sub EventWaitHandle (initialState As Boolean, mode As EventResetMode)
     
    5456    既存の名前付き同期イベントを開きます。
    5557    */
    56     Static Function OpenExisting(name As String) As WaitHandle
    57         This.Handle(OpenEvent(EVENT_ALL_ACCESS,FALSE,ToTCStr(name)))
     58    Static Function OpenExisting(name As String) As EventWaitHandle
     59        If ActiveBasic.IsNothing(name) Then
     60            Throw New ArgumentNullException("name")
     61        Else If name.Length = 0 Then
     62            Throw New ArgumentException("name")
     63        End If
     64        OpenExisting = New EventWaitHandle
     65        Dim h = OpenEvent(EVENT_ALL_ACCESS, FALSE, ToTCStr(name))
     66        If h = 0 Then
     67            IO.Detail.ThrowWinLastErrorIOException("OpenEvent failed.")
     68        End If
     69        OpenExisting.Handle = h
    5870    End Function
    5971
     
    95107WaitHandle から継承
    96108Handle
    97 SafeWaitHandle 
     109SafeWaitHandle
    98110*/
    99111
  • trunk/ab5.0/ablib/src/Classes/System/Threading/Exception.ab

    r566 r599  
    1 NameSpace System
    2 NameSpace Threading
     1Namespace System
     2Namespace Threading
    33
    44Class AbandonedMutexException
     
    104104End Class
    105105
    106 End NameSpace
    107 End NameSpace
     106End Namespace
     107End Namespace
  • trunk/ab5.0/ablib/src/Classes/System/Threading/Thread.ab

    r597 r599  
    460460
    461461    Function FindThreadInfo(threadID As DWord) As *ThreadInfo
     462        EnterCriticalSection(CriticalSection)
    462463        Dim i As Long
    463464        For i = 0 To ELM(ThreadNum)
     
    467468            End If
    468469        Next
     470        LeaveCriticalSection(CriticalSection)
    469471    End Function
    470472
     
    476478Public
    477479    Function GetCurrentException() As ExceptionService
     480        EnterCriticalSection(CriticalSection)
    478481        Dim dwNowThreadId = GetCurrentThreadId()
    479 
    480482        Dim i As Long
    481483        For i=0 To ELM(ThreadNum)
    482484            With collection[i]
    483485                If .thread.ThreadId = dwNowThreadId Then
    484                     Return .exception
     486                    GetCurrentException = .exception
     487                    Exit For
    485488                End If
    486489            End With
    487490        Next
    488 
    489         OutputDebugString( Ex"カレントスレッドの取得に失敗\r\n" )
    490         Return Nothing
     491        LeaveCriticalSection(CriticalSection)
     492        If ActiveBasic.IsNothing(GetCurrentException) Then
     493            OutputDebugString(Ex"カレントスレッドの取得に失敗\r\n")
     494        End If
    491495    End Function
    492496End Class
  • trunk/ab5.0/ablib/src/Classes/System/Threading/WaitHandle.ab

    r581 r599  
    2424
    2525    ' Methods
    26     Virtual Sub WaitHandle()
     26    Sub WaitHandle()
    2727    End Sub
    2828
     
    4343
    4444    Function WaitOne() As Boolean
    45         Return WaitOne(INFINITE, FALSE)
    46     End Function
    47 
    48     Function WaitOne(millisecondsTimeout As Long, exitContext As Boolean) As Boolean
    49         Return WaitHandle.AfterWait(WaitForSingleObject(h, millisecondsTimeout As DWord), 1)
    50     End Function
    51 
    52     Function WaitOne(timeout As System.TimeSpan, exitContext As Boolean) As Boolean
    53         Return WaitHandle.AfterWait(WaitForSingleObject(h, timeout.TotalMilliseconds() As DWord), 1)
    54     End Function
    55 
    56     Static Function WaitAll(count As DWord, handles As *HANDLE) As Boolean
    57         Return WaitAll(count, handles, INFINITE, FALSE)
    58     End Function
    59 
    60     Static Function WaitAll(count As DWord, handles As *HANDLE, millisecondsTimeout As Long, exitContext As Boolean) As Boolean
    61         Return WaitHandle.AfterWait(WaitForMultipleObjects(count, handles, TRUE, millisecondsTimeout), count)
    62     End Function
    63 
    64     Static Function WaitAll(count As DWord, handles As *HANDLE, timeout As System.TimeSpan, exitContext As Boolean) As Boolean
    65         Return WaitHandle.AfterWait(WaitForMultipleObjects(count, handles, TRUE, timeout.TotalMilliseconds() As DWord), count)
    66     End Function
    67 
    68     Static Function WaitAny(count As DWord, handles As *HANDLE) As Boolean
    69         Return WaitAny(count, handles, INFINITE, FALSE)
    70     End Function
    71 
    72     Static Function WaitAny(count As DWord, handles As *HANDLE, millisecondsTimeout As Long, exitContext As Boolean) As Boolean
    73         Return WaitHandle.AfterWait(WaitForMultipleObjects(count, handles, FALSE, millisecondsTimeout), count)
    74     End Function
    75 
    76     Static Function WaitAny(count As DWord, handles As *HANDLE, timeout As System.TimeSpan, exitContext As Boolean) As Boolean
    77         Return WaitHandle.AfterWait(WaitForMultipleObjects(count, handles, FALSE, timeout.TotalMilliseconds() As DWord), count)
     45        Return WaitOne(INFINITE As DWord)
     46    End Function
     47
     48    Function WaitOne(millisecondsTimeout As DWord) As Boolean
     49        If h = 0 Then
     50            Throw New ObjectDisposedException("WaitHandle.WaitOne")
     51        End If
     52        Return afterWait(WaitForSingleObject(h, millisecondsTimeout As DWord), 1)
     53    End Function
     54
     55    Function WaitOne(millisecondsTimeout As Long) As Boolean
     56        ThrowIfInvalidLongValue(millisecondsTimeout)
     57        Return WaitOne(millisecondsTimeout As DWord)
     58    End Function
     59
     60    Function WaitOne(timeout As System.TimeSpan) As Boolean
     61        Return WaitOne(timeout.TotalMilliseconds() As Long)
     62    End Function
     63
     64    Static Function WaitAll(handles As Collections.Generic.IList<WaitHandle>) As Boolean
     65        Return waitImpl(handles, TRUE, INFINITE As DWord)
     66    End Function
     67
     68    Static Function WaitAll(handles As Collections.Generic.IList<WaitHandle>, millisecondsTimeout As Long) As Boolean
     69        ThrowIfInvalidLongValue(millisecondsTimeout)
     70        Return waitImpl(handles, TRUE, millisecondsTimeout As DWord)
     71    End Function
     72
     73    Static Function WaitAll(handles As Collections.Generic.IList<WaitHandle>, millisecondsTimeout As DWord) As Boolean
     74        Return waitImpl(handles, TRUE, millisecondsTimeout)
     75    End Function
     76
     77    Static Function WaitAll(handles As Collections.Generic.IList<WaitHandle>, timeout As System.TimeSpan) As Boolean
     78        Return WaitAny(handles, timeout.TotalMilliseconds() As Long)
     79    End Function
     80
     81    Static Function WaitAny(handles As Collections.Generic.IList<WaitHandle>) As Boolean
     82        Return waitImpl(handles, FALSE, INFINITE As DWord)
     83    End Function
     84
     85    Static Function WaitAny(handles As Collections.Generic.IList<WaitHandle>, millisecondsTimeout As Long) As Boolean
     86        ThrowIfInvalidLongValue(millisecondsTimeout)
     87        Return waitImpl(handles, FALSE, millisecondsTimeout As DWord)
     88    End Function
     89
     90    Static Function WaitAny(handles As Collections.Generic.IList<WaitHandle>, millisecondsTimeout As DWord) As Boolean
     91        Return waitImpl(handles, FALSE, millisecondsTimeout)
     92    End Function
     93
     94    Static Function WaitAny(handles As Collections.Generic.IList<WaitHandle>, timeout As System.TimeSpan) As Boolean
     95        Return WaitAny(handles, timeout.TotalMilliseconds() As Long)
    7896    End Function
    7997
    8098    Static Function SignalAndWait(toSignal As WaitHandle, toWaitOn As WaitHandle) As Boolean
    81         Return SignalAndWait(toSignal, toWaitOn, INFINITE, FALSE)
    82     End Function
    83 
    84     Static Function SignalAndWait (toSignal As WaitHandle, toWaitOn As WaitHandle, timeout As System.TimeSpan, exitContext As Boolean) As Boolean
    85         Return SignalAndWait(toSignal, toWaitOn, timeout.TotalMilliseconds() As Long, FALSE)
    86     End Function
    87 
    88     Static Function SignalAndWait(toSignal As WaitHandle, toWaitOn As WaitHandle, millisecondsTimeout As Long, exitContext As Boolean) As Boolean
     99        Return SignalAndWait(toSignal, toWaitOn, INFINITE)
     100    End Function
     101
     102    Static Function SignalAndWait(toSignal As WaitHandle, toWaitOn As WaitHandle, timeout As System.TimeSpan) As Boolean
     103        Return SignalAndWait(toSignal, toWaitOn, timeout.TotalMilliseconds() As Long)
     104    End Function
     105
     106    Static Function SignalAndWait(toSignal As WaitHandle, toWaitOn As WaitHandle, timeout As Long) As Boolean
     107        Return SignalAndWait(toSignal, toWaitOn, timeout As DWord)
     108    End Function
     109
     110    Static Function SignalAndWait(toSignal As WaitHandle, toWaitOn As WaitHandle, millisecondsTimeout As DWord) As Boolean
    89111        Dim pSignalObjectAndWait = GetProcAddress(GetModuleHandle("Kernel32.dll"), ToMBStr("SignalObjectAndWait")) As Detail.PFNSignalObjectAndWait
    90112        If pSignalObjectAndWait = 0 Then
    91113            Throw New PlatformNotSupportedException("WaitHandle.SignalAndWait: This platform doesn't supoort this operation.")
    92114        End If
    93         Return WaitHandle.AfterWait(pSignalObjectAndWait(toSignal.Handle, toWaitOn.Handle, millisecondsTimeout As DWord, FALSE), 1)
    94     End Function
    95 
    96 Public
    97     Function WaitTimeout() As Long
    98         Return WAIT_TIMEOUT
    99     End Function
     115        Return afterWait(pSignalObjectAndWait(toSignal.Handle, toWaitOn.Handle, millisecondsTimeout As DWord, FALSE), 1)
     116    End Function
     117
     118    Static Const WaitTimeout = WAIT_TIMEOUT
    100119
    101120Protected
     
    105124    h As HANDLE
    106125
    107     Static Function AfterWait(ret As DWord, n As DWord) As Boolean
     126    /*!
     127    @brief WaitAll/WaitAnyの実装
     128    @param[in] handles 待機ハンドル
     129    @param[in] waitAll WaitAllならTRUE、WaitAnyならFALSE
     130    @param[in] millisecondsTimeout タイムアウトまでの時間。-1 As DWordなら無限に待ち続ける。
     131    @return シグナルが発生したらTrue、タイムアウトになったらFalse。
     132    @date 2008/08/27
     133    @auther Egtra
     134    */
     135    Static Function waitImpl(handles As Collections.Generic.IList<WaitHandle>, waitAll As BOOL, millisecondsTimeout As DWord) As Boolean
     136'       If ActiveBasic.IsNothing(handles) Then
     137'           Throw New ArgumentNullException("handles")
     138'       End If
     139        Dim count = handles.Count
     140        If count > MAXIMUM_WAIT_OBJECTS Then
     141            Throw New InvalidOperationException("handles.Count > MAXIMUM_WAIT_OBJECTS")
     142        End If
     143        Return afterWait(WaitForMultipleObjects(count, ToArrayOfHANDLE(handles), waitAll, millisecondsTimeout), count)
     144    End Function
     145
     146    /*!
     147    @brief 待機が終了した後の処理を行う。
     148    @param[in] ret 待機関数の戻り値
     149    @param[in] n 待機させたハンドルの数
     150    @return シグナルが発生したらTrue、タイムアウトになったらFalse。
     151    @auther Egtra
     152    */
     153    Static Function afterWait(ret As DWord, n As DWord) As Boolean
    108154        Select Case ret
    109155            Case WAIT_TIMEOUT
    110156                Return False
    111157            Case WAIT_ABANDONED
    112                 ' Throw AbandonedMutexException
     158                Throw New AbandonedMutexException
    113159                Debug
    114160                ExitThread(0)
    115             'Case WAIT_FAILED
     161            Case WAIT_FAILED
     162                ActiveBasic.Windows.ThrowWithLastError()
    116163            Case Else
    117164                If WAIT_OBJECT_0 <= ret And ret < WAIT_OBJECT_0 + n Then
     
    123170        End Select
    124171    End Function
     172
     173    /*!
     174    @brief WaitHandleのリストをHANDLE配列にする。
     175    @param[in] handles 変換元
     176    @return 変換済みの配列の要素を指すポインタ
     177    @date 2008/08/27
     178    @auther Egtra
     179    */
     180    Static Function ToArrayOfHANDLE(handles As Collections.Generic.IList<WaitHandle>) As *HANDLE
     181        Dim count = handles.Count
     182        ToArrayOfHANDLE = GC_malloc(count * SizeOf(HANDLE))
     183        Dim i As Long
     184        For i = 0 To ELM(count)
     185            ToArrayOfHANDLE[i] = handles.Item[i].h
     186        Next
     187    End Function
     188
     189    /*!
     190    @brief Long値が0以上か-1でない場合、例外を投げる。
     191    @param[in] x テストする値
     192    @throw ArgumentOutOfRangeException -1未満の値のとき
     193    @date 2008/08/27
     194    @auther Egtra
     195    */
     196    Static Sub ThrowIfInvalidLongValue(x As Long)
     197        If x < -1 Then
     198            Throw New ArgumentOutOfRangeException("millisecondsTimeout")
     199        End If
     200    End Sub
    125201End Class
    126202
Note: See TracChangeset for help on using the changeset viewer.