void notifyBackupComplete ( ) { int newBackupAcksCompleted = BACKUP_ACKS_RECEIVED . incrementAndGet ( this ) ; Object pendingResponse = this . pendingResponse ; if ( pendingResponse == VOID ) { // no pendingResponse has been set, so we are done since the invocation on the primary needs to complete first return ; } // if a pendingResponse is set, then the backupsAcksExpected has been set (so we can now safely read backupsAcksExpected) int backupAcksExpected = this . backupsAcksExpected ; if ( backupAcksExpected < newBackupAcksCompleted ) { // the backups have not yet completed, so we are done return ; } if ( backupAcksExpected != newBackupAcksCompleted ) { // we managed to complete one backup, but we were not the one completing the last backup, so we are done return ; } // we are the lucky one since we just managed to complete the last backup for this invocation and since the // pendingResponse is set, we can set it on the future complete ( pendingResponse ) ; }
this method can be called concurrently