Index: trunk/ab5.0/ablib/src/Classes/System/Threading/EventWaitHandle.ab
===================================================================
--- trunk/ab5.0/ablib/src/Classes/System/Threading/EventWaitHandle.ab	(revision 597)
+++ trunk/ab5.0/ablib/src/Classes/System/Threading/EventWaitHandle.ab	(revision 599)
@@ -11,5 +11,7 @@
 Class EventWaitHandle
 	Inherits System.Threading.WaitHandle
-
+Private
+	Sub EventWaitHandle()
+	End Sub
 Public
 	Sub EventWaitHandle (initialState As Boolean, mode As EventResetMode)
@@ -54,6 +56,16 @@
 	既存の名前付き同期イベントを開きます。
 	*/
-	Static Function OpenExisting(name As String) As WaitHandle
-		This.Handle(OpenEvent(EVENT_ALL_ACCESS,FALSE,ToTCStr(name)))
+	Static Function OpenExisting(name As String) As EventWaitHandle
+		If ActiveBasic.IsNothing(name) Then
+			Throw New ArgumentNullException("name")
+		Else If name.Length = 0 Then
+			Throw New ArgumentException("name")
+		End If
+		OpenExisting = New EventWaitHandle
+		Dim h = OpenEvent(EVENT_ALL_ACCESS, FALSE, ToTCStr(name))
+		If h = 0 Then
+			IO.Detail.ThrowWinLastErrorIOException("OpenEvent failed.")
+		End If
+		OpenExisting.Handle = h
 	End Function
 
@@ -95,5 +107,5 @@
 WaitHandle から継承
 Handle
-SafeWaitHandle 
+SafeWaitHandle
 */
 
Index: trunk/ab5.0/ablib/src/Classes/System/Threading/Exception.ab
===================================================================
--- trunk/ab5.0/ablib/src/Classes/System/Threading/Exception.ab	(revision 597)
+++ trunk/ab5.0/ablib/src/Classes/System/Threading/Exception.ab	(revision 599)
@@ -1,4 +1,4 @@
-NameSpace System
-NameSpace Threading
+Namespace System
+Namespace Threading
 
 Class AbandonedMutexException
@@ -104,4 +104,4 @@
 End Class
 
-End NameSpace
-End NameSpace
+End Namespace
+End Namespace
Index: trunk/ab5.0/ablib/src/Classes/System/Threading/Thread.ab
===================================================================
--- trunk/ab5.0/ablib/src/Classes/System/Threading/Thread.ab	(revision 597)
+++ trunk/ab5.0/ablib/src/Classes/System/Threading/Thread.ab	(revision 599)
@@ -460,4 +460,5 @@
 
 	Function FindThreadInfo(threadID As DWord) As *ThreadInfo
+		EnterCriticalSection(CriticalSection)
 		Dim i As Long
 		For i = 0 To ELM(ThreadNum)
@@ -467,4 +468,5 @@
 			End If
 		Next
+		LeaveCriticalSection(CriticalSection)
 	End Function
 
@@ -476,17 +478,19 @@
 Public
 	Function GetCurrentException() As ExceptionService
+		EnterCriticalSection(CriticalSection)
 		Dim dwNowThreadId = GetCurrentThreadId()
-
 		Dim i As Long
 		For i=0 To ELM(ThreadNum)
 			With collection[i]
 				If .thread.ThreadId = dwNowThreadId Then
-					Return .exception
+					GetCurrentException = .exception
+					Exit For
 				End If
 			End With
 		Next
-
-		OutputDebugString( Ex"カレントスレッドの取得に失敗\r\n" )
-		Return Nothing
+		LeaveCriticalSection(CriticalSection)
+		If ActiveBasic.IsNothing(GetCurrentException) Then
+			OutputDebugString(Ex"カレントスレッドの取得に失敗\r\n")
+		End If
 	End Function
 End Class
Index: trunk/ab5.0/ablib/src/Classes/System/Threading/ThreadPool.ab
===================================================================
--- trunk/ab5.0/ablib/src/Classes/System/Threading/ThreadPool.ab	(revision 599)
+++ trunk/ab5.0/ablib/src/Classes/System/Threading/ThreadPool.ab	(revision 599)
@@ -0,0 +1,221 @@
+'Classes/System/Threading/ThreadPool.ab
+
+Namespace System
+Namespace Threading
+Namespace Detail
+
+TypeDef PQueueUserWorkItem = *Function(fn As LPTHREAD_START_ROUTINE, context As VoidPtr, flags As DWord) As BOOL
+
+TypeDef PRegisterWaitForSingleObject = *Function(ByRef hNewWaitObject As HANDLE, hObject As HANDLE, Callback As WAITORTIMERCALLBACK, Context As VoidPtr, dwMilliseconds As DWord, dwFlags As DWord) As BOOL
+
+Const WM_QueueUserWorkItem = WM_APP + 100
+Const WM_RegisterWaitForSingleObject = WM_APP + 101
+
+Class QueueContextData<T>
+Public
+	Callback As T
+	State As Object
+
+	Sub QueueContextData(c As T, s As Object)
+		Callback = c
+		State = s
+	End Sub
+End Class
+
+Class WaitData
+Public
+	WaitObject As WaitHandle
+	Callback As WaitOrTimerCallback
+	State As Object
+
+	Sub WaitData(w As WaitHandle, c As WaitOrTimerCallback, s As Object)
+		WaitObject = w
+		Callback = c
+		State = s
+	End Sub
+End Class
+
+End Namespace
+
+Delegate Sub WaitCallback(state As Object)
+Delegate Sub WaitOrTimerCallback(state As Object, timedOut As Boolean)
+
+Class ThreadPool
+Public
+	Static Function QueueUserWorkItem(callback As WaitCallback, state = Nothing As Object) As Boolean
+		startThread()
+		Dim qcd = New Detail.QueueContextData<WaitCallback>(callback, state)
+		Dim h = ActiveBasic.AllocObjectHandle(qcd)
+		PostThreadMessage(thread.ThreadId, Detail.WM_QueueUserWorkItem, 0, h)
+	End Function
+
+	'とりあえずタイムアウト非対応
+	Static Function RegisterWaitForSingleObject(waitObject As WaitHandle, callback As WaitOrTimerCallback, state As Object) As RegisteredWaitHandle
+		startThread()
+		Dim wd = New Detail.WaitData(waitObject, callback, state)
+		Dim h = ActiveBasic.AllocObjectHandle(wd)
+		PostThreadMessage(thread.ThreadId, Detail.WM_RegisterWaitForSingleObject, 0, h)
+	End Function
+/*
+	Static Function RegisterWaitForSingleObject(waitObject As WaitHandle, callback As WaitOrTimerCallback, state As Object, millisecondsTimeOutInterval As DWord, executeOnlyOnce As Boolean) As RegisteredWaitHandle
+	End Function
+*/
+Private
+	Static Function waitCallback(param As VoidPtr) As DWord
+		Try
+			Diagnostics.Debug.Assert(param <> 0)
+			Dim qcd = ActiveBasic.ReleaseObjectHandle(param As LONG_PTR) As Detail.QueueContextData<WaitCallback>
+			With qcd
+				Diagnostics.Debug.Assert(.Callback <> 0)
+				Dim c = .Callback
+				c(.State)
+			End With
+		Catch e As Object
+		End Try
+	End Function
+
+	Static Sub waitOrTimerCallback(param As VoidPtr, TimerOrWaitFired As BOOLEAN)
+		Try
+			Diagnostics.Debug.Assert(param <> 0)
+			Dim qcd = ActiveBasic.ReleaseObjectHandle(param As LONG_PTR) As Detail.QueueContextData<WaitOrTimerCallback>
+			With qcd
+				Diagnostics.Debug.Assert(.Callback <> 0)
+				Dim c = .Callback
+				c(.State, TimerOrWaitFired)
+			End With
+		Catch e As Object
+		End Try
+	End Sub
+
+	Static Sub startThread()
+		If ActiveBasic.IsNothing(thread) Then
+			Dim lock = New ActiveBasic.Windows.CriticalSectionLock(_System_CriticalSection)
+			thread = New Thread(AddressOf(poolThread), 0)
+			thread.Name = "ThreadPool"
+			thread.Start()
+			While isMessageQueueCreated = False
+				Sleep(1)
+			Wend
+			lock.Dispose()
+		End If
+	End Sub
+
+	Static Function poolThread(pv As VoidPtr) As DWord
+		Try
+			Dim msg As MSG
+			PeekMessage(msg, 0, 0, 0, PM_NOREMOVE) 'メッセージキューの作成
+			isMessageQueueCreated = True
+			Dim waitList = New Collections.Generic.List<Detail.WaitData>
+			Dim handles = waitListToArrayOfHANDLE(waitList)
+			Do
+				While PeekMessage(msg, 0, 0, 0, PM_REMOVE)
+					Select Case msg.message
+						Case WM_QUIT
+							Exit Do
+						Case Detail.WM_QueueUserWorkItem
+							waitCallback(msg.lParam As VoidPtr)
+						Case Detail.WM_RegisterWaitForSingleObject
+							Diagnostics.Debug.Assert(msg.lParam <> 0)
+							Dim wd = ActiveBasic.ReleaseObjectHandle(msg.lParam) As Detail.WaitData
+							waitList.Add(wd)
+							handles = waitListToArrayOfHANDLE(waitList)
+					End Select
+				Wend
+				Dim retWait = MsgWaitForMultipleObjects(waitList.Count As DWord, handles, FALSE, INFINITE, QS_ALLINPUT)
+				If retWait = &hffffffff Then
+					poolThread = retWait
+					Exit Do
+				ElseIf WAIT_OBJECT_0 <= retWait And retWait < WAIT_OBJECT_0 + waitList.Count Then
+					Dim i = retWait - WAIT_OBJECT_0
+					Dim wd = waitList[i]
+					With wd
+						Dim c = wd.Callback
+						c(wd.State, False)
+					End With
+					waitList.RemoveAt(i)
+				End If
+			Loop
+		Catch e As Object
+			Diagnostics.Trace.WriteLine("ThreadPool thread catches an exception:")
+			Diagnostics.Trace.WriteLine(e.ToString)
+		End Try
+	End Function
+
+	Static Function waitListToArrayOfHANDLE(waitList As Collections.Generic.List<Detail.WaitData>) As *HANDLE
+		Diagnostics.Debug.Assert(Not ActiveBasic.IsNothing(waitList))
+		waitListToArrayOfHANDLE = GC_malloc(waitList.Count * SizeOf(HANDLE))
+		Dim count = waitList.Count
+		Dim i As Long
+		For i = 0 To ELM(count)
+			waitListToArrayOfHANDLE[i] = waitList.Item[i].WaitObject.Handle
+		Next
+	End Function
+
+	Static thread = Nothing As Thread
+	Static isMessageQueueCreated = False As Boolean
+End Class
+
+Class RegisteredWaitHandle
+End Class
+#ifdef __UNDEFINED__
+Class ThreadPool
+Public
+	Static Function QueueUserWorkItem(callback As WaitCallback, state = Nothing As Object) As Boolean
+		Dim pfn = GetProcAddress(GetModuleHandle("kernel32"), ToMBStr("QueueUserWorkItem")) As Detail.PQueueUserWorkItem
+		If pfn = 0 Then
+			'ToDo: 自前実装
+			Throw New NotSupportedException("RegisterWaitForSingleObject requires Windows 2000")
+		End If
+		Dim qcd = New Detail.QueueContextData<WaitCallback>(callback, state)
+		Dim h = ActiveBasic.AllocObjectHandle(qcd)
+		pfn(AddressOf (waitCallback), h As VoidPtr, WT_EXECUTELONGFUNCTION)
+	End Function
+
+	Static Function RegisterWaitForSingleObject(waitObject As WaitHandle, callback As WaitOrTimerCallback, state As Object, millisecondsTimeOutInterval As DWord, executeOnlyOnce As Boolean) As RegisteredWaitHandle
+		Dim pfn = GetProcAddress(GetModuleHandle("kernel32"), ToMBStr("RegisterWaitForSingleObject")) As Detail.PRegisterWaitForSingleObject
+		If pfn = 0 Then
+			'ToDo: 自前実装
+			Throw New NotSupportedException("RegisterWaitForSingleObject requires Windows 2000")
+		End If
+		Dim qcd = New Detail.QueueContextData<WaitOrTimerCallback>(callback, state)
+		Dim h = ActiveBasic.AllocObjectHandle(qcd)
+		Dim wo As HANDLE
+		pfn(wo, waitObject.Handle, 0, 0 As VoidPtr, 0, WT_EXECUTELONGFUNCTION)
+'		pfn(wo, waitObject.Handle, AddressOf (waitOrTimerCallback), h As VoidPtr, millisecondsTimeOutInterval, WT_EXECUTELONGFUNCTION)
+	End Function
+
+Private
+	Static Function waitCallback(param As VoidPtr) As DWord
+		Try
+			Diagnostics.Debug.Assert(param <> 0)
+			Dim qcd = ActiveBasic.ReleaseObjectHandle(param As LONG_PTR) As Detail.QueueContextData<WaitCallback>
+			With qcd
+				Diagnostics.Debug.Assert(.Callback <> 0)
+				Dim c = .Callback
+				c(.State)
+			End With
+		Catch e As Object
+		End Try
+	End Function
+
+	Static Sub waitOrTimerCallback(param As VoidPtr, TimerOrWaitFired As BOOLEAN)
+		Try
+			Diagnostics.Debug.Assert(param <> 0)
+			Dim qcd = ActiveBasic.ReleaseObjectHandle(param As LONG_PTR) As Detail.QueueContextData<WaitOrTimerCallback>
+			With qcd
+				Diagnostics.Debug.Assert(.Callback <> 0)
+				Dim c = .Callback
+				c(.State, TimerOrWaitFired)
+			End With
+		Catch e As Object
+		End Try
+	End Sub
+End Class
+
+Class RegisteredWaitHandle
+End Class
+
+#endif
+
+End Namespace
+End Namespace
Index: trunk/ab5.0/ablib/src/Classes/System/Threading/WaitHandle.ab
===================================================================
--- trunk/ab5.0/ablib/src/Classes/System/Threading/WaitHandle.ab	(revision 597)
+++ trunk/ab5.0/ablib/src/Classes/System/Threading/WaitHandle.ab	(revision 599)
@@ -24,5 +24,5 @@
 
 	' Methods
-	Virtual Sub WaitHandle()
+	Sub WaitHandle()
 	End Sub
 
@@ -43,59 +43,78 @@
 
 	Function WaitOne() As Boolean
-		Return WaitOne(INFINITE, FALSE)
-	End Function
-
-	Function WaitOne(millisecondsTimeout As Long, exitContext As Boolean) As Boolean
-		Return WaitHandle.AfterWait(WaitForSingleObject(h, millisecondsTimeout As DWord), 1)
-	End Function
-
-	Function WaitOne(timeout As System.TimeSpan, exitContext As Boolean) As Boolean
-		Return WaitHandle.AfterWait(WaitForSingleObject(h, timeout.TotalMilliseconds() As DWord), 1)
-	End Function
-
-	Static Function WaitAll(count As DWord, handles As *HANDLE) As Boolean
-		Return WaitAll(count, handles, INFINITE, FALSE)
-	End Function
-
-	Static Function WaitAll(count As DWord, handles As *HANDLE, millisecondsTimeout As Long, exitContext As Boolean) As Boolean
-		Return WaitHandle.AfterWait(WaitForMultipleObjects(count, handles, TRUE, millisecondsTimeout), count)
-	End Function
-
-	Static Function WaitAll(count As DWord, handles As *HANDLE, timeout As System.TimeSpan, exitContext As Boolean) As Boolean
-		Return WaitHandle.AfterWait(WaitForMultipleObjects(count, handles, TRUE, timeout.TotalMilliseconds() As DWord), count)
-	End Function
-
-	Static Function WaitAny(count As DWord, handles As *HANDLE) As Boolean
-		Return WaitAny(count, handles, INFINITE, FALSE)
-	End Function
-
-	Static Function WaitAny(count As DWord, handles As *HANDLE, millisecondsTimeout As Long, exitContext As Boolean) As Boolean
-		Return WaitHandle.AfterWait(WaitForMultipleObjects(count, handles, FALSE, millisecondsTimeout), count)
-	End Function
-
-	Static Function WaitAny(count As DWord, handles As *HANDLE, timeout As System.TimeSpan, exitContext As Boolean) As Boolean
-		Return WaitHandle.AfterWait(WaitForMultipleObjects(count, handles, FALSE, timeout.TotalMilliseconds() As DWord), count)
+		Return WaitOne(INFINITE As DWord)
+	End Function
+
+	Function WaitOne(millisecondsTimeout As DWord) As Boolean
+		If h = 0 Then
+			Throw New ObjectDisposedException("WaitHandle.WaitOne")
+		End If
+		Return afterWait(WaitForSingleObject(h, millisecondsTimeout As DWord), 1)
+	End Function
+
+	Function WaitOne(millisecondsTimeout As Long) As Boolean
+		ThrowIfInvalidLongValue(millisecondsTimeout)
+		Return WaitOne(millisecondsTimeout As DWord)
+	End Function
+
+	Function WaitOne(timeout As System.TimeSpan) As Boolean
+		Return WaitOne(timeout.TotalMilliseconds() As Long)
+	End Function
+
+	Static Function WaitAll(handles As Collections.Generic.IList<WaitHandle>) As Boolean
+		Return waitImpl(handles, TRUE, INFINITE As DWord)
+	End Function
+
+	Static Function WaitAll(handles As Collections.Generic.IList<WaitHandle>, millisecondsTimeout As Long) As Boolean
+		ThrowIfInvalidLongValue(millisecondsTimeout)
+		Return waitImpl(handles, TRUE, millisecondsTimeout As DWord)
+	End Function
+
+	Static Function WaitAll(handles As Collections.Generic.IList<WaitHandle>, millisecondsTimeout As DWord) As Boolean
+		Return waitImpl(handles, TRUE, millisecondsTimeout)
+	End Function
+
+	Static Function WaitAll(handles As Collections.Generic.IList<WaitHandle>, timeout As System.TimeSpan) As Boolean
+		Return WaitAny(handles, timeout.TotalMilliseconds() As Long)
+	End Function
+
+	Static Function WaitAny(handles As Collections.Generic.IList<WaitHandle>) As Boolean
+		Return waitImpl(handles, FALSE, INFINITE As DWord)
+	End Function
+
+	Static Function WaitAny(handles As Collections.Generic.IList<WaitHandle>, millisecondsTimeout As Long) As Boolean
+		ThrowIfInvalidLongValue(millisecondsTimeout)
+		Return waitImpl(handles, FALSE, millisecondsTimeout As DWord)
+	End Function
+
+	Static Function WaitAny(handles As Collections.Generic.IList<WaitHandle>, millisecondsTimeout As DWord) As Boolean
+		Return waitImpl(handles, FALSE, millisecondsTimeout)
+	End Function
+
+	Static Function WaitAny(handles As Collections.Generic.IList<WaitHandle>, timeout As System.TimeSpan) As Boolean
+		Return WaitAny(handles, timeout.TotalMilliseconds() As Long)
 	End Function
 
 	Static Function SignalAndWait(toSignal As WaitHandle, toWaitOn As WaitHandle) As Boolean
-		Return SignalAndWait(toSignal, toWaitOn, INFINITE, FALSE)
-	End Function
-
-	Static Function SignalAndWait (toSignal As WaitHandle, toWaitOn As WaitHandle, timeout As System.TimeSpan, exitContext As Boolean) As Boolean
-		Return SignalAndWait(toSignal, toWaitOn, timeout.TotalMilliseconds() As Long, FALSE)
-	End Function
-
-	Static Function SignalAndWait(toSignal As WaitHandle, toWaitOn As WaitHandle, millisecondsTimeout As Long, exitContext As Boolean) As Boolean
+		Return SignalAndWait(toSignal, toWaitOn, INFINITE)
+	End Function
+
+	Static Function SignalAndWait(toSignal As WaitHandle, toWaitOn As WaitHandle, timeout As System.TimeSpan) As Boolean
+		Return SignalAndWait(toSignal, toWaitOn, timeout.TotalMilliseconds() As Long)
+	End Function
+
+	Static Function SignalAndWait(toSignal As WaitHandle, toWaitOn As WaitHandle, timeout As Long) As Boolean
+		Return SignalAndWait(toSignal, toWaitOn, timeout As DWord)
+	End Function
+
+	Static Function SignalAndWait(toSignal As WaitHandle, toWaitOn As WaitHandle, millisecondsTimeout As DWord) As Boolean
 		Dim pSignalObjectAndWait = GetProcAddress(GetModuleHandle("Kernel32.dll"), ToMBStr("SignalObjectAndWait")) As Detail.PFNSignalObjectAndWait
 		If pSignalObjectAndWait = 0 Then
 			Throw New PlatformNotSupportedException("WaitHandle.SignalAndWait: This platform doesn't supoort this operation.")
 		End If
-		Return WaitHandle.AfterWait(pSignalObjectAndWait(toSignal.Handle, toWaitOn.Handle, millisecondsTimeout As DWord, FALSE), 1)
-	End Function
-
-Public
-	Function WaitTimeout() As Long
-		Return WAIT_TIMEOUT
-	End Function
+		Return afterWait(pSignalObjectAndWait(toSignal.Handle, toWaitOn.Handle, millisecondsTimeout As DWord, FALSE), 1)
+	End Function
+
+	Static Const WaitTimeout = WAIT_TIMEOUT
 
 Protected
@@ -105,13 +124,41 @@
 	h As HANDLE
 
-	Static Function AfterWait(ret As DWord, n As DWord) As Boolean
+	/*!
+	@brief WaitAll/WaitAnyの実装
+	@param[in] handles 待機ハンドル
+	@param[in] waitAll WaitAllならTRUE、WaitAnyならFALSE
+	@param[in] millisecondsTimeout タイムアウトまでの時間。-1 As DWordなら無限に待ち続ける。
+	@return シグナルが発生したらTrue、タイムアウトになったらFalse。
+	@date 2008/08/27
+	@auther Egtra
+	*/
+	Static Function waitImpl(handles As Collections.Generic.IList<WaitHandle>, waitAll As BOOL, millisecondsTimeout As DWord) As Boolean
+'		If ActiveBasic.IsNothing(handles) Then
+'			Throw New ArgumentNullException("handles")
+'		End If
+		Dim count = handles.Count
+		If count > MAXIMUM_WAIT_OBJECTS Then
+			Throw New InvalidOperationException("handles.Count > MAXIMUM_WAIT_OBJECTS")
+		End If
+		Return afterWait(WaitForMultipleObjects(count, ToArrayOfHANDLE(handles), waitAll, millisecondsTimeout), count)
+	End Function
+
+	/*!
+	@brief 待機が終了した後の処理を行う。
+	@param[in] ret 待機関数の戻り値
+	@param[in] n 待機させたハンドルの数
+	@return シグナルが発生したらTrue、タイムアウトになったらFalse。
+	@auther Egtra
+	*/
+	Static Function afterWait(ret As DWord, n As DWord) As Boolean
 		Select Case ret
 			Case WAIT_TIMEOUT
 				Return False
 			Case WAIT_ABANDONED
-				' Throw AbandonedMutexException
+				Throw New AbandonedMutexException
 				Debug
 				ExitThread(0)
-			'Case WAIT_FAILED
+			Case WAIT_FAILED
+				ActiveBasic.Windows.ThrowWithLastError()
 			Case Else
 				If WAIT_OBJECT_0 <= ret And ret < WAIT_OBJECT_0 + n Then
@@ -123,4 +170,33 @@
 		End Select
 	End Function
+
+	/*!
+	@brief WaitHandleのリストをHANDLE配列にする。
+	@param[in] handles 変換元
+	@return 変換済みの配列の要素を指すポインタ
+	@date 2008/08/27
+	@auther Egtra
+	*/
+	Static Function ToArrayOfHANDLE(handles As Collections.Generic.IList<WaitHandle>) As *HANDLE
+		Dim count = handles.Count 
+		ToArrayOfHANDLE = GC_malloc(count * SizeOf(HANDLE))
+		Dim i As Long
+		For i = 0 To ELM(count)
+			ToArrayOfHANDLE[i] = handles.Item[i].h
+		Next
+	End Function
+
+	/*!
+	@brief Long値が0以上か-1でない場合、例外を投げる。
+	@param[in] x テストする値
+	@throw ArgumentOutOfRangeException -1未満の値のとき
+	@date 2008/08/27
+	@auther Egtra
+	*/
+	Static Sub ThrowIfInvalidLongValue(x As Long)
+		If x < -1 Then
+			Throw New ArgumentOutOfRangeException("millisecondsTimeout")
+		End If
+	End Sub
 End Class
 
