/// <summary>
        /// Subscribe to the inner event
        /// </summary>
        public void Add(TFromHandler from)
        {
            var to = _convert(from);

            Transactional.Update(ref _handlers, h => h.Add(from, to));
            _add(to);
        }
Exemple #2
0
        public async Task SimpleUpdateWith2Params()
        {
            var list = ImmutableList <int> .Empty;

            Transactional.Update(ref list, 42, 10000, (l, x, y) => l.Add(y - x));

            list.Should().HaveCount(1);
            list[0].Should().Be(9958);
        }
Exemple #3
0
        public async Task SimpleUpdateWithTuple()
        {
            var list = ImmutableList <int> .Empty;

            var res = Transactional.Update(ref list, l => Tuple.Create(l.Add(42), 21));

            list.Should().HaveCount(1);
            res.Should().Be(21);
        }
Exemple #4
0
        public async Task SimpleUpdateWith1Param()
        {
            var list = ImmutableList <int> .Empty;

            Transactional.Update(ref list, 42, (l, x) => l.Add(x));

            list.Should().HaveCount(1);
            list[0].Should().Be(42);
        }
#pragma warning restore 1998

        public IDisposable RegisterHandler(IHttpHandler handler)
        {
            Transactional.Update(ref _handlers, handler, (list, h) => list.Add(h));
            _handlers.Add(handler);

            return(Disposable.Create(() =>
            {
                Transactional.Update(ref _handlers, handler, (list, h) => list.Remove(h));
                (handler as IDisposable)?.Dispose();
            }));
        }
Exemple #6
0
        public void OnCompleted(Action continuation)
        {
            Transactional.Update(
                ref _continuations,
                continuation,
                (previous, c) => previous == null ? ImmutableList <Action> .Empty.Add(c) : previous.Add(c));

            if (Termination != TerminationType.Running)
            {
                RaiseOnCompleted();
            }
        }
        /// <summary>
        /// Create  a handler for this relative path
        /// </summary>
        /// <remarks>
        /// Disposing the return value will remove the unregister the handler.
        /// </remarks>
        public IDisposable RegisterHandler(IHttpHandler handler)
        {
            if (_handlers == null)
            {
                throw new ObjectDisposedException(nameof(RelativePathHandler));
            }

            Transactional.Update(ref _handlers, handler, (list, h) => list.Add(h));
            _handlers.Add(handler);

            return(Disposable.Create(() =>
            {
                Transactional.Update(ref _handlers, handler, (list, h) => list.Remove(h));
                (handler as IDisposable)?.Dispose();
            }));
        }
Exemple #8
0
        public void When_Update_WithTwoParameter_ReturnsOriginalValue_Then_FastExit()
        {
            var value1 = new MyClass();
            var value2 = new MyClass();

            var obj        = value1;
            var invocation = 0;

            Transactional.Update(ref obj, 1, 2, (o, _, __) =>
            {
                invocation++;
                obj = value2;
                return(o);
            });

            Assert.AreEqual(1, invocation);
            Assert.AreEqual(value2, obj);
        }
Exemple #9
0
        public void When_UpdateObject_ReturnsOriginalValue_Then_FastExit()
        {
            var value1 = new object();
            var value2 = new object();

            var obj        = value1;
            var invocation = 0;

            Transactional.Update(ref obj, o =>
            {
                invocation++;
                obj = value2;
                return(o);
            });

            Assert.AreEqual(1, invocation);
            Assert.AreEqual(value2, obj);
        }
Exemple #10
0
        public void When_Update_WithProjectionAndOneParameter_ReturnsOriginalValue_Then_FastExit()
        {
            var value1 = new MyClass();
            var value2 = new MyClass();

            var obj        = value1;
            var invocation = 0;

            Transactional.Update(ref obj, 1, (o, _) =>
            {
                invocation++;
                obj = value2;
                return(Tuple.Create(o, new object()));
            });

            Assert.AreEqual(1, invocation);
            Assert.AreEqual(value2, obj);
        }
Exemple #11
0
        public async Task AtomicUpdate()
        {
            var list = ImmutableList <int> .Empty;

            var ev = new AutoResetEvent(false);

            var runs1 = 0;

            var t = Task.Run(() =>
            {
                Transactional.Update(ref list, l =>
                {
                    var ret = l.Add(42);

                    // We've capture the list, release the thread that will create
                    // the race condition
                    ev.Set();

                    // Now wait for the race to happen
                    ev.WaitOne();
                    runs1++;

                    return(ret);
                });
            });

            // Wait for the other thread to have captured the list
            ev.WaitOne();

            // Update the list reference while the other thread is updaint
            Transactional.Update(ref list, l => l.Add(42));

            // Release the waiting thread.
            ev.Set();

            await t;

            list.Should().HaveCount(2);
            runs1.Should().Be(2);
        }