#ifndef __AutoSymbolList_h_ #define __AutoSymbolList_h_ #include "../shared/ThreadSafeRefCount.h" #include "../ax_alert_server/Types.h" /* This unit is responsible for looking up symbol list data when we need it, * refreshing it periodically, and reusing it if multiple strategies request * the data. * * The interface is small. This unit will automatically initialize itself the * first time it is called. The strategy code will ask this unit for a symbol * list object. The execution code will query that object to see if a specific * symbol is in that list. The symbol list object is reference counted so it * will automatically clean itself up. Someone using a strategy will not even * know that we've switched from the old system to this. */ class AutoSymbolList { public: // These types look a lot like SymbolListDesciption and SymbolLists in // AlertConfig.h. The important difference is that those classes used 0 // for the ownerId to mean the current user. We don't have that concept. // ownerId should never be 0 in SingleList. struct SingleList { UserId ownerId; SymbolListId listId; bool operator ==(SingleList const &other) const; bool operator !=(SingleList const &other) const; bool operator <(SingleList const &other) const; }; typedef std::set< SingleList > Description; typedef NCTSRefCount< AutoSymbolList > Ref; // This is thread safe. virtual bool isPresent(char const *symbol) =0; //virtual bool isPresent(std::string const &symbol) =0; virtual ~AutoSymbolList() { } // This is thread safe. This might be shared. The result will have data and // it will be ready to use as soon as you receive it. static Ref find(Description const &description); // This will force us to review all symbol lists right now. That means // checking which ones are no longer in use and removing them from memory. // That means reloading the rest from the database. This is only aimed at // test programs that can't use the normal background thread to update // the lists. This does not have the finesse of that thread. This might // hold some global locks longer than it should. But in a single threaded // program that's okay. static void debugUpdateAllNow(); // Reexamine the request. Maybe we're done with the request and it can be // removed from our internal list of requests that we periodically update. // Maybe the request doesn't exist at all, so we ignore the function call. // Otherwise, we refresh the cached copy of the request from the database. // Returns true if the request is in our internal list after the function // call is complete. // // Originally this was hidden. It was only available to the // AutoSymbolListManager. You had no need to call this yourself because // the AutoSymbolListManager would automatically call this periodically. // I exposed this because that thread is moving to a different *.C file. // However, I suppose it's okay if other people use this, too. Maybe // a user asks to refresh his lists immediately. // // Note that we take a description of a list, not a pointer. If you are // holding a pointer to the list, that will bump the reference count, so // we will not remove the list from the cache. Normally you create the // list while you're parsing, and then you give it to the execution code. // This is all automatic as part of the parsing and execution process. static bool reloadOrRelease(Description const &descriptionOfRequest); }; /* This manages the list of symbol lists. This is required to automatically * refesh the contents of the lists from the database. * * Ideally this would be completely hidden in AutoSymbolList.C. But some of * our test programs run in a different setup than the main program. * * AutoSymbolListScheduler.h includes a simple function to initialize a thread * to take care of all of this. That's what the main program should use. That * used to be automatic. Older programs had no choice and would always start * that thread (or fail to compile if they were single threaded!). * * If you don't initialize that, you'll get a very simplified offering. You * will still get symbol lists full of data. But they will never be updated. * Also, they will never be freed from memory! That's probably good enough * for a test program, depending what you're trying to test. See * AutoSymbolList::debugUpdateAllNow() for more options. */ class AutoSymbolListManager { private: protected: AutoSymbolListManager() { } static AutoSymbolListManager *_instance; public: virtual void add(AutoSymbolList::Description const &description) =0; static AutoSymbolListManager *instance() { return _instance; } }; #endif