Commits on May 20, 2015
  1. Fix some broken links.

    tsuna committed May 20, 2015
  2. Fix deadlock on join() timeout.

    tsuna committed May 20, 2015
    This closes #4.
Commits on Aug 1, 2013
  1. Release v1.4.0.

    tsuna committed Aug 1, 2013
Commits on Jul 20, 2013
Commits on Jun 17, 2013
  1. Release v1.3.3.

    tsuna committed Jun 17, 2013
  2. Fix the type signature of the group() methods.

    tsuna committed Jun 17, 2013
    This is a compatible API change.
Commits on May 30, 2013
  1. Release 1.3.2.

    tsuna committed May 30, 2013
Commits on May 22, 2013
  1. Fix a race condition in Deferred.toString()

    tsuna committed May 22, 2013
    The `result' field was checked against `null' and then used.  However
    this field can change at any time, so we must first copy it into a local
    variable to make sure it doesn't become `null' at an incongruous moment,
    which could cause a `NullPointerException'.  This issue is especially
    likely to occur when a `TimeoutException' is raised roughly at the same
    time as the `result' field is being updated by a callback.
    Bug reported by Viral Bajaria.
  2. Start version 1.3.2.

    tsuna committed May 22, 2013
Commits on Nov 11, 2012
Commits on Nov 4, 2012
  1. Release v1.3.1.

    tsuna committed Nov 4, 2012
  2. Enforce the correct limit on the size of the callback chain.

    tsuna committed Nov 4, 2012
    The fix in c0aed96 wasn't done right, and was effectively limiting
    the length of the callback chain to 8192 callbacks, instead of 16383.
Commits on Oct 29, 2012
  1. Release v1.3.0.

    tsuna committed Oct 29, 2012
  2. Prepare for the v1.3.0 release.

    tsuna committed Oct 29, 2012
  3. Update URL of JDK6 Javadoc.

    tsuna committed Oct 29, 2012
  4. Update copyright information.

    tsuna committed Oct 29, 2012
  5. Properly raise a StackOverflowError when too many callbacks are chained.

    tsuna committed Oct 29, 2012
    The check was incorrect and could never trigger, and instead an
    ArrayIndexOutOfBoundsException would be raised later when a short
    value would wrap around.
    Thanks to Nick Telford for reporting the bug.
Commits on Apr 9, 2012
  1. Release v1.2.0.

    tsuna committed Apr 9, 2012
    Change-Id: Ie4d2be7df718bdb70562d15468b2c5a01ece8eda
  2. Prepare for the 1.2.0 release.

    tsuna committed Apr 9, 2012
    Change-Id: I087319196ca7844099ef75b59c0756dd749e6acb
Commits on Apr 8, 2012
  1. Allow up to 16383 callbacks on a Deferred.

    tsuna committed Apr 8, 2012
    Change-Id: I9f9a7fb5110f693db6813c0b8a62f0d03b896a1e
  2. Keep the state of a Deferred in a plain int.

    tsuna committed Apr 8, 2012
    Change-Id: Ib87d90cb8d7a45dc438548ae0ae57479af39aa3d
Commits on Mar 6, 2012
  1. Have distclean remove Maven's target directory.

    tsuna committed Mar 6, 2012
    Change-Id: Id0c80994ba3cf6f120ed6d0d5782abaecc06a56d
  2. Use `:='.

    tsuna committed Mar 6, 2012
    Change-Id: I46350478e2578e50b0cb95881eb2ccdca43b8195
  3. Maven SDL compatibility & plugin updates.

    bdd authored and tsuna committed Mar 6, 2012
    maven-sources-plugin simply jars the sourceDirectory to create the
    -sources artifact. We don't have empty dirs for the package path and
    there's no way to configure maven-sources-plugin to prepend path.
    Create a .mvn-compat directory at top level and symlink it
    src/main/java/<pkg-path> to top level src/ directory.
    Update's `' with the new `sourceDirectory' and while there
    add the missing version decleration to maven-sources-plugin and update
    This closes #1.
    Change-Id: Ibd0a7b8a166de84004b248e16a3786ef95c0c680
    Signed-off-by: Benoit Sigoure <>
Commits on Jan 28, 2012
  1. Start version 1.2.0.

    tsuna committed Jan 28, 2012
    Change-Id: I04fe0b90c4c9b71aae45ed9c96a4105018a9b878
  2. Generate pom.xml from Makefile.

    tsuna committed Jan 28, 2012
    Change-Id: I1e3e4ba409116d8bef9b2d09d0708260fb9c5c33
  3. Mavenize with no impact to dir hierarchy

    bdd authored and tsuna committed Nov 26, 2011
    SU Async will be available from Maven Central so projects depending on
    it and building with Maven, Ant+Ivy2 or SBT can easily get it.
    Likewise Asynchronous HBase client is being mavenized.
    This is the initial public release of POM and seeking community
    Change-Id: I50faee3bd08a79ba886f307d1e1374eac7a76dd3
Commits on Sep 27, 2011
  1. Release v1.1.0.

    tsuna committed Sep 27, 2011
    Change-Id: Id3142f69074ceaebc7f190e861dd7e2dad55b21f
  2. Add support for timed synchronous joins.

    tsuna committed Sep 25, 2011
    New API: The `join()' and `joinUninterruptibly()' methods now have an
    overloaded version that accepts a timeout in milliseconds and throws
    the new TimeoutException when a timed join times out.
    Change-Id: If8c01ef0bdfa0c5cd6d558a0da35ea1ff43283d3
  3. Use a single array instead of 2 LinkedList for callbacks.

    tsuna committed Sep 25, 2011
    In retrospect, using LinkedList was a bad idea because of the insane
    amount of memory overhead it has, especially in Java.  An array can
    provide the same O(1) tail insertion (amortized), O(1) head removal,
    while using far less RAM.
    Heap dumps in OpenTSDB frequently show a lot of memory used just for
    the LinkedList head and for each LinkedList$Entry.
    On x86-64, with Sun's JVM 1.6.x, this yields the following savings:
      - First callback added costs an extra 32 bytes of RAM, instead of
        144 bytes with the LinkedList implementation.
      - Second callback added doesn't cost anything extra, whereas the
        LinkedList implementation adds 48 bytes of overhead per callback.
    For a typical Deferred with 2 callbacks, this translates into 160 bytes
    of RAM saved per instance.
    This change also improves CPU cache efficiency since now all the
    references to the callbacks are in the same cacheline (or contiguous
    cachelines).  The end result is that a benchmark that creates 100k
    Deferred, with an equal number of Deferred with 1, 2, 3, 4 and 5
    callbacks, and calls them all back runs 14-15% faster on a dual Intel
    E5520, 12-16% faster on dual Intel L5630.
    Change-Id: I1c5e487947fe6e478940f16172bf90a1e4021298
  4. Start version 1.1.0.

    tsuna committed Sep 25, 2011
    Change-Id: I6095fc86de443d5cc6b14e99ae03a0a29a051dee
Commits on Oct 29, 2010
  1. Optimization: don't wait on a Deferred already in State.DONE.

    tsuna committed Oct 26, 2010
    When a Callback returned a Deferred already in State.DONE, the current
    Deferred was paused and immediately resumed, which involved the creation
    of an unnecessary Continue callback and other objects.  We now bypass
    this entire code path, which helps in the cases where a Callback returns
    a Deferred built with Deferred.fromResult or Deferred.fromError, or if a
    real Deferred completes so quickly that we directly see it in State.DONE.
    Change-Id: I710266e05b5f37d676018f706c923ecafa276ffc
Commits on Oct 16, 2010
  1. Fix a race condition when adding a callback.

    tsuna committed Oct 16, 2010
    The following "unlucky execution" could happen:
     Deferred in state RUNNING.
     Thread A (in runCallbacks)                 | Thread B (in addCallbacks)
       complete execution of the last callback  |   CAS state DONE -> RUNNING fails
       acquire this' monitor                    |
       observe that the callback chain is empty |
       set state to DONE                        |
       null out callback chains                 |
       release this' monitor                    |
                                                |   acquire this' monitor
    					    |   queue the new callbacks
    					    |   release this' monitor
    Now Thread B left the Deferred in state DONE with a callback in the
    chain that will never be called unless another callback is added to it.
    The fix consists in swapping the CAS and the acquisition of this'
    monitor in addCallbacks.  In the unlucky timing above, this could
    have 2 possible outcomes:
      1. Thread A acquires this' monitor first and then thread B's CAS
         will succeed, so B will keep executing the callback chain.
      2. Thread B acquires this' monitor first and queues the new
         callbacks, then thread A will execute them.
    When swapping the CAS and the acquisition of this' monitor, the CAS
    becomes unnecessary and can be replaced with a regular volatile-read
    followed by a regular volatile-write.  The purpose of the CAS was
    originally to avoid acquiring this' monitor when it wasn't necessary
    but this "optimization" wasn't even effective since the most common
    code path is to add a callback to a Deferred in state PENDING, and
    this code path always needed a failed CAS + monitor acquisition.
    Change-Id: I365cec225e9d15aa09280ce066bf11ce56c1d358