handlers in scoringmgr managed life cycle of handle
authorjaehoon.hyun <jaehoon.hyun@samsung.com>
Tue, 2 Apr 2019 06:27:17 +0000 (15:27 +0900)
committerjaehoon.hyun <jaehoon.hyun@samsung.com>
Tue, 2 Apr 2019 06:27:17 +0000 (15:27 +0900)
src/scoringmgr/handlers.go

index 4bb6f58..d7e1eca 100644 (file)
@@ -1,28 +1,50 @@
 package scoringmgr
-
+/*
+#include <stdlib.h>
+#include <dlfcn.h>
+#cgo LDFLAGS: -ldl
+*/
+import "C"
 import "unsafe"
 
 import (
+  
+  "time"
   confdescription  "configuremgr/description"
+
+)
+
+const (
+  LIB_STATUS_INIT = 1
+  LIB_STATUS_RUN  = 2
+  LIB_STATUS_DONE = 3
 )
 
 type Handler struct {
   handlerName   string
   libPath       string
+  functionName  string
   devicesScore  map[string]float64
   intervalMs    int
   resourceCount int
   scoreValue    int
-  symbolPtr     unsafe.Pointer
+  statusSignal  chan int
+  endSignal     chan bool
+  parents       *Handlers
+
+  //for dynamic loading
+  symbol        uintptr
+  dl            uintptr
 
 }
 
 type Handlers struct {
   table map[string]*Handler
 
-  Ch                  chan interface{}
-  IloadScoringLibrary func (string, int) ()
-  GetScore            func (string) float64
+  Ch    chan interface{}
+  
+  IRunningScore func (uintptr) ()
+  IGetScore     func (string, string) float64
 }
 
 
@@ -52,8 +74,8 @@ func (handlers *Handlers) Listening() {
       select {
         case obj := <- handlers.Ch :
           ILog.Printf("input handlers.Ch from configuremgr")
-          handlerObj := handlers.makeHandler(obj.(pair))
-          handlers.runScoring(handlerObj)
+          handlers.makeHandler(obj.(pair)).runScoring()
+
       }
 
     }
@@ -61,19 +83,121 @@ func (handlers *Handlers) Listening() {
   }()
 }
 
+func (handlers *Handlers) RemoveLib(libName string) {
+  handler := handlers.table[libName]
+
+  //for producer
+  handler.statusSignal <- LIB_STATUS_DONE
+
+  //for consumer
+  handler.statusSignal <- LIB_STATUS_DONE
+
+  //Close dynamic loader
+  defer C.dlclose(unsafe.Pointer(handler.dl))
+}
+
 func (handlers *Handlers) makeHandler(pairObj pair) (handlerObj *Handler) {
   handlerObj = new(Handler)
   handlerObj.handlerName  = pairObj.libPath
   handlerObj.libPath      = pairObj.libPath
   handlerObj.intervalMs   = pairObj.doc.ResourceType.IntervalTimeMs
+  handlerObj.functionName = pairObj.doc.ScoringMethod.FunctionName
   handlerObj.devicesScore = make(map[string]float64)
+  handlerObj.statusSignal = make(chan int, 1024)
+  handlerObj.endSignal    = make(chan bool, 1024)
+  handlerObj.parents      = handlers
 
   handlers.table[pairObj.libPath] = handlerObj
 
   return
 }
 
-func (handlers *Handlers) runScoring(handlerObj *Handler) {
-  go handlers.IloadScoringLibrary(handlerObj.libPath, handlerObj.intervalMs)
+func (handler *Handler) runScoring() {
+
+  ILog.Println("Run scoring")
+
+  go func(){
+
+    for {
+      select {
+        case status := <- handler.statusSignal :
+          handler.process(status)
+        case <- handler.endSignal :
+          ILog.Println("consumer signal go routine die")
+          return
+      }
+    }
+  }()
+
+  go func() {
+    
+    handler.statusSignal <- LIB_STATUS_INIT
+
+    for {
+
+      select {
+        case <- handler.endSignal :
+          ILog.Println("producer signal go routine die")
+          return
+        default:
+          handler.statusSignal <- LIB_STATUS_RUN
+          time.Sleep(time.Duration(1000) * time.Millisecond)
+          ILog.Printf("status run sleep time : %d\n", handler.intervalMs)
+      }
+
+    }
+
+  }()
+
   return
+}
+
+func (handler *Handler) process(status int) {
+
+  switch(status){
+    case LIB_STATUS_INIT:
+      ILog.Printf("init\n")
+      handler.init()
+      break
+    case LIB_STATUS_RUN:
+    ILog.Printf("run\n")
+      handler.running()
+      break
+  }
+
+}
+
+
+func (handler *Handler) init() {
+
+  sym := C.CString(handler.functionName)
+  defer C.free(unsafe.Pointer(sym))
+
+  lib := C.CString(handler.libPath)
+  defer C.free(unsafe.Pointer(lib))
+
+  dl, err := C.dlopen(lib , C.RTLD_LAZY)
+  handler.dl = uintptr(dl)
+
+  if err != nil {
+    ELog.Fatal("dlopen error occured")
+  }
+  
+  symbolPtr, symbolErr := C.dlsym(dl, sym)
+  if symbolErr != nil {
+    ELog.Fatal("symbol error occured")
+  }
+
+  handler.symbol = uintptr(symbolPtr)
+
+  ILog.Printf("functionName : %s\n", handler.functionName)
+  ILog.Printf("libPath      : %s\n", handler.libPath)
+  ILog.Printf("symbol       : %#08X\n", handler.symbol)
+
+
+  return 
+}
+
+func (handler *Handler) running() {
+    handler.parents.IRunningScore(handler.symbol)
 }
\ No newline at end of file