/** * <p> * Decrements the reference count by n. * </p><p> * An object is asynchronously disposed once all references are * released. Using a disposed object will cause undefined errors. * The system does not guarantee that a given client is the last or * only reference to a given object. * </p> * @param n */ final protected void release(int n) { if( TRACE ) { synchronized(traces) { assertRetained(); int x = retained.addAndGet(-n); trace("released "+n, x); if ( x == 0) { trace("disposed", x); dispose(); } } } else { assertRetained(); if (retained.addAndGet(-n) == 0) { dispose(); } } }
/** * <p> * Increment the reference count of this object. * </p> * * Calls to {@link #retain()} must be balanced with calls to * {@link #release()}. */ final public void retain() { if( TRACE ) { synchronized(traces) { assertRetained(); final int x = retained.incrementAndGet(); trace("retained", x); } } else { assertRetained(); retained.getAndIncrement(); } }
/** * <p> * Adds a disposer runnable that is executed once the object is disposed. * </p><p> * A dispatch object's disposer runnable will be invoked on the object's target queue * once the object's retain counter reaches zero. This disposer may be * used by the application to release any resources associated with the object. * </p> * * @param disposer */ final public void setDisposer(Task disposer) { assertRetained(); this.disposer = disposer; }
/** * <p> * Adds a disposer runnable that is executed once the object is disposed. * </p><p> * A dispatch object's disposer runnable will be invoked on the object's target queue * once the object's retain counter reaches zero. This disposer may be * used by the application to release any resources associated with the object. * </p> * * @param disposer */ final public void setDisposer(final Runnable disposer) { this.setDisposer(new TaskWrapper(disposer)); }
final private void trace(final String action, final int counter) { if( traces.size() < MAX_TRACES) { Exception ex = new Exception() { public String toString() { return "Trace "+(traces.size()+1)+": "+action+", counter: "+counter+", thread: "+Thread.currentThread().getName(); } }; String squashed = squash(ex.getStackTrace()); if( squashed == null ) { StringWriter sw = new StringWriter(); ex.printStackTrace(new PrintWriter(sw)); traces.add("\n"+sw); } // else { // traces.add("\n"+ex.toString()+"\n at "+squashed+"\n"); // } } else if (traces.size() == MAX_TRACES) { traces.add("MAX_TRACES reached... no more traces will be recorded."); } }
/** * <p> * Decrement the reference count of this object. * </p><p> * An object is asynchronously disposed once all references are * released. Using a disposed object will cause undefined errors. * The system does not guarantee that a given client is the last or * only reference to a given object. * </p> */ final public void release() { if( TRACE ) { synchronized(traces) { assertRetained(); final int x = retained.decrementAndGet(); trace("released", x); if (x == 0) { dispose(); trace("disposed", x); } } } else { assertRetained(); if (retained.decrementAndGet() == 0) { dispose(); } } }