#ifndef __ReportAlertsThread_h_ #define __ReportAlertsThread_h_ #include #include #include #include "../shared/SelectableRequestQueue.h" #include "../shared/ThreadClass.h" #include "../shared/Messages.h" #include "../shared/CommandDispatcher.h" class ReportAlertsThread : private ThreadClass { private: class ReportAlert : public Request { public: ReportAlert() : Request(NULL) { } std::string category; std::string info; }; static ReportAlertsThread *instance; enum { mtAddCategory, mtDeleteCategory, mtDeleteAll, mtListCategories, mtReportAlert, mtResponseId, mtAddAlertCategory, mtFlushPermissions, mtDump, mtSetCacheable, mtQuit }; // These say who is subscribed to what. SelectableRequestQueue _incoming; typedef std::set< std::string > CategorySet; typedef std::map< SocketInfo *, CategorySet > BySocket; BySocket _bySocket; typedef std::set< SocketInfo * > SocketSet; typedef std::map< std::string, SocketSet > ByCategory; ByCategory _byCategory; std::map< SocketInfo *, ExternalRequest::MessageId > _responseId; void deleteAll(SocketInfo *socket); void dump(std::string const &message); // Once a minute tickle the dead man timer for any micro_proxy users. time_t _nextTimerRefresh; void doTimerRefresh(); // Who is permissioned for what. This maps a socket to a list of // permissions. The permissions are a set of categories. At least one of // the categories in this set must be a prefix of the category for the actual // alert, or the user does not have permission to see the alert. If a socket // is not in this list, we have not loaded the permissions yet. If the // socket points to the empty set, the user has no permissions. BySocket _permissionsBySocket; bool isPermissioned(SocketInfo *socket, std::string const &category); // This is available if the client asks for it, but we don't use it any other // way. This maps alert categories to user friendly decriptions. PropertyList _allAlertCategories; // Sometimes, when a person first requests a category, we want to send the // most recent message to the user immediately, rather than waiting for the // next message. std::set< std::string > _cacheable; PropertyList _cache; protected: void threadFunction(); public: ReportAlertsThread(); ~ReportAlertsThread(); static ReportAlertsThread *getInstance() { return instance; } // This is thread safe. void reportAlert(std::string const &category, std::string const &info); // This is thread safe. This is not required by the server. We can provide // a list of alerts to the GUI if it requests it. These alerts will be // filtered for each user so he can only see what he's got permission to see. void addAlertCategory(std::string const &category, std::string const &description); // This is thread safe. The default is not to cache message. void setCacheable(std::string const &category); }; #endif