[VOL-3930] Using a shared lock for Resource acquisition and release

Change-Id: Ibf6346135380ab14d0c89f0e2945ebefdee1b4f9
diff --git a/vendor/github.com/opencord/voltha-lib-go/v4/pkg/techprofile/tech_profile.go b/vendor/github.com/opencord/voltha-lib-go/v4/pkg/techprofile/tech_profile.go
index 5cb5a2e..0f2741f 100644
--- a/vendor/github.com/opencord/voltha-lib-go/v4/pkg/techprofile/tech_profile.go
+++ b/vendor/github.com/opencord/voltha-lib-go/v4/pkg/techprofile/tech_profile.go
@@ -36,8 +36,10 @@
 // Interface to pon resource manager APIs
 type iPonResourceMgr interface {
 	GetResourceID(ctx context.Context, IntfID uint32, ResourceType string, NumIDs uint32) ([]uint32, error)
+	FreeResourceID(ctx context.Context, IntfID uint32, ResourceType string, ReleaseContent []uint32) error
 	GetResourceTypeAllocID() string
 	GetResourceTypeGemPortID() string
+	GetResourceTypeOnuID() string
 	GetTechnology() string
 }
 
@@ -221,6 +223,7 @@
 type TechProfileMgr struct {
 	config            *TechProfileFlags
 	resourceMgr       iPonResourceMgr
+	OnuIDMgmtLock     sync.RWMutex
 	GemPortIDMgmtLock sync.RWMutex
 	AllocIDMgmtLock   sync.RWMutex
 }
@@ -659,9 +662,7 @@
 	logger.Infow(ctx, "Allocating TechProfileMgr instance from techprofile template", log.Fields{"uniPortName": uniPortName, "intfId": intfId, "numGem": tp.NumGemPorts})
 
 	if tp.InstanceCtrl.Onu == "multi-instance" {
-		t.AllocIDMgmtLock.Lock()
-		tcontIDs, err = t.resourceMgr.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeAllocID(), 1)
-		t.AllocIDMgmtLock.Unlock()
+		tcontIDs, err = t.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeAllocID(), 1)
 		if err != nil {
 			logger.Errorw(ctx, "Error getting alloc id from rsrcrMgr", log.Fields{"intfId": intfId})
 			return nil
@@ -673,9 +674,7 @@
 		} else if tpInst == nil {
 			// No "single-instance" tp found on one any uni port for the given TP ID
 			// Allocate a new TcontID or AllocID
-			t.AllocIDMgmtLock.Lock()
-			tcontIDs, err = t.resourceMgr.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeAllocID(), 1)
-			t.AllocIDMgmtLock.Unlock()
+			tcontIDs, err = t.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeAllocID(), 1)
 			if err != nil {
 				logger.Errorw(ctx, "Error getting alloc id from rsrcrMgr", log.Fields{"intfId": intfId})
 				return nil
@@ -686,9 +685,7 @@
 		}
 	}
 	logger.Debugw(ctx, "Num GEM ports in TP:", log.Fields{"NumGemPorts": tp.NumGemPorts})
-	t.GemPortIDMgmtLock.Lock()
-	gemPorts, err = t.resourceMgr.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeGemPortID(), tp.NumGemPorts)
-	t.GemPortIDMgmtLock.Unlock()
+	gemPorts, err = t.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeGemPortID(), tp.NumGemPorts)
 	if err != nil {
 		logger.Errorw(ctx, "Error getting gemport ids from rsrcrMgr", log.Fields{"intfId": intfId, "numGemports": tp.NumGemPorts})
 		return nil
@@ -793,7 +790,7 @@
 	logger.Infow(ctx, "Allocating TechProfileMgr instance from techprofile template", log.Fields{"uniPortName": uniPortName, "intfId": intfId, "numGem": tp.NumGemPorts})
 
 	if tp.InstanceCtrl.Onu == "multi-instance" {
-		if tcontIDs, err = t.resourceMgr.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeAllocID(), 1); err != nil {
+		if tcontIDs, err = t.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeAllocID(), 1); err != nil {
 			logger.Errorw(ctx, "Error getting alloc id from rsrcrMgr", log.Fields{"intfId": intfId})
 			return nil
 		}
@@ -804,7 +801,7 @@
 		} else if tpInst == nil {
 			// No "single-instance" tp found on one any uni port for the given TP ID
 			// Allocate a new TcontID or AllocID
-			if tcontIDs, err = t.resourceMgr.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeAllocID(), 1); err != nil {
+			if tcontIDs, err = t.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeAllocID(), 1); err != nil {
 				logger.Errorw(ctx, "Error getting alloc id from rsrcrMgr", log.Fields{"intfId": intfId})
 				return nil
 			}
