Program: 29202
Project: 29202
Buggy source:
private boolean checkCache(Permission p,Epoch e){
  rLock.lock();
  try {
    if (loading) {
      return false;
    }
 else     if (cache != null) {
      return checkLoadedCache(p,e);
    }
  }
  finally {
    rLock.unlock();
  }
  wLock.lock();
  if (loading) {
    wLock.unlock();
    return false;
  }
 else   if (cache != null) {
    rLock.lock();
    wLock.unlock();
    try {
      return checkLoadedCache(p,e);
    }
  finally {
      rLock.unlock();
    }
  }
 else {
    cache=null;
    loading=true;
    wLock.unlock();
  }
  Permissions nextCache=new Permissions();
  boolean setPc=false;
  String oldpcID=null;
  try {
    oldpcID=PolicyContext.getContextID();
    if (this.pcID == null || !this.pcID.equals(oldpcID)) {
      setPc=true;
    }
  }
 catch (  Exception ex) {
    _logger.log(Level.SEVERE,"String_Node_Str",ex);
    return false;
  }
  PermissionCollection pc=null;
  try {
    if (setPc) {
      setPolicyContextID(this.pcID);
    }
    pc=policy.getPermissions(this.codesource);
  }
 catch (  Exception ex) {
    _logger.log(Level.SEVERE,"String_Node_Str",ex);
    return false;
  }
 finally {
    if (setPc) {
      try {
        setPolicyContextID(oldpcID);
      }
 catch (      Exception ex) {
        _logger.log(Level.SEVERE,"String_Node_Str",ex);
        return false;
      }
    }
  }
  resolvePermissions(pc,p);
  Enumeration granted=pc.elements();
  while (granted.hasMoreElements()) {
    Permission i=(Permission)granted.nextElement();
    if (i.equals(allPermission)) {
      nextCache.add(i);
    }
 else {
      boolean classMatch=true;
      if (this.classes != null) {
        classMatch=false;
        Class iClazz=i.getClass();
        for (int j=0; j < this.classes.length; j++) {
          if (this.classes[j].equals(iClazz)) {
            classMatch=true;
            break;
          }
        }
      }
      if (classMatch) {
        if (this.name != null) {
          String iName=i.getName();
          if (iName != null && this.name.equals(iName)) {
            nextCache.add(i);
          }
        }
 else {
          nextCache.add(i);
        }
      }
    }
  }
  wLock.lock();
  cache=nextCache;
  loading=false;
  try {
    rLock.lock();
    wLock.unlock();
    return checkLoadedCache(p,e);
  }
  finally {
    rLock.unlock();
  }
}

Fixed version (ground truth):
private boolean checkCache(Permission p,Epoch e){
  rLock.lock();
  try {
    if (loading) {
      return false;
    }
 else     if (cache != null) {
      return checkLoadedCache(p,e);
    }
  }
  finally {
    rLock.unlock();
  }
  wLock.lock();
  try {
    if (loading) {
      return false;
    }
 else     if (cache != null) {
      rLock.lock();
      wLock.unlock();
      wLock=null;
      try {
        return checkLoadedCache(p,e);
      }
  finally {
        rLock.unlock();
      }
    }
 else {
      cache=null;
      loading=true;
    }
  }
  finally {
    if (wLock != null)     wLock.unlock();
    rLock.unlock();
  }
  Permissions nextCache=new Permissions();
  boolean setPc=false;
  String oldpcID=null;
  try {
    oldpcID=PolicyContext.getContextID();
    if (this.pcID == null || !this.pcID.equals(oldpcID)) {
      setPc=true;
    }
  }
 catch (  Exception ex) {
    _logger.log(Level.SEVERE,"String_Node_Str",ex);
    return false;
  }
  PermissionCollection pc=null;
  try {
    if (setPc) {
      setPolicyContextID(this.pcID);
    }
    pc=policy.getPermissions(this.codesource);
  }
 catch (  Exception ex) {
    _logger.log(Level.SEVERE,"String_Node_Str",ex);
    return false;
  }
 finally {
    if (setPc) {
      try {
        setPolicyContextID(oldpcID);
      }
 catch (      Exception ex) {
        _logger.log(Level.SEVERE,"String_Node_Str",ex);
        return false;
      }
    }
  }
  resolvePermissions(pc,p);
  Enumeration granted=pc.elements();
  while (granted.hasMoreElements()) {
    Permission i=(Permission)granted.nextElement();
    if (i.equals(allPermission)) {
      nextCache.add(i);
    }
 else {
      boolean classMatch=true;
      if (this.classes != null) {
        classMatch=false;
        Class iClazz=i.getClass();
        for (int j=0; j < this.classes.length; j++) {
          if (this.classes[j].equals(iClazz)) {
            classMatch=true;
            break;
          }
        }
      }
      if (classMatch) {
        if (this.name != null) {
          String iName=i.getName();
          if (iName != null && this.name.equals(iName)) {
            nextCache.add(i);
          }
        }
 else {
          nextCache.add(i);
        }
      }
    }
  }
  wLock.lock();
  try {
    cache=nextCache;
    loading=false;
    try {
      rLock.lock();
      wLock.unlock();
      wLock=null;
      return checkLoadedCache(p,e);
    }
  finally {
      rLock.unlock();
    }
  }
  finally {
    if (wLock != null)     wLock.unlock();
  }
}