refactor emit() and emitwithcallback()
diff --git a/apid.go b/apid.go
index fdf937c..4392b8f 100644
--- a/apid.go
+++ b/apid.go
@@ -1,12 +1,15 @@
 package apid
 
 import (
+	"errors"
 	"os"
+	"time"
 )
 
 const (
 	SystemEventsSelector  EventSelector = "system event"
 	ShutdownEventSelector EventSelector = "shutdown event"
+	ShutdownTimeout       int           = 10
 )
 
 var (
@@ -15,8 +18,6 @@
 
 	pluginInitFuncs []PluginInitFunc
 	services        Services
-
-	shutdownChan chan int
 )
 
 type Services interface {
@@ -49,8 +50,6 @@
 	ss.api = s.API()
 	ss.data = s.Data()
 
-	shutdownChan = make(chan int)
-
 	ss.events.Emit(SystemEventsSelector, APIDInitializedEvent)
 }
 
@@ -76,21 +75,22 @@
 	log.Debugf("done initializing plugins")
 }
 
-func ShutdownPlugins() {
-	Events().EmitWithCallback(ShutdownEventSelector, ShutdownEvent{"apid is going to shutdown"}, shutdownHandler)
-}
-
-func shutdownHandler(event Event) {
-	log := Log()
-	log.Debugf("shutdown apid")
-	shutdownChan <- 1
-}
-
-/* wait for the shutdown of registered graceful-shutdown plugins, blocking until the required plugins finish shutdown
- * this is used to prevent the main from exiting
- */
-func WaitPluginsShutdown() {
-	<-shutdownChan
+// Shutdown all the plugins that have registered for ShutdownEventSelector.
+// This call will block until either all required plugins shutdown, or a timeout occurred.
+func ShutdownPluginsAndWait() error {
+	shutdownEvent := ShutdownEvent{"apid is going to shutdown"}
+	eventChan := Events().Emit(ShutdownEventSelector, shutdownEvent)
+	select {
+	case event := <-eventChan:
+		if e, ok := event.(ShutdownEvent); ok {
+			if e == shutdownEvent {
+				return nil
+			}
+		}
+		return errors.New("Emit() problem: wrong event delivered")
+	case <-time.After(time.Duration(ShutdownTimeout) * time.Second):
+		return errors.New("Shutdown timeout")
+	}
 }
 
 func AllServices() Services {
diff --git a/events_service.go b/events_service.go
index 1106f2d..c11b358 100644
--- a/events_service.go
+++ b/events_service.go
@@ -11,10 +11,9 @@
 type EventHandlerFunc func(event Event)
 
 type EventsService interface {
-	/* publish an event to the selector.
-	It will send a copy of the delivered event to the returned channel, after all listeners have responded to the event.
-	Call "Emit()" for non-blocking, "<-Emit()" for blocking.
-	*/
+	// Publish an event to the selector.
+	// It will send a copy of the delivered event to the returned channel, after all listeners have responded to the event.
+	// Call "Emit()" for non-blocking, "<-Emit()" for blocking.
 	Emit(selector EventSelector, event Event) chan Event
 
 	// publish an event to the selector, call the passed handler when all listeners have responded to the event