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
