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

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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.