Mercurial > pub > ImplabNet
diff Implab/Parallels/ArrayTraits.cs @ 24:ee04e1fa78da
fixed dispatch pool race condition
author | cin |
---|---|
date | Thu, 14 Nov 2013 01:15:07 +0400 |
parents | e3935fdf59a2 |
children | 9bf5b23650c9 |
line wrap: on
line diff
--- a/Implab/Parallels/ArrayTraits.cs Wed Nov 13 14:03:20 2013 +0400 +++ b/Implab/Parallels/ArrayTraits.cs Thu Nov 14 01:15:07 2013 +0400 @@ -167,5 +167,46 @@ return promise.Anyway(() => semaphore.Dispose()); } + + /* + this method is pretty fast, but it may cause a stack overflow if an element transformation is made faster then the next operation is + be chained, in this case the syncronous callback invocation will occur + + public static Promise<TDst[]> ChainedMap2<TSrc, TDst>(this TSrc[] source, ChainedOperation<TSrc, TDst> transform, int threads) { + if (source == null) + throw new ArgumentNullException("source"); + if (transform == null) + throw new ArgumentNullException("transform"); + if (threads <= 0) + throw new ArgumentOutOfRangeException("Threads number must be greater then zero"); + + var promise = new Promise<TDst[]>(); + var res = new TDst[source.Length]; + var index = -1; // we will start with increment + var len = source.Length; + var pending = len; + + Action<int> callback = null; + callback = (current) => { + if (current < len) { + transform(source[current]) + .Then( + x => { + res[current] = x; + if (Interlocked.Decrement(ref pending) == 0) + promise.Resolve(res); + else + callback(Interlocked.Increment(ref index)); + }, + e => promise.Reject(e) + ); + } + }; + + for (int i = 0; i < threads; i++) + callback(Interlocked.Increment(ref index)); + return promise; + } + */ } }