--- /dev/null
+package servicemgr
+
+import (
+ "os/exec"
+ "sync"
+ "sync/atomic"
+)
+
+// ConcurrentMap type
+type ConcurrentMap struct {
+ sync.RWMutex
+ items map[uint64]interface{}
+}
+
+// ConcurrentMapItem type
+type ConcurrentMapItem struct {
+ Key uint64
+ Value interface{}
+}
+
+// Set is for setting map item
+func (cm *ConcurrentMap) Set(key uint64, value interface{}) {
+ cm.Lock()
+ defer cm.Unlock()
+
+ cm.items[key] = value
+}
+
+// Get is for getting map item
+func (cm *ConcurrentMap) Get(key uint64) (interface{}, bool) {
+ cm.Lock()
+ defer cm.Unlock()
+
+ value, ok := cm.items[key]
+
+ return value, ok
+}
+
+// Remove is for removing map item
+func (cm *ConcurrentMap) Remove(key uint64) {
+ cm.Lock()
+ defer cm.Unlock()
+
+ delete(cm.items, key)
+}
+
+// Iter is for iterating map item
+func (cm *ConcurrentMap) Iter() <-chan ConcurrentMapItem {
+ c := make(chan ConcurrentMapItem)
+
+ f := func() {
+ cm.Lock()
+ defer cm.Unlock()
+
+ for k, v := range cm.items {
+ c <- ConcurrentMapItem{k, v}
+ }
+ close(c)
+ }
+ go f()
+
+ return c
+}
+
+// CreateServiceMap function
+func CreateServiceMap(cmd *exec.Cmd, serviceName string, appName string) uint64 {
+ serviceID := getServiceIdx()
+ msgChan := make(chan string, 10)
+
+ ServiceCmdMap.Set(serviceID, cmd)
+ ServiceMsgMap.Set(serviceID, msgChan)
+ ServiceNameMap.Set(serviceID, serviceName)
+ ServiceAppNameMap.Set(serviceID, appName)
+
+ return serviceID
+}
+
+// InitServiceMap function
+func InitServiceMap() {
+ ServiceCmdMap = ConcurrentMap{items: make(map[uint64]interface{})}
+ ServiceMsgMap = ConcurrentMap{items: make(map[uint64]interface{})}
+ ServiceNameMap = ConcurrentMap{items: make(map[uint64]interface{})}
+ ServiceAppNameMap = ConcurrentMap{items: make(map[uint64]interface{})}
+}
+
+// DeleteServiceMap function
+func DeleteServiceMap(serviceID uint64) {
+ ServiceCmdMap.Remove(serviceID)
+ ServiceMsgMap.Remove(serviceID)
+ ServiceNameMap.Remove(serviceID)
+ ServiceAppNameMap.Remove(serviceID)
+}
+
+// getServiceIdx() is for getting global serviceID
+func getServiceIdx() uint64 {
+ atomic.AddUint64(&ServiceIdx, 1)
+ return atomic.LoadUint64(&ServiceIdx)
+}
+
+// ServiceCmdMap is that map has service information (KEY : ServiceID / Value : *exec.Cmd)
+var ServiceCmdMap ConcurrentMap
+
+// ServiceMsgMap is that map has service information (KEY : ServiceID / Value : chan string)
+var ServiceMsgMap ConcurrentMap
+
+// ServiceNameMap is that map has service information (KEY : ServiceID / Value : string)
+var ServiceNameMap ConcurrentMap
+
+// ServiceAppNameMap is that map has service information (KEY : ServiceID / Value : string)
+var ServiceAppNameMap ConcurrentMap
+
+// ServiceIdx is for unique service ID
+var ServiceIdx uint64
--- /dev/null
+package servicemgr
+
+import (
+ "fmt"
+
+ "github.com/grandcat/zeroconf"
+)
+
+const (
+ //pass & fail public enum
+ Fail = 0
+ Pass = 1
+)
+
+var exits map[string]chan int = make(map[string]chan int)
+
+func RegisterService(name string, domain string, port int, ret chan int) (int, error) {
+ if name == "" {
+ ret <- Fail
+ return Fail, fmt.Errorf("Missing service name")
+ }
+
+ if domain == "" {
+ domain = "local"
+ }
+
+ if port == 0 {
+ ret <- Fail
+ return Fail, fmt.Errorf("Missing service port")
+ }
+
+ var service string = "_" + name + "._tcp"
+
+ server, err := zeroconf.Register(name, service, domain, port, []string{""}, nil)
+ if err != nil {
+ return Fail, err
+ }
+ defer server.Shutdown()
+
+ exits[name] = make(chan int)
+ ret <- Pass
+
+ select {
+ case <-exits[name]:
+ server.Shutdown()
+ }
+
+ return Pass, nil
+}
+
+func RemoveService(name string) (int, error) {
+ done := make(chan int)
+
+ if exits[name] == nil {
+ return Fail, fmt.Errorf("Service name is invalid")
+ }
+
+ go func() {
+ exits[name] <- Pass
+ done <- Pass
+ }()
+
+ select {
+ case <-done:
+ delete(exits, name)
+ }
+ return Pass, nil
+}