[ 
https://issues.apache.org/jira/browse/HBASE-14279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14716135#comment-14716135
 ] 

Hiroshi Ikeda commented on HBASE-14279:
---------------------------------------

{code}
  public void put(K key, V value) {
    ...
    Pair<Object, Set<V>> existing = container.putIfAbsent(key, lockAndSet);
    if (existing != null) {
      synchronized (existing.getFirst()) {
        existing = container.get(key); //Re check if the key is associate with 
the set.
        ...
{code}

I think you recognize that, the element given from {{container.putIfAbset}} 
might be removed the next moment, so that you lock and re-check. But in that 
case you just lock the obsolete object that is already removed from the 
container, and you cannot prevent the other overtaking threads from replacing 
the element.

Even if you would again lock the object inside the re-checked element, the 
rechecked element may be also removed from the container the next moment for 
the same reason, and the code should be as follows:

{code}
  public void put(K key, V value) {
    ...
    Pair<Object, Set<V>> existing = container.putIfAbsent(key, lockAndSet);
    if (existing != null) {
      synchronized (existing.getFirst()) {
        existing = container.putIfAbsent(key, lockAndSet);

        if (existing != null) {
          synchronized (existing.getFirst()) {
            existing = container.putIfAbsent(key, lockAndSet);
            ...

            (It continues to infinity.)
{code}

After all, you cannot atomically add/remove elements with some additional 
processing under locking objects inside the container.


> Race condition in ConcurrentIndex
> ---------------------------------
>
>                 Key: HBASE-14279
>                 URL: https://issues.apache.org/jira/browse/HBASE-14279
>             Project: HBase
>          Issue Type: Bug
>            Reporter: Hiroshi Ikeda
>            Assignee: Heng Chen
>            Priority: Minor
>         Attachments: HBASE-14279.patch
>
>
> {{ConcurrentIndex.put}} and {{remove}} are in race condition. It is possible 
> to remove a non-empty set, and to add a value to a removed set. Also 
> {{ConcurrentIndex.values}} is vague in sense that the returned set sometimes 
> trace the current state and sometimes doesn't.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to