Please find attached a changeset to address the problem reported in
bug 6927486, "Deadlock in legacy Hashtable writeObject()".

The problem reported is similar to one found in java.util.Vector, for
which a fix is also currently under review
(http://mail.openjdk.java.net/pipermail/core-libs-dev/2010-December/005529.html).

This fixes approach is similar to that in Vector - namely to record
the objects to be serialized within the synchronization in
Hashtable.writeObject(), so that the calls to writeObject() in that
method can be moved to beyond the synchronization, thus avoiding the
possibility of deadlock.

(The calls to writeObject() - for the keys and value of the
hashtable's entries - are the last activity within
Hashtable.writeObject(), so no additional calls need be delayed).

The keys and values to be written out are recorded in a stack of Entry
objects, created specially for the task to form a local single-linked
list of entries, which is then traversed outside the synchronized
block to make the calls to s.writeObject() with each entry's key and
value.

I believe this is the most efficient means of addressing the problem -
any suggestions on how to further improve it gratefully received.

As the order of writing out the entries has effectively changed from
FIFO to LIFO (as it uses a stack), I have reversed the order the code
traverses the table (from low index to high).

(I note that the API doc explicitly gives no guarantees as to the
order the entries are serialized. Nevertheless, as the initial
traversal order was the more uncommon of the two forms, I suspect that
there might be some deeper reasoning as to why it was done that way,
hence why I've tried to retain its spirit).

Any reviews or comment gratefully received,
Thanks,
Neil

PS:
The evaluation of this bug suggests that java.util.Random and
java.util.PropertyPermission may also be susceptible to serialization
deadlock (ie. in addition to Vector and Hashtable).

I do not believe this to be case: whilst their writeObject() methods
are synchronized, neither class needs to call
ObjectOutputStream.writeObject() within them, so the possibility of
deadlock there cannot arise.

PPS:
I notice the API javadoc for PropertyPermission does not give its
serialized form (and the "See Also:" section), even though it is
Serializable, which strikes me as unusual.

I suppose it has no serializable fields of its own (over that which
BasicPermission has), but I'm sure I've seen other serializable
classes with no fields having "serialized form" entries.

--
Unless stated above:
IBM email: neil_richards at uk.ibm.com
IBM United Kingdom Limited - Registered in England and Wales with number 741598.
Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU

Attachment: 6927486.export
Description: Binary data

Reply via email to