Hi people!

As I was looking at the solr source code the other day, I noticed the following:

public abstract class RefCounted<Type> {
[...]
public final RefCounted<Type> incref() { refcount.incrementAndGet (); return this; }
  public void decref() { if (refcount.decrementAndGet()==0) close(); }
  protected abstract void close();
[...]
}

The implementation for close() supposedly invalidates the contents of the field resource (in
this case a SolrIndexSearcher, but that's not the point).

I believe there is a race condition between incref() and decref(). Consider these events:
Thread A acquires an RefCounted object, refcount is 1
Thread A calls decref(), decrementAndGet() sets refcount to 0, "if" condition is true before Thread A enters close(), Thread B acquires the same instance of the refcounted object
  and calls incref().
Thread A increases refcount to 1 and returns the refcounted object
Thread B continues to close() and thus invalidates the resource which Thread A now tries to use
things break.

Is my reasoning correct? My fear is that I slowly get paranoid ;)
If so (not the paranoid part), what would be your suggestion to fix this? Adding locks around incrementAndGet() and decrementAndGet(), close() somewhat defeats the elegance of RefCounted. One might play tricks with various checks of refcount, but I haven't
completely thought that one through yet, so it might not work at all.

cheers,

-k

--
Kay Röpke
http://www.epublica.de

epublica GmbH, Gänsemarkt 43, 20354 Hamburg, Tel. +49 (0)40/4109879-0
GF: Heiner Jürgensen, Michael Otto, Norbert Schuler, Hanno Zulla
Registergericht: Amtsgericht Hamburg, HRB 89162



Reply via email to