Package freenet.node

Source Code of freenet.node.MultiMessageCallback

package freenet.node;

import freenet.io.comm.AsyncMessageCallback;

/** Waits for multiple asynchronous message sends, then calls finish(). */
public abstract class MultiMessageCallback {
 
  private int waiting;
  private int waitingForSend;
 
  private boolean armed;
 
  private boolean someFailed;
 
  /** This is called when all messages have been acked, or failed */
  abstract void finish(boolean success);
 
  /** This is called when all messages have been sent (but not acked) or failed to send */
  abstract void sent(boolean success);

  public AsyncMessageCallback make() {
    synchronized(this) {
      AsyncMessageCallback cb = new AsyncMessageCallback() {

        private boolean finished;
        private boolean sent;
       
        @Override
        public void sent() {
          boolean success;
          synchronized(MultiMessageCallback.this) {
            if(finished || sent || !armed) return;
            sent = true;
            waitingForSend--;
            if(waitingForSend > 0) return;
            success = !someFailed;
          }
          MultiMessageCallback.this.sent(success);
        }

        @Override
        public void acknowledged() {
          complete(true);
        }

        @Override
        public void disconnected() {
          complete(false);
        }

        @Override
        public void fatalError() {
          complete(false);
        }
       
        private void complete(boolean success) {
          boolean callSent = false;
          synchronized(MultiMessageCallback.this) {
            if(finished) return;
            if(!sent) {
              sent = true;
              waitingForSend--;
              if(waitingForSend == 0)
                callSent = true;
            }
            if(!success) someFailed = true;
            finished = true;
            waiting--;
            if(!finished()) return;
            if(someFailed) success = false;
          }
          if(callSent)
            MultiMessageCallback.this.sent(success);
          finish(success);
        }
       
      };
      waiting++;
      waitingForSend++;
      return cb;
    }
  }

  public void arm() {
    boolean success;
    boolean callSent = false;
    boolean complete = false;
    synchronized(this) {
      armed = true;
      complete = waiting == 0;
      if(waitingForSend == 0) callSent = true;
      success = !someFailed;
    }
    if(callSent) sent(success);
    if(complete) finish(success);
  }
 
  protected final synchronized boolean finished() {
    return armed && waiting == 0;
  }

}
TOP

Related Classes of freenet.node.MultiMessageCallback

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.