[ https://issues.apache.org/jira/browse/ZOOKEEPER-2141?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15216993#comment-15216993 ]
Edward Ribeiro commented on ZOOKEEPER-2141: ------------------------------------------- Hi [~adammilnesmith] and [~fournc], I am *really* sorry for only having (limited) time to review/check this patch after it has been committed to trunk. :( So, please, take it more like a couple of highlights, if you like. The patch is really cool, and great work, but I have seen some things that raised some questions I would like to point, plus a couple of minor (i.e., irrelevant) issues. 1. The piece of code below, from {{ReferenceCountedACLCache}}, worried me a bit: {code} public synchronized boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ReferenceCountedACLCache that = (ReferenceCountedACLCache) o; synchronized (that) { if (aclIndex != that.aclIndex) return false; } (...) {code} See, we are acquiring a lock of object {{foo1}} and then acquiring the lock of object {{foo2}} ({{that}}, in this case) inside it. My question is: wouldn't this potentially leads to a DEADLOCK? I mean, imagine a situation below, or something alike: {code} Thread-1: foo1.equals(foo2); Thread-2: foo2.equals(foo1); {code} I guess that with the *right thread interleaving*, it could lead to a deadlock. I was so amused by this possibility that wrote a dummy snippet to evaluate this, as you can see here (with appropriate insertion of {{Thread.sleeps}} to reproduce the desired interleaving): https://gist.github.com/eribeiro/bd2aca6fbae0255b64ba0b4f896e6a8d and got some runs to successfully reproduce a deadlock as seen here: https://gist.github.com/eribeiro/96f95b295a4b90c0d261057d4542063a Disclaimer: maybe this situation NEVER happens in this particular case (if so, sorry for disturbing you, *really*), but I thought it was worth mentioning. ;) I *guess* a possible solution would be to make {{aclIndex}} a {{volatile}} variable as a "lightweight" alternative to {{synchronized}}, right? Volatile makes has a happens before semantic and it prevents reordering of statements. Wdyt? 2. The inherited code has the following snippet (now moved to {{ReferenceCountedACLCache}}): {code} public synchronized Long convertAcls(List<ACL> acls) { if (acls == null) return -1L; {code} What if the acls list is empty, i.e., {{acls = new ArrayList<>()}}? It's okay to cache an empty ACL {{List}} or could we just change the lines above to: {code} public synchronized Long convertAcls(List<ACL> acls) { if (acls == null || acls.isEmpty()) return -1L; {code} Again, this can NEVER happen in this case above so, I am all for letting it as-is today. :) 3. The comment in the following snippet seems a bit out of date (list of longs???): {code} /** * converts the list of acls to a list of longs. * Increments the reference counter for this ACL. * @param acls * @return a list of longs that map to the acls */ public synchronized Long convertAcls(List<ACL> acls) { {code} 4. AtomicLongWithEquals extends AtomicLong. I failed to see a _good_ reason to create a custom AtomicLong, as its instances are not used as keys. What is the rationale behind this? Disclaimer: IMO, extending a j.u. library is an anti-pattern as we don't have control over it and future changes in the parent class can easily break the codebase. 5. ReferenceCountedACLCache.OPEN_UNSAFE_ACL_ID could be made static besides being final. 6. ReferenceCountedACLCacheTest#convertACLsNTimes performs n-1 convertions as seen here (see the ``<`` and the ``-1``): {code} for (int i = 0; i < num -1; i++) { cache.convertAcls(acl); } {code} Is this the intended behaviour? There are other irrelevant observations, but I will refrain myself from citing them by now. Cheers! Eddie > ACL cache in DataTree never removes entries > ------------------------------------------- > > Key: ZOOKEEPER-2141 > URL: https://issues.apache.org/jira/browse/ZOOKEEPER-2141 > Project: ZooKeeper > Issue Type: Bug > Affects Versions: 3.4.6 > Reporter: Karol Dudzinski > Assignee: Adam Milne-Smith > Fix For: 3.4.9, 3.5.2 > > Attachments: ZOOKEEPER-2141-3.4.patch, ZOOKEEPER-2141.patch, > ZOOKEEPER-2141.patch, ZOOKEEPER-2141.patch, ZOOKEEPER-2141.patch, > ZOOKEEPER-2141.patch > > > The problem and potential solutions are discussed in > http://mail-archives.apache.org/mod_mbox/zookeeper-user/201502.mbox/browser > I will attach a proposed patch in due course. -- This message was sent by Atlassian JIRA (v6.3.4#6332)