Esempio n. 1
0
        private async Task add(T value, IAccessContext <CSScope> context)
        {
            await TaskCollector.With(async tc =>
            {
                CSScope pessimisticScope =
                    new CSScope(RWScope.ReadWrite,
                                InfiniteIntervalScope.Create(
                                    RWScope.ReadWrite, 0, null),
                                $"pessimistic scope for add-{value}");

                await context.InChildWithin(pessimisticScope,
                                            async childContext =>
                {
                    Tuple <node, int> lastNodeInfo =
                        await getLastNode(childContext);

                    /* At this point, we don’t require write access
                     * to the nodes from 0 to count - 1 anymore,
                     * but IInfiniteIntervalScope is not granular enough
                     * to represent that.
                     * Read tasks for lower indexes could proceed. */

                    node newNode = new node
                    {
                        Successor = null,
                        Value     = value
                    };

                    tc.Add(appendToLastNode(
                               newNode, lastNodeInfo, childContext));
                });
            });
        }
Esempio n. 2
0
        private async Task appendToLastNode(
            node newNode, Tuple <node, int> lastNodeInfo,
            IAccessContext <CSScope> context)
        {
            await context.InChildWithin(async childContext =>
            {
                if (lastNodeInfo == null)
                {
                    /* Setting first node */

                    /* Requires an IInfiniteIntervalScope from 0 to infinity,
                     * because setting the first node determines
                     * could also change all other nodes. */

                    var scope = new CSScope(
                        RWScope.ReadWrite,
                        InfiniteIntervalScope.Create(
                            RWScope.ReadWrite, 0, 1),
                        $"scope for appendToLastNode {newNode.Value}");

                    /* TRAP: Using context instead of childContext here
                     * may easily lead to a deadlock. */
                    childContext.RequiredScope = scope;

                    /* Wait for all required scope before writing. */
                    await childContext.UntilAvailable();

                    state.FirstNode = newNode;
                }
                else
                {
                    /* Set the new node */

                    int newIndex = lastNodeInfo.Item2 + 1;

                    var scope = new CSScope(
                        RWScope.ReadWrite,
                        InfiniteIntervalScope.Create(
                            RWScope.ReadWrite, newIndex, newIndex + 1));
                    childContext.RequiredScope = scope;
                    await childContext.UntilAvailable();

                    lastNodeInfo.Item1.Successor = newNode;
                }
                state.Count++;
            });
        }