diff --git a/api/api.go b/api/api.go index 688e2f2b..c9647f7b 100644 --- a/api/api.go +++ b/api/api.go @@ -24,6 +24,9 @@ type ServiceInterface interface { // shutdown the service Shutdown() + // return if the service is running + IsRunning() bool + // add a use case to the service AddUseCase(useCase UseCaseInterface) diff --git a/mocks/ServiceInterface.go b/mocks/ServiceInterface.go index c2a318b9..868ead26 100644 --- a/mocks/ServiceInterface.go +++ b/mocks/ServiceInterface.go @@ -218,6 +218,51 @@ func (_c *ServiceInterface_IsAutoAcceptEnabled_Call) RunAndReturn(run func() boo return _c } +// IsRunning provides a mock function with given fields: +func (_m *ServiceInterface) IsRunning() bool { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for IsRunning") + } + + var r0 bool + if rf, ok := ret.Get(0).(func() bool); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(bool) + } + + return r0 +} + +// ServiceInterface_IsRunning_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsRunning' +type ServiceInterface_IsRunning_Call struct { + *mock.Call +} + +// IsRunning is a helper method to define mock.On call +func (_e *ServiceInterface_Expecter) IsRunning() *ServiceInterface_IsRunning_Call { + return &ServiceInterface_IsRunning_Call{Call: _e.mock.On("IsRunning")} +} + +func (_c *ServiceInterface_IsRunning_Call) Run(run func()) *ServiceInterface_IsRunning_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *ServiceInterface_IsRunning_Call) Return(_a0 bool) *ServiceInterface_IsRunning_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *ServiceInterface_IsRunning_Call) RunAndReturn(run func() bool) *ServiceInterface_IsRunning_Call { + _c.Call.Return(run) + return _c +} + // LocalDevice provides a mock function with given fields: func (_m *ServiceInterface) LocalDevice() spine_goapi.DeviceLocalInterface { ret := _m.Called() diff --git a/service/service.go b/service/service.go index a5a571f9..4aa972fb 100644 --- a/service/service.go +++ b/service/service.go @@ -42,9 +42,11 @@ type Service struct { // defines wether a user interaction to accept pairing is possible isPairingPossible bool - startOnce sync.Once + // return if the service is running + isRunning bool - mux sync.Mutex + mux sync.Mutex + muxRunning sync.Mutex } // creates a new EEBUS service @@ -153,15 +155,39 @@ func (s *Service) Setup() error { // Starts the service func (s *Service) Start() { - s.startOnce.Do(func() { - s.connectionsHub.Start() - }) + s.muxRunning.Lock() + defer s.muxRunning.Unlock() + + // make sure we do not start twice while the service is already running + if s.isRunning { + return + } + + s.connectionsHub.Start() } // Shutdown all services and stop the server. func (s *Service) Shutdown() { + s.muxRunning.Lock() + defer s.muxRunning.Unlock() + + // if the service is not running, we do not need to shut it down + if !s.isRunning { + return + } + // Shut down all running connections s.connectionsHub.Shutdown() + + s.isRunning = false +} + +// return if the service is running +func (s *Service) IsRunning() bool { + s.muxRunning.Lock() + defer s.muxRunning.Unlock() + + return s.isRunning } // add a use case to the service