Hi Kay,
You are right for general usage of RefCounted... I should probably add
a comment to that class.
Solr as a whole doesn't have a problem though because other locking
ensures that once the refcount reaches 0, no one will increment it
again.
SolrCore holds a reference itself, and only calls decref in
SolrCore.registerSearcher() which is synchronized on searcherLock.
Once the refcount is 0, there will be another registered searcher that
will be handed out (incref()).

-Yonik

On 5/29/07, Kay Röpke <[EMAIL PROTECTED]> wrote:
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

Reply via email to