Module: sems
Branch: master
Commit: 7349c5356a1b96dd7a25fe9a50f025a53a108a93
URL:    
http://git.sip-router.org/cgi-bin/gitweb.cgi/sems/?a=commit;h=7349c5356a1b96dd7a25fe9a50f025a53a108a93

Author: Raphael Coeffic <[email protected]>
Committer: Raphael Coeffic <[email protected]>
Date:   Mon Sep 27 17:29:34 2010 +0200

Adds notification capabilities to msg_storage.

The msg_storage plug-in has been extended to send notifications to a 
AmDynInvoke instance in following cases:
 - new message
 - message marked as read
 - message has been deleted

---

 apps/msg_storage/MsgStorage.cpp |   71 +++++++++++++++++++++++++++++++++++++--
 apps/msg_storage/MsgStorage.h   |   15 ++++++++
 2 files changed, 83 insertions(+), 3 deletions(-)

diff --git a/apps/msg_storage/MsgStorage.cpp b/apps/msg_storage/MsgStorage.cpp
index d0da5dc..5502663 100644
--- a/apps/msg_storage/MsgStorage.cpp
+++ b/apps/msg_storage/MsgStorage.cpp
@@ -21,7 +21,9 @@ MsgStorage* MsgStorage::_instance = 0;
 EXPORT_PLUGIN_CLASS_FACTORY(MsgStorage, MOD_NAME);
 
 MsgStorage::MsgStorage(const string& name)
-    : AmDynInvokeFactory(name) { 
+  : AmDynInvokeFactory(name),
+    listeners()
+{ 
       _instance = this; 
 }
 
@@ -52,7 +54,7 @@ int MsgStorage::onLoad() {
   status = mkdir(path.c_str(), 
                     S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
   if (status && (errno != EEXIST)) {
-    ERROR("creating test path in storage '%s': %s\n", 
+    ERROR("Write permission check failed. Could not create '%s': %s\n", 
          path.c_str(),strerror(errno));
     return -1;
   }
@@ -91,6 +93,7 @@ void MsgStorage::invoke(const string& method,
     userdir_open(args.get(0).asCStr(),       
       args.get(1).asCStr(),
       ret);
+#if 0
   } else if(method == "userdir_close"){
     ret.push(userdir_close(args.get(0).asCStr(),
       args.get(1).asCStr()));
@@ -98,6 +101,12 @@ void MsgStorage::invoke(const string& method,
     userdir_getcount(args.get(0).asCStr(),
       args.get(1).asCStr(),
       ret);
+#endif
+  } else if(method == "events_subscribe"){
+    events_subscribe(args.get(0).asDynInv(),
+                    args.get(1).asCStr());
+  } else if(method == "events_unsubscribe"){
+    events_unsubscribe(args.get(0).asDynInv());
   } else if(method == "_list"){
     ret.push("msg_new");
     ret.push("msg_get");
@@ -105,8 +114,13 @@ void MsgStorage::invoke(const string& method,
     ret.push("msg_delete");
     
     ret.push("userdir_open");
+#if 0
     ret.push("userdir_close");
     ret.push("userdir_getcount");
+#endif
+
+    ret.push("events_subscribe");
+    ret.push("events_unsubscribe");
   }
   else
     throw AmDynInvoke::NotImplemented(method); 
@@ -146,6 +160,9 @@ int MsgStorage::msg_new(string domain, string user,
   if (data)
     filecopy(data, fp);
   fclose(fp);
+
+  event_notify(domain,user,"msg_new");
+
   return MSG_OK;
 }
 
@@ -185,6 +202,8 @@ int MsgStorage::msg_markread(string domain, string user, 
string msg_name) {
     return MSG_EREADERROR;
   }
 
+  event_notify(domain,user,"msg_markread");
+
   return MSG_OK;
 }
 
@@ -196,6 +215,9 @@ int MsgStorage::msg_delete(string domain, string user, 
string msg_name) {
            path.c_str(),strerror(errno));
       return MSG_EMSGNOTFOUND;
   }
+
+  event_notify(domain,user,"msg_delete");
+
   return MSG_OK;
 }
 
@@ -246,12 +268,55 @@ void MsgStorage::userdir_open(string domain, string user, 
AmArg& ret) {
   ret.push(msglist);
 }
 
+#if 0
 int MsgStorage::userdir_close(string domain, string user) {   
   // TODO: unblock the directory from delete (decrease lock)
   return 0; 
 }
 
-void MsgStorage::userdir_getcount(string domain, string user, AmArg& ret) { }
+void MsgStorage::userdir_getcount(string domain, string user, AmArg& ret) { 
+  // TODO: return some useful value
+}
+#endif
+
+void MsgStorage::events_subscribe(AmDynInvoke* event_sink, string method)
+{
+  listeners_mut.lock();
+  listeners.insert(make_pair(event_sink,method));
+  listeners_mut.unlock();
+}
+
+void MsgStorage::events_unsubscribe(AmDynInvoke* event_sink)
+{
+  listeners_mut.lock();
+  listeners.erase(event_sink);
+  listeners_mut.unlock();
+}
+
+void MsgStorage::event_notify(const string& domain, 
+                             const string& user, 
+                             const string& event)
+{
+  AmArg args,ret;
+  args.push(domain);
+  args.push(user);
+  args.push(event);
+
+  listeners_mut.lock();
+
+  for(Listeners::iterator it = listeners.begin();
+      it != listeners.end(); ++it) {
+    try {
+      it->first->invoke(it->second, args, ret);
+    }
+    catch(...){
+      DBG("Unexpected exception while notifying event subscribers");
+    }
+    ret.clear();
+  }
+
+  listeners_mut.unlock();
+}
 
 // copies ifp to ofp, blockwise
 void MsgStorage::filecopy(FILE* ifp, FILE* ofp) {
diff --git a/apps/msg_storage/MsgStorage.h b/apps/msg_storage/MsgStorage.h
index 67c1266..88aadfe 100644
--- a/apps/msg_storage/MsgStorage.h
+++ b/apps/msg_storage/MsgStorage.h
@@ -3,6 +3,9 @@
 
 #include "AmApi.h"
 
+#include <map>
+using std::map;
+
 class MsgStorage : public AmDynInvokeFactory, 
                   public AmDynInvoke
 {
@@ -11,6 +14,10 @@ class MsgStorage : public AmDynInvokeFactory,
 
   string msg_dir;
 
+  typedef map<AmDynInvoke*,string> Listeners;
+  Listeners  listeners;
+  AmMutex    listeners_mut;
+  
   int msg_new(string domain, string user, string msg_name, FILE* data);
   void msg_get(string domain, string user, string msg_name, AmArg& ret);
   int msg_markread(string domain, string user, string msg_name);
@@ -20,7 +27,15 @@ class MsgStorage : public AmDynInvokeFactory,
   int userdir_close(string domain, string user);
   void userdir_getcount(string domain, string user, AmArg& ret);
 
+  void events_subscribe(AmDynInvoke* event_sink, string method);
+  void events_unsubscribe(AmDynInvoke* event_sink);
+
+  void event_notify(const string& domain, 
+                   const string& user, 
+                   const string& event);
+
   inline void filecopy(FILE* ifp, FILE* ofp);
+
  public:
   MsgStorage(const string& name);
   ~MsgStorage();

_______________________________________________
Semsdev mailing list
[email protected]
http://lists.iptel.org/mailman/listinfo/semsdev

Reply via email to