[VOL-4525] openonuAdapterGo - reconciling of ONU falls back from status success to falied
[VOL-4533] openonuAdapterGo - sporadically uni ports are missing after reconcile test

Change-Id: I127f1b97c97566dfe8a7ddae220d45a06b8d38e2
diff --git a/VERSION b/VERSION
index 4fc01ac..3c59b40 100755
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.3.19
+1.3.20
diff --git a/internal/pkg/onuadaptercore/device_handler.go b/internal/pkg/onuadaptercore/device_handler.go
index 77b1dbd..dcc7fa6 100644
--- a/internal/pkg/onuadaptercore/device_handler.go
+++ b/internal/pkg/onuadaptercore/device_handler.go
@@ -3748,6 +3748,16 @@
 				log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.deviceID})
 			select {
 			case success := <-dh.chReconcilingFinished:
+				logger.Debugw(ctx, "reconciling finished signal received",
+					log.Fields{"device-id": dh.deviceID, "dh.chReconcilingFinished": dh.chReconcilingFinished})
+				// To guarantee that the case-branch below is completely processed before reconciling processing is continued,
+				// dh.mutexReconcilingFlag is locked already here. Thereby it is ensured, that further reconciling processing is stopped
+				// at next call of dh.IsReconciling() until dh.reconciling is set after informing core about finished reconciling below.
+				// This change addresses a problem described in VOL-4533 where the flag dh.reconciling not yet reset causes the uni ports
+				// not to be created in ONOS in function dh.addUniPort(), when reconciling was started in reason "starting-openomci".
+				// TODO: Keeping the mutex beyond an RPC towards core seems justifiable, as the effects here are easily overseeable.
+				// However, a later refactoring of the functionality remains unaffected.
+				dh.mutexReconcilingFlag.Lock()
 				if success {
 					if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
 						logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
@@ -3797,6 +3807,7 @@
 			case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
 				logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
 					log.Fields{"device-id": dh.deviceID})
+				dh.mutexReconcilingFlag.Lock()
 
 				if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
 					logger.Errorw(ctx, "No valid OnuDevice",
@@ -3810,7 +3821,6 @@
 				}
 				dh.deviceReconcileFailedUpdate(ctx, drReconcileMaxTimeout, connectStatus)
 			}
-			dh.mutexReconcilingFlag.Lock()
 			dh.reconciling = cNoReconciling
 			dh.mutexReconcilingFlag.Unlock()
 		}()
diff --git a/internal/pkg/onuadaptercore/mib_sync.go b/internal/pkg/onuadaptercore/mib_sync.go
index 567a3f4..208d8cd 100644
--- a/internal/pkg/onuadaptercore/mib_sync.go
+++ b/internal/pkg/onuadaptercore/mib_sync.go
@@ -321,10 +321,12 @@
 
 		// start go routine with select() on reconciling flow channel before
 		// starting flow reconciling process to prevent loss of any signal
-		go func() {
+		syncChannel := make(chan struct{})
+		go func(aSyncChannel chan struct{}) {
 			// In multi-ONU/multi-flow environment stopping reconcilement has to be delayed until
 			// we get a signal that the processing of the last step to rebuild the adapter internal
 			// flow data is finished.
+			aSyncChannel <- struct{}{}
 			select {
 			case success := <-oo.baseDeviceHandler.chReconcilingFlowsFinished:
 				if success {
@@ -344,7 +346,11 @@
 				oo.baseDeviceHandler.setReconcilingFlows(false)
 				_ = oo.pMibUploadFsm.pFsm.Event(ulEvMismatch)
 			}
-		}()
+		}(syncChannel)
+		// block further processing until the above Go routine has really started
+		// and is ready to receive values from chReconcilingFlowsFinished
+		<-syncChannel
+
 		oo.baseDeviceHandler.reconcileDeviceFlowConfig(ctx)
 
 		oo.mutexPersOnuConfig.RLock()