@@ -814,7 +811,7 @@
 		}
 	}
 	logger.Debugw(ctx, "Num GEM ports in TP:", log.Fields{"NumGemPorts": tp.NumGemPorts})
-	if gemPorts, err = t.resourceMgr.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeGemPortID(), tp.NumGemPorts); err != nil {
+	if gemPorts, err = t.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeGemPortID(), tp.NumGemPorts); err != nil {
 		logger.Errorw(ctx, "Error getting gemport ids from rsrcrMgr", log.Fields{"intfId": intfId, "numGemports": tp.NumGemPorts})
 		return nil
 	}
@@ -1397,3 +1394,62 @@
 	}
 	return nil
 }
+
+func (t *TechProfileMgr) GetResourceID(ctx context.Context, IntfID uint32, ResourceType string, NumIDs uint32) ([]uint32, error) {
+	logger.Debugw(ctx, "getting-resource-id", log.Fields{
+		"intf-id":       IntfID,
+		"resource-type": ResourceType,
+		"num":           NumIDs,
+	})
+	var err error
+	var ids []uint32
+	switch ResourceType {
+	case t.resourceMgr.GetResourceTypeAllocID():
+		t.AllocIDMgmtLock.Lock()
+		ids, err = t.resourceMgr.GetResourceID(ctx, IntfID, ResourceType, NumIDs)
+		t.AllocIDMgmtLock.Unlock()
+	case t.resourceMgr.GetResourceTypeGemPortID():
+		t.GemPortIDMgmtLock.Lock()
+		ids, err = t.resourceMgr.GetResourceID(ctx, IntfID, ResourceType, NumIDs)
+		t.GemPortIDMgmtLock.Unlock()
+	case t.resourceMgr.GetResourceTypeOnuID():
+		t.OnuIDMgmtLock.Lock()
+		ids, err = t.resourceMgr.GetResourceID(ctx, IntfID, ResourceType, NumIDs)
+		t.OnuIDMgmtLock.Unlock()
+	default:
+		return nil, fmt.Errorf("ResourceType %s not supported", ResourceType)
+	}
+	if err != nil {
+		return nil, err
+	}
+	return ids, nil
+}
+
+func (t *TechProfileMgr) FreeResourceID(ctx context.Context, IntfID uint32, ResourceType string, ReleaseContent []uint32) error {
+	logger.Debugw(ctx, "freeing-resource-id", log.Fields{
+		"intf-id":         IntfID,
+		"resource-type":   ResourceType,
+		"release-content": ReleaseContent,
+	})
+	var err error
+	switch ResourceType {
+	case t.resourceMgr.GetResourceTypeAllocID():
+		t.AllocIDMgmtLock.Lock()
+		err = t.resourceMgr.FreeResourceID(ctx, IntfID, ResourceType, ReleaseContent)
+		t.AllocIDMgmtLock.Unlock()
+	case t.resourceMgr.GetResourceTypeGemPortID():
+		t.GemPortIDMgmtLock.Lock()
+		err = t.resourceMgr.FreeResourceID(ctx, IntfID, ResourceType, ReleaseContent)
+		t.GemPortIDMgmtLock.Unlock()
+	case t.resourceMgr.GetResourceTypeOnuID():
+		t.OnuIDMgmtLock.Lock()
+		err = t.resourceMgr.FreeResourceID(ctx, IntfID, ResourceType, ReleaseContent)
+		t.OnuIDMgmtLock.Unlock()
+	default:
+		return fmt.Errorf("ResourceType %s not supported", ResourceType)
+	}
+	if err != nil {
+		return err
+	}
+	return nil
+}