Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf6cea7c

Browse files
committed
Merge branch 'master' into fsharp4
Conflicts:src/fsharp/FSharp.Core/array.fssrc/fsharp/FSharp.Core/seq.fs
2 parents58669ae +cacff75 commitf6cea7c

File tree

12 files changed

+126
-67
lines changed

12 files changed

+126
-67
lines changed

‎src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Control/AsyncModule.fs‎

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ open System
99
openFSharp.Core.Unittests.LibraryTestFx
1010
openNUnit.Framework
1111

12+
moduleLeakUtils=
13+
// when testing for liveness, the things that we want to observe must always be created in
14+
// a nested function call to avoid the GC (possibly) treating them as roots past the last use in the block.
15+
// We also need something non trivial to disuade the compiler from inlining in Release builds.
16+
typeToRun<'a>(f: unit->'a)=
17+
memberthis.Invoke()= f()
18+
19+
letrun(toRun:ToRun<'a>)= toRun.Invoke()
1220

1321
// ---------------------------------------------------
1422

@@ -191,6 +199,41 @@ type AsyncModule() =
191199

192200
for_i=1to50do test()
193201

202+
203+
[<Test>]
204+
memberthis.``Async.AwaitWaitHandle does not leak memory``()=
205+
// This test checks that AwaitWaitHandle does not leak continuations (described in #131),
206+
// We only test the worst case - when the AwaitWaitHandle is already set.
207+
use manualResetEvent=new System.Threading.ManualResetEvent(true)
208+
209+
lettryToLeak()=
210+
letresource=
211+
LeakUtils.ToRun(fun()->
212+
letresource= obj()
213+
letwork=
214+
async{
215+
let!_= Async.AwaitWaitHandle manualResetEvent
216+
GC.KeepAlive(resource)
217+
return()
218+
}
219+
220+
work|> Async.RunSynchronously|> ignore
221+
WeakReference(resource))
222+
|> LeakUtils.run
223+
224+
Assert.IsTrue(resource.IsAlive)
225+
226+
GC.Collect()
227+
GC.WaitForPendingFinalizers()
228+
GC.Collect()
229+
GC.WaitForPendingFinalizers()
230+
GC.Collect()
231+
232+
Assert.IsFalse(resource.IsAlive)
233+
234+
// The leak hangs on a race condition which is really hard to trigger in F# 3.0, hence the 100000 runs...
235+
for_in1..100do tryToLeak()
236+
194237
[<Test>]
195238
memberthis.``AwaitWaitHandle.DisposedWaitHandle2``()=
196239
letwh=new System.Threading.ManualResetEvent(false)

‎src/fsharp/FSharp.Core/array.fs‎

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ namespace Microsoft.FSharp.Collections
1212
openMicrosoft.FSharp.Core.Operators
1313
openMicrosoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators
1414
openMicrosoft.FSharp.Core.SR
15-
openMicrosoft.FSharp.Core.LanguagePrimitives.ErrorStrings
1615
#if FX_NO_ICLONEABLE
1716
openMicrosoft.FSharp.Core.ICloneableExtensions
1817
#else
@@ -36,7 +35,7 @@ namespace Microsoft.FSharp.Collections
3635
[<CompiledName("Last")>]
3736
let inlinelast(array:'T[])=
3837
checkNonNull"array" array
39-
if array.Length=0then invalidArg"array" InputArrayEmptyString
38+
if array.Length=0then invalidArg"array"LanguagePrimitives.ErrorStrings.InputArrayEmptyString
4039
array.[array.Length-1]
4140

4241
[<CompiledName("TryLast")>]
@@ -205,7 +204,7 @@ namespace Microsoft.FSharp.Collections
205204
[<CompiledName("Head")>]
206205
lethead(array:'T[])=
207206
checkNonNull"array" array
208-
if array.Length=0then invalidArg"array" InputArrayEmptyStringelse array.[0]
207+
if array.Length=0then invalidArg"array"LanguagePrimitives.ErrorStrings.InputArrayEmptyStringelse array.[0]
209208

210209
[<CompiledName("Copy")>]
211210
letcopy(array:'T[])=
@@ -719,18 +718,20 @@ namespace Microsoft.FSharp.Collections
719718
letreduce f(array:_[])=
720719
checkNonNull"array" array
721720
letlen= array.Length
722-
if len=0then invalidArg"array" InputArrayEmptyStringelse
723-
letf= OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f)
724-
let mutableres= array.[0]
725-
for i=1to len-1do
726-
res<- f.Invoke(res,array.[i])
727-
res
721+
if len=0then
722+
invalidArg"array" LanguagePrimitives.ErrorStrings.InputArrayEmptyString
723+
else
724+
letf= OptimizedClosures.FSharpFunc<_,_,_>.Adapt(f)
725+
let mutableres= array.[0]
726+
for i=1to len-1do
727+
res<- f.Invoke(res,array.[i])
728+
res
728729

729730
[<CompiledName("ReduceBack")>]
730731
letreduceBack f(array:_[])=
731732
checkNonNull"array" array
732733
letlen= array.Length
733-
if len=0then invalidArg"array" InputArrayEmptyString
734+
if len=0then invalidArg"array"LanguagePrimitives.ErrorStrings.InputArrayEmptyString
734735
else foldSubRight f array0(len-2) array.[len-1]
735736

736737
[<CompiledName("SortInPlaceWith")>]
@@ -843,7 +844,7 @@ namespace Microsoft.FSharp.Collections
843844
[<CompiledName("Min")>]
844845
let inlinemin(array:_[])=
845846
checkNonNull"array" array
846-
if array.Length=0then invalidArg"array" InputArrayEmptyString
847+
if array.Length=0then invalidArg"array"LanguagePrimitives.ErrorStrings.InputArrayEmptyString
847848
let mutableacc= array.[0]
848849
for i=1to array.Length-1do
849850
letcurr= array.[i]
@@ -854,7 +855,7 @@ namespace Microsoft.FSharp.Collections
854855
[<CompiledName("MinBy")>]
855856
let inlineminBy f(array:_[])=
856857
checkNonNull"array" array
857-
if array.Length=0then invalidArg"array" InputArrayEmptyString
858+
if array.Length=0then invalidArg"array"LanguagePrimitives.ErrorStrings.InputArrayEmptyString
858859
let mutableaccv= array.[0]
859860
let mutableacc= f accv
860861
for i=1to array.Length-1do
@@ -868,7 +869,7 @@ namespace Microsoft.FSharp.Collections
868869
[<CompiledName("Max")>]
869870
let inlinemax(array:_[])=
870871
checkNonNull"array" array
871-
if array.Length=0then invalidArg"array" InputArrayEmptyString
872+
if array.Length=0then invalidArg"array"LanguagePrimitives.ErrorStrings.InputArrayEmptyString
872873
let mutableacc= array.[0]
873874
for i=1to array.Length-1do
874875
letcurr= array.[i]
@@ -879,7 +880,7 @@ namespace Microsoft.FSharp.Collections
879880
[<CompiledName("MaxBy")>]
880881
let inlinemaxBy f(array:_[])=
881882
checkNonNull"array" array
882-
if array.Length=0then invalidArg"array" InputArrayEmptyString
883+
if array.Length=0then invalidArg"array"LanguagePrimitives.ErrorStrings.InputArrayEmptyString
883884
let mutableaccv= array.[0]
884885
let mutableacc= f accv
885886
for i=1to array.Length-1do

‎src/fsharp/FSharp.Core/control.fs‎

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1671,29 +1671,34 @@ namespace Microsoft.FSharp.Control
16711671
Action<obj>(fun _->
16721672
if latch.Enter()then
16731673
// if we got here - then we need to unregister RegisteredWaitHandle + trigger cancellation
1674-
// entrance to TP callback is protected by latch - so savedCont will never be called
1675-
match!rwhwith
1676-
| None->()
1677-
| Some rwh-> rwh.Unregister(null)|> ignore
1674+
// entrance to TP callback is protected by latch - so savedCont will never be called
1675+
lock rwh(fun()->
1676+
match!rwhwith
1677+
| None->()
1678+
| Some rwh-> rwh.Unregister(null)|> ignore)
16781679
Async.Start(async{do(aux.ccont(OperationCanceledException())|> unfake)}))
16791680

1680-
and registration: CancellationTokenRegistration= aux.token.Register(cancelHandler,null)
1681+
and registration: CancellationTokenRegistration= aux.token.Register(cancelHandler,null)
16811682

16821683
letsavedCont= args.cont
16831684
try
1684-
rwh:= Some(ThreadPool.RegisterWaitForSingleObject
1685-
(waitObject=waitHandle,
1686-
callBack=WaitOrTimerCallback(fun _ timeOut->
1687-
if latch.Enter()then
1688-
rwh:= None
1689-
registration.Dispose()
1690-
aux.trampolineHolder.Protect(fun()-> savedCont(not timeOut))|> unfake),
1691-
state=null,
1692-
millisecondsTimeOutInterval=millisecondsTimeout,
1693-
executeOnlyOnce=true));
1694-
FakeUnit
1685+
lock rwh(fun()->
1686+
rwh:= Some(ThreadPool.RegisterWaitForSingleObject
1687+
(waitObject=waitHandle,
1688+
callBack=WaitOrTimerCallback(fun _ timeOut->
1689+
if latch.Enter()then
1690+
lock rwh(fun()-> rwh.Value.Value.Unregister(null)|> ignore)
1691+
rwh:= None
1692+
registration.Dispose()
1693+
aux.trampolineHolder.Protect(fun()-> savedCont(not timeOut))|> unfake),
1694+
state=null,
1695+
millisecondsTimeOutInterval=millisecondsTimeout,
1696+
executeOnlyOnce=true));
1697+
FakeUnit)
16951698
with_->
1696-
if latch.Enter()then reraise()// reraise exception only if we successfully enter the latch (no other continuations were called)
1699+
if latch.Enter()then
1700+
registration.Dispose()
1701+
reraise()// reraise exception only if we successfully enter the latch (no other continuations were called)
16971702
else FakeUnit
16981703
)
16991704
#endif

‎src/fsharp/FSharp.Core/local.fs‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ namespace Microsoft.FSharp.Primitives.Basics
44

55
openMicrosoft.FSharp.Core
66
openMicrosoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators
7-
openMicrosoft.FSharp.Core.LanguagePrimitives.ErrorStrings
87
openMicrosoft.FSharp.Collections
98
openMicrosoft.FSharp.Core.Operators
109
openSystem.Diagnostics.CodeAnalysis
@@ -327,7 +326,7 @@ module internal List =
327326

328327

329328
letinit count f=
330-
if count<0then invalidArg"count" InputMustBeNonNegativeString
329+
if count<0then invalidArg"count"LanguagePrimitives.ErrorStrings.InputMustBeNonNegativeString
331330
if count=0then[]
332331
else
333332
letres= freshConsNoTail(f0)
@@ -344,7 +343,7 @@ module internal List =
344343
takeFreshConsTail cons2(n-1) xs
345344

346345
lettake n l=
347-
if n<0then invalidArg"count" InputMustBeNonNegativeString
346+
if n<0then invalidArg"count"LanguagePrimitives.ErrorStrings.InputMustBeNonNegativeString
348347
if n=0then[]else
349348
match lwith
350349
|[]-> raise<| System.InvalidOperationException(SR.GetString(SR.notEnoughElements))
@@ -714,7 +713,7 @@ module internal Array =
714713
(#"newarr !0" type('T) count: 'T array #)
715714

716715
let inlineinit(count:int)(f:int->'T)=
717-
if count<0then invalidArg"count" InputMustBeNonNegativeString
716+
if count<0then invalidArg"count"LanguagePrimitives.ErrorStrings.InputMustBeNonNegativeString
718717
letarr=(zeroCreateUnchecked count: 'T array)
719718
for i=0to count-1do
720719
arr.[i]<- f i
@@ -883,4 +882,4 @@ module internal Array =
883882
res.[i]<- array.[startIndex+i]
884883
else
885884
Array.Copy(array, startIndex, res,0, count)
886-
res
885+
res

‎src/fsharp/FSharp.Core/prim-types.fs‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -656,17 +656,17 @@ namespace Microsoft.FSharp.Core
656656

657657
moduleLanguagePrimitives=
658658

659-
660-
module(* internal*)ErrorStrings=
659+
[<Sealed>]
660+
type(* internal*)ErrorStrings=
661661
//inlinefunctionscannotcallGetString,sowemustmakethesebitspublic
662-
letAddressOpNotFirstClassString=SR.GetString(SR.addressOpNotFirstClass)
663-
letNoNegateMinValueString=SR.GetString(SR.noNegateMinValue)
662+
staticmemberAddressOpNotFirstClassStringwithget()=SR.GetString(SR.addressOpNotFirstClass)
663+
staticmemberNoNegateMinValueStringwithget()=SR.GetString(SR.noNegateMinValue)
664664
//needstobepublictobevisiblefrominlinefunction'average'andothers
665-
letInputSequenceEmptyString=SR.GetString(SR.inputSequenceEmpty)
665+
staticmemberInputSequenceEmptyStringwithget()=SR.GetString(SR.inputSequenceEmpty)
666666
//needstobepublictobevisiblefrominlinefunction'average'andothers
667-
letInputArrayEmptyString=SR.GetString(SR.arrayWasEmpty)
667+
staticmemberInputArrayEmptyStringwithget()=SR.GetString(SR.arrayWasEmpty)
668668
//needstobepublictobevisiblefrominlinefunction'average'andothers
669-
letInputMustBeNonNegativeString=SR.GetString(SR.inputMustBeNonNegative)
669+
staticmemberInputMustBeNonNegativeStringwithget()=SR.GetString(SR.inputMustBeNonNegative)
670670

671671
[<CodeAnalysis.SuppressMessage("Microsoft.Design","CA1034:NestedTypesShouldNotBeVisible")>]//nestedmoduleOK
672672
moduleIntrinsicOperators=

‎src/fsharp/FSharp.Core/prim-types.fsi‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,22 +1015,23 @@ namespace Microsoft.FSharp.Core
10151015
val inline DivideByInt< ^T >:x:^T->y:int->^T when ^T:(static member DivideByInt:^T*int->^T)
10161016

10171017
///<summary>For internal use only</summary>
1018-
module(*internal*)ErrorStrings=
1018+
[<Sealed>]
1019+
type(*internal*)ErrorStrings=
10191020

10201021
[<CompilerMessage("This value is for use by compiled F#code and should not be used directly",1204,IsHidden=true)>]
1021-
valInputSequenceEmptyString:string
1022+
static memberInputSequenceEmptyString:string with get
10221023

10231024
[<CompilerMessage("This value is for use by compiled F#code and should not be used directly",1204,IsHidden=true)>]
1024-
valInputArrayEmptyString:string
1025+
static memberInputArrayEmptyString:string with get
10251026

10261027
[<CompilerMessage("This value is for use by compiled F#code and should not be used directly",1204,IsHidden=true)>]
1027-
valAddressOpNotFirstClassString:string
1028+
static memberAddressOpNotFirstClassString:string with get
10281029

10291030
[<CompilerMessage("This value is for use by compiled F#code and should not be used directly",1204,IsHidden=true)>]
1030-
valNoNegateMinValueString:string
1031+
static memberNoNegateMinValueString:string with get
10311032

10321033
[<CompilerMessage("This value is for use by compiled F#code and should not be used directly",1204,IsHidden=true)>]
1033-
valInputMustBeNonNegativeString:string
1034+
static memberInputMustBeNonNegativeString:string with get
10341035

10351036

10361037
//-------------------------------------------------------------------------

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp