diff --git a/daemon/src/managerimpl.cpp b/daemon/src/managerimpl.cpp
index a58684849ebd3d02a087ea63434dd8a3891a0596..9ca0827a31f44b904de3e24bc2b4e562e37bc12d 100644
--- a/daemon/src/managerimpl.cpp
+++ b/daemon/src/managerimpl.cpp
@@ -1351,27 +1351,41 @@ ManagerImpl::removeStream(Call& call)
     getRingBufferPool().unBindAll(call_id);
 }
 
+// Not thread-safe, SHOULD be called in same thread that run poolEvents()
 void
 ManagerImpl::registerEventHandler(uintptr_t handlerId, EventHandler handler)
 {
-    eventHandlerMap_.insert(std::make_pair(handlerId, handler));
+    eventHandlerMap_[handlerId] = handler;
 }
 
+// Not thread-safe, SHOULD be called in same thread that run poolEvents()
 void
 ManagerImpl::unregisterEventHandler(uintptr_t handlerId)
 {
-    eventHandlerMap_.erase(handlerId);
+    auto iter = eventHandlerMap_.find(handlerId);
+    if (iter != eventHandlerMap_.end()) {
+        if (iter == nextEventHandler_)
+            nextEventHandler_ = eventHandlerMap_.erase(iter);
+        else
+            eventHandlerMap_.erase(iter);
+    }
 }
 
 // Must be invoked periodically by a timer from the main event loop
 void ManagerImpl::pollEvents()
 {
-    // Make a copy of handlers map as handlers can modify this map
-    const auto handlers = eventHandlerMap_;
-    for (const auto& it : handlers) {
+    auto iter = eventHandlerMap_.begin();
+    while (iter != eventHandlerMap_.end()) {
         if (finished_)
             return;
-        it.second();
+
+        // WARN: following callback can do anything and typically
+        // calls (un)registerEventHandler.
+        // Think twice before modify this code.
+
+        nextEventHandler_ = std::next(iter);
+        iter->second();
+        iter = nextEventHandler_;
     }
 }
 
diff --git a/daemon/src/managerimpl.h b/daemon/src/managerimpl.h
index bb7a4a6f887ff839e7844c9d832fbd86a9e45628..0371145f715fb4da502a9a9a3bb5486506c999b9 100644
--- a/daemon/src/managerimpl.h
+++ b/daemon/src/managerimpl.h
@@ -968,7 +968,8 @@ class ManagerImpl {
     private:
         NON_COPYABLE(ManagerImpl);
 
-        std::map<uintptr_t, EventHandler> eventHandlerMap_{};
+        std::map<uintptr_t, EventHandler> eventHandlerMap_;
+        decltype(eventHandlerMap_)::iterator nextEventHandler_;
 
         /**
          * Test if call is a valid call, i.e. have been created and stored in