On Fri, 16 Jun 2023 12:45:58 GMT, Weijun Wang <wei...@openjdk.org> wrote:

>> src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java line 
>> 1438:
>> 
>>> 1436: 
>>> 1437:         if (entry.attributes == null) {
>>> 1438:             entry.attributes = ConcurrentHashMap.newKeySet();
>> 
>> It seems that there is still a risk that two threads may compete here, then 
>> you may end up with one thread working with a different copy of the 
>> attributes, no longer tied to the entry. E.g:
>> 
>> Thread#1 sees attributes is null, Thread#2 sees attributes is null, both set 
>> attributes and only one of them win. The caller in the second thread (that 
>> lost) is given the "dangling" map that has not been set, and if it modifies 
>> it then modifications will be lost.
>> I don't know if this scenario can actually happen - but the possibility is 
>> there. Unless there's always some locking further up the stack that would 
>> prevent this?
>> 
>> Also I see in total four places that do:
>> 
>> [entry|this].attributes = new HashSet<>();
>> 
>> 
>> wouldn't you need to modify all four places in the same manner?
>
> Correct. Done.
> 
> I'll look into making the classes immutable in the next release. I hesitate 
> to make such a big change in RDP.

I wonder if this would work, if you don't want to use final or volatile + CAS:


 class Entry { 
     ...
     private Set<KeyStore.Entry.Attribute> createAttributesMap() {
          synchronized (this) {
              var attributes = this.attributes;
              if (attributes == null) {
                  return attributes = this.attributes = 
ConcurrentHashMap.newKeySet();
              } else return attributes;
           }
       }
       
 }
 
 ...
 
      if (entry.attributes == null) {
          entry.attributes = entry.createAttributesMap();
      }

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/14506#discussion_r1232315157

Reply via email to