Changeset 599


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
Files:
1 added
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/ab5.0/ablib/src/Classes/ActiveBasic/Windows/UI/Control.ab

    r575 r599  
    123123                .x, .y, .cx, .cy, .hwndParent, .hMenu, .hInstance, .lpCreateParams)
    124124            If hwnd = 0 Then
    125                 ActiveBasic.Windows.ThrowByWindowsError(GetLastError())
     125                ActiveBasic.Windows.ThrowWithLastError(GetLastError())
    126126            End If
    127127           
  • trunk/ab5.0/ablib/src/Classes/ActiveBasic/Windows/Windows.ab

    r575 r599  
    110110
    111111/*!
    112 @brief  GetLastErrorのエラー値を基に例外を投げる。
    113 @date   2008/07/13
     112@brief  Windowsのエラー値を基に例外を投げる
    114113@param[in] dwErrorCode  Win32エラーコード
    115114@throw WindowsException 常に投げられる。
    116 @auther Egtra
     115@date 2008/07/13
     116@auther Egtra
    117117*/
    118 Sub ThrowByWindowsError(dwErrorCode As DWord)
     118Sub ThrowWithErrorCode(dwErrorCode As DWord)
    119119    Throw New WindowsException(HRESULT_FROM_WIN32(dwErrorCode))
    120120End Sub
    121121
     122/*!
     123@brief 内部でGetLastErrorを呼んで、その値を基に例外を投げる。
     124@throw WindowsException 常に投げられる。
     125@date 2008/08/26
     126@auther Egtra
     127*/
     128Sub ThrowWithLastError()
     129    ThrowWithErrorCode(GetLastError())
     130End Sub
    122131/*!
    123132@brief  HRESULT値を基に例外を投げる。
  • 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
  • trunk/ab5.0/ablib/src/Classes/index.ab

    r598 r599  
    9292#require "./System/Threading/AutoResetEvent.ab"
    9393#require "./System/Threading/EventWaitHandle.ab"
     94#require "./System/Threading/Exception.ab"
    9495#require "./System/Threading/ManualResetEvent.ab"
    9596#require "./System/Threading/Mutex.ab"
    9697#require "./System/Threading/Semaphore.ab"
    9798#require "./System/Threading/Thread.ab"
     99#require "./System/Threading/ThreadPool.ab"
    98100#require "./System/Threading/Timeout.ab"
    99101#require "./System/Threading/WaitHandle.ab"
  • trunk/ab5.0/ablib/src/WinNT.ab

    r497 r599  
    55355535Const WT_TRANSFER_IMPERSONATION = &h00000100
    55365536'Const WT_SET_MAX_THREADPOOL_THREADS(Flags, Limit)  ((Flags) Or= (Limit)<<16)
    5537 TypeDef WAITORTIMERCALLBACKFUNC = *Sub(p As VoidPtr, b As Boolean)
     5537TypeDef WAITORTIMERCALLBACKFUNC = *Sub(p As VoidPtr, b As BOOLEAN)
    55385538TypeDef WORKERCALLBACKFUNC = *Sub(p As VoidPtr)
    55395539TypeDef APC_CALLBACK_FUNCTION = *Sub(dw AS DWord, p1 As VoidPtr, p2 As VoidPtr)
  • trunk/ab5.0/ablib/src/api_system.sbp

    r562 r599  
    555555End Type
    556556Declare Function GetFileInformationByHandle Lib "kernel32" (
    557     ByVal hFile As HANDLE,
    558     ByRef FileInformation As BY_HANDLE_FILE_INFORMATION
     557    ByVal hFile As HANDLE,
     558    ByRef FileInformation As BY_HANDLE_FILE_INFORMATION
    559559) As BOOL
    560560Declare Function GetFileSize Lib "kernel32" (hFile As HANDLE, pFileSizeHigh As *DWord) As DWord
    561 'Declare Function GetFileSizeEx Lib "kernel32" (hFile As HANDLE, pFileSizeHigh As *QWord) As Boolean
     561'Declare Function GetFileSizeEx Lib "kernel32" (hFile As HANDLE, pFileSizeHigh As *QWord) As BOOL
    562562Declare Function GetFileTime Lib "kernel32" (hFile As HANDLE, ByRef lpCreationTime As FILETIME, ByRef lpLastAccessTime As FILETIME, ByRef lpLastWriteTime As FILETIME) As BOOL
    563563
     
    805805Const FILE_CURRENT = 1
    806806Const FILE_END =     2
    807 Declare Function SetFilePointer Lib "kernel32" (hFile As HANDLE, lDistanceToMove As Long, lpDistanceToMoveHigh As DWordPtr, dwMoveMethod As DWord) As DWord
     807Declare Function SetFilePointer Lib "kernel32" (hFile As HANDLE, lDistanceToMove As Long, lpDistanceToMoveHigh As *Long, dwMoveMethod As DWord) As DWord
    808808
    809809Declare Function SetFileTime Lib "kernel32" (hFile As HANDLE, ByRef lpCreationTime As FILETIME, ByRef lpLastAccessTime As FILETIME, ByRef lpLastWriteTime As FILETIME) As BOOL
     
    975975Const MAKEINTATOM(i) = (i As Word As ULONG_PTR As LPTSTR)
    976976Const INVALID_ATOM = 0 As ATOM
     977
     978'#if _WIN32_WINNT > &h0500
     979TypeDef WAITORTIMERCALLBACK = WAITORTIMERCALLBACKFUNC
     980
     981'#endif
  • trunk/ab5.0/ablib/src/system/exception.ab

    r464 r599  
    5454            End If
    5555
    56             If Object.ReferenceEquals( ex, Nothing ) Then
     56            If ActiveBasic.IsNothing( ex ) Then
    5757                ' パラメータなしのとき
    5858                If paramName[0] = 0 Then
Note: See TracChangeset for help on using the changeset viewer.