Message9955

Author stefan.richthofer
Recipients jmadden, stefan.richthofer
Date 2015-04-24.17:02:36
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1429894956.76.0.963903202678.issue2337@psf.upfronthosting.co.za>
In-reply-to
Content
Right, it should be fixed for PyDequeIter too. Some remarks:

- In PyDequeIter, traverseNode should not stop at header, but rotate around the entire circle until .lastReturned is reached again (in case lastReturned != header initially)

- Checking node.right for null during iteration should not be necessary as PyDeque always keeps the list a circle, having never null-links

- Unless a multithreaded scenario removes a node and nulls its .right while traverse-iteration traverses it

- But the right way to prevent this is to make traverseNode synchronized anyway, isn't it?

- I reasoned whether this might produce subtle deadlocks, but I suppose it should not.

Proposed code:


    private class PyDequeIter extends PyIterator {
        ...
        ...

        /* Traverseproc implementation */
        @Override
        public int traverse(Visitproc visit, Object arg) {
            int retVal = super.traverse(visit, arg);
            if (retVal != 0) {
                return retVal;
            }
            return traverseNode(lastReturned, Visitproc visit, Object arg);
        }

        @Override
        public boolean refersDirectlyTo(PyObject ob) throws UnsupportedOperationException {
            if (ob == null) {
                return false;
            } else if (super.refersDirectlyTo(ob)) {
                return true;
            } else {
                throw new UnsupportedOperationException();
            }
        }
    }


    /* Traverseproc implementation */
    private synchronized int traverseNode(Node node, Visitproc visit, Object arg) {
        if (node == null) {
            return 0;
        }
        int retVal = 0;
        if (node.data != null) {
            retVal = visit.visit(node.data, arg);
            if (retVal != 0) {
                return retVal;
            }
        }
        Node tmp = node.right;
        while (tmp != node) {
            if (tmp.data != null) {
                retVal = visit.visit(tmp.data, arg);
                if (retVal != 0) {
                    return retVal;
                }
            }
            tmp = tmp.right;
        }
        return retVal;
    }

    @Override
    public int traverse(Visitproc visit, Object arg) {
        return traverseNode(header, visit, arg);
    }
 ...
History
Date User Action Args
2015-04-24 17:02:36stefan.richthofersetmessageid: <1429894956.76.0.963903202678.issue2337@psf.upfronthosting.co.za>
2015-04-24 17:02:36stefan.richthofersetrecipients: + stefan.richthofer, jmadden
2015-04-24 17:02:36stefan.richthoferlinkissue2337 messages
2015-04-24 17:02:36stefan.richthofercreate