Program: 113375
Project: 113375
Buggy source:
/** 
 * Invalidate the majority of the replicas listed in xLocList. Will sleep until the lease has timed out if the primary didn't respond.
 * @param fileId
 * @param capability
 * @param xLocSet
 * @param numAcksRequired
 * @throws InterruptedException
 * @throws MRCException
 */
private ReplicaStatus[] invalidateReplicas(String fileId,Capability cap,XLocSet xLocSet,int numAcksRequired) throws InterruptedException, MRCException {
  @SuppressWarnings("String_Node_Str") final RPCResponse<xtreemfs_xloc_set_invalidateResponse>[] responses=new RPCResponse[xLocSet.getReplicasCount()];
  OSDServiceClient client=master.getOSDClient();
  FileCredentials creds=FileCredentials.newBuilder().setXcap(cap.getXCap()).setXlocs(xLocSet).build();
  for (int i=0; i < responses.length; i++) {
    ServiceUUID OSDServiceUUID=new ServiceUUID(Helper.getOSDUUIDFromXlocSet(xLocSet,i,0));
    try {
      responses[i]=client.xtreemfs_xloc_set_invalidate(OSDServiceUUID.getAddress(),RPCAuthentication.authNone,RPCAuthentication.userService,creds,fileId);
    }
 catch (    IOException ex) {
      if (Logging.isDebug()) {
        Logging.logError(Logging.LEVEL_DEBUG,this,ex);
      }
    }
  }
  /** 
 * This local class is used to collect responses to the asynchronous invalidate requests. <br> It counts the number of errors and successful requests and stores an array of returned ReplicaStatus and a flag indicating if the primary did respond.
 */
class InvalidatedResponseListener implements RPCResponseAvailableListener<xtreemfs_xloc_set_invalidateResponse> {
    private int numResponses=0;
    private int numErrors=0;
    private boolean primaryResponded=false;
    private RPCResponse<xtreemfs_xloc_set_invalidateResponse>[] responses;
    private ReplicaStatus[] states;
    public InvalidatedResponseListener(    RPCResponse<xtreemfs_xloc_set_invalidateResponse>[] responses){
      this.responses=responses;
      states=new ReplicaStatus[responses.length];
      for (int i=0; i < responses.length; i++) {
        responses[i].registerListener(this);
      }
    }
    @Override synchronized public void responseAvailable(    RPCResponse<xtreemfs_xloc_set_invalidateResponse> r){
      int osdNum=-1;
      for (int i=0; i < responses.length; i++) {
        if (responses[i] == r) {
          osdNum=i;
          break;
        }
      }
      assert(osdNum > -1);
      try {
        xtreemfs_xloc_set_invalidateResponse response=r.get();
        if (response.hasStatus()) {
          states[osdNum]=response.getStatus();
        }
        if (response.getIsPrimary()) {
          primaryResponded=true;
        }
        numResponses++;
      }
 catch (      Exception ex) {
        numErrors++;
        Logging.logMessage(Logging.LEVEL_DEBUG,Category.replication,this,"String_Node_Str",ex.toString());
      }
 finally {
        r.freeBuffers();
        this.notifyAll();
      }
    }
    synchronized ReplicaStatus[] getReplicaStates(){
      ReplicaStatus[] result=new ReplicaStatus[states.length];
      System.arraycopy(states,0,result,0,states.length);
      return result;
    }
  }
  InvalidatedResponseListener listener=new InvalidatedResponseListener(responses);
  int numMaxErrors=responses.length - numAcksRequired;
synchronized (listener) {
    while (listener.numResponses < numAcksRequired) {
      listener.wait();
      if (listener.numErrors > numMaxErrors) {
        throw new MRCException("String_Node_Str");
      }
    }
  }
  long now=System.currentTimeMillis();
  long leaseEndTimeMs=now + leaseToMS;
synchronized (listener) {
    while (!listener.primaryResponded && now < leaseEndTimeMs && (listener.numResponses + listener.numErrors) < responses.length) {
      listener.wait(leaseEndTimeMs - now);
      now=System.currentTimeMillis();
    }
  }
  ReplicaStatus[] states=listener.getReplicaStates();
  return states;
}

Fixed version (ground truth):
/** 
 * Invalidate the majority of the replicas listed in xLocList. Will sleep until the lease has timed out if the primary didn't respond.
 * @param fileId
 * @param capability
 * @param xLocSet
 * @param numAcksRequired
 * @throws InterruptedException
 * @throws MRCException
 */
private ReplicaStatus[] invalidateReplicas(String fileId,Capability cap,XLocSet xLocSet,int numAcksRequired) throws InterruptedException, MRCException {
  @SuppressWarnings("String_Node_Str") final RPCResponse<xtreemfs_xloc_set_invalidateResponse>[] responses=new RPCResponse[xLocSet.getReplicasCount()];
  OSDServiceClient client=master.getOSDClient();
  FileCredentials creds=FileCredentials.newBuilder().setXcap(cap.getXCap()).setXlocs(xLocSet).build();
  for (int i=0; i < responses.length; i++) {
    ServiceUUID OSDServiceUUID=new ServiceUUID(Helper.getOSDUUIDFromXlocSet(xLocSet,i,0));
    try {
      responses[i]=client.xtreemfs_xloc_set_invalidate(OSDServiceUUID.getAddress(),RPCAuthentication.authNone,RPCAuthentication.userService,creds,fileId);
    }
 catch (    IOException ex) {
      if (Logging.isDebug()) {
        Logging.logError(Logging.LEVEL_DEBUG,this,ex);
      }
      throw new MRCException(ex);
    }
  }
  /** 
 * This local class is used to collect responses to the asynchronous invalidate requests. <br> It counts the number of errors and successful requests and stores an array of returned ReplicaStatus and a flag indicating if the primary did respond.
 */
class InvalidatedResponseListener implements RPCResponseAvailableListener<xtreemfs_xloc_set_invalidateResponse> {
    private int numResponses=0;
    private int numErrors=0;
    private boolean primaryResponded=false;
    private RPCResponse<xtreemfs_xloc_set_invalidateResponse>[] responses;
    private ReplicaStatus[] states;
    public InvalidatedResponseListener(    RPCResponse<xtreemfs_xloc_set_invalidateResponse>[] responses){
      this.responses=responses;
      states=new ReplicaStatus[responses.length];
      for (int i=0; i < responses.length; i++) {
        responses[i].registerListener(this);
      }
    }
    @Override synchronized public void responseAvailable(    RPCResponse<xtreemfs_xloc_set_invalidateResponse> r){
      int osdNum=-1;
      for (int i=0; i < responses.length; i++) {
        if (responses[i] == r) {
          osdNum=i;
          break;
        }
      }
      assert(osdNum > -1);
      try {
        xtreemfs_xloc_set_invalidateResponse response=r.get();
        if (response.hasStatus()) {
          states[osdNum]=response.getStatus();
        }
        if (response.getIsPrimary()) {
          primaryResponded=true;
        }
        numResponses++;
      }
 catch (      Exception ex) {
        numErrors++;
        Logging.logMessage(Logging.LEVEL_DEBUG,Category.replication,this,"String_Node_Str",ex.toString());
      }
 finally {
        r.freeBuffers();
        this.notifyAll();
      }
    }
    synchronized ReplicaStatus[] getReplicaStates(){
      ReplicaStatus[] result=new ReplicaStatus[states.length];
      System.arraycopy(states,0,result,0,states.length);
      return result;
    }
  }
  InvalidatedResponseListener listener=new InvalidatedResponseListener(responses);
  int numMaxErrors=responses.length - numAcksRequired;
synchronized (listener) {
    while (listener.numResponses < numAcksRequired) {
      listener.wait();
      if (listener.numErrors > numMaxErrors) {
        throw new MRCException("String_Node_Str");
      }
    }
  }
  long now=System.currentTimeMillis();
  long leaseEndTimeMs=now + leaseToMS;
synchronized (listener) {
    while (!listener.primaryResponded && now < leaseEndTimeMs && (listener.numResponses + listener.numErrors) < responses.length) {
      listener.wait(leaseEndTimeMs - now);
      now=System.currentTimeMillis();
    }
  }
  ReplicaStatus[] states=listener.getReplicaStates();
  return states;
}