// // MODULE: TOPICSHOP.H // // PURPOSE: Provide a means of "publishing" troubleshooter topics. This is where a // working thread goes to obtain a CTopic to use // // COMPANY: Saltmine Creative, Inc. (206)-284-7511 support@saltmine.com // // AUTHOR: Joe Mabel // // ORIGINAL DATE: 9-10-98 // // NOTES: // // Version Date By Comments //-------------------------------------------------------------------- // V3.0 09-10-98 JM // #if !defined(AFX_TOPICSHOP_H__0CEED643_48C2_11D2_95F3_00C04FC22ADD__INCLUDED_) #define AFX_TOPICSHOP_H__0CEED643_48C2_11D2_95F3_00C04FC22ADD__INCLUDED_ #if _MSC_VER >= 1000 #pragma once #endif // _MSC_VER >= 1000 #include "apgtslstread.h" #include "apgtsHTIread.h" #include "Pointer.h" #include "Topic.h" #include "counter.h" #include #pragma warning(disable:4786) #define LSTFILENAME _T("apgts.lst") typedef counting_ptr CP_TOPIC; class CTopicInCatalog { public: enum TopicStatus {eNotInited, eFail, eOK}; private: CTopicInfo m_topicinfo; // symbolic name of topic, associated file names bool m_bTopicInfoMayNotBeCurrent; // set when we change topic info & haven't yet built. mutable CRITICAL_SECTION m_csTopicinfo; // must lock to access m_topicinfo or // m_bTopicInfoMayNotBeCurrent (outside the constructor) bool m_bInited; // true if we have attempted to build m_cpTopic. // Mainly, this is here so that if we have tried to build // the relevant CTopic and failed, we don't waste our time // trying to build it again. If this is true and // m_cpTopic.IsNull(), then we are unable to build this // troubleshooting topic. CP_TOPIC m_cpTopic; // smart (counting) pointer. If non-null, points to a // "published" topic, which is guaranteed to persist as // long as this points to it, or as long as a CP_TOPIC // copied from this pointer points to it. HANDLE m_hev; // event to trigger when this topic is (successfully or // unsuccessfully) loaded. CHourlyDailyCounter m_countLoad; // track attempted loads of this topic CHourlyDailyCounter m_countLoadOK; // track successful loads of this topic CHourlyDailyCounter m_countEvent; // track: initial placement in catalog, file change, // or operator request for change. More interesting for // first & last times than total number. CHourlyDailyCounter m_countHit; // track user requests for this topic... // ... and break them down to hits which are the first on a new cookie // & those which are not CHourlyDailyCounter m_countHitNewCookie; CHourlyDailyCounter m_countHitOldCookie; public: CTopicInCatalog(const CTopicInfo & topicinfo); ~CTopicInCatalog(); CTopicInfo GetTopicInfo() const; void SetTopicInfo(const CTopicInfo &topicinfo); void CountHit(bool bNewCookie); CP_TOPIC & GetTopicNoWait(CP_TOPIC& cpTopic) const; CP_TOPIC & GetTopic(CP_TOPIC& cpTopic) const; void Init(const CTopic* pTopic); void CountChange(); TopicStatus GetTopicStatus() const; bool GetTopicInfoMayNotBeCurrent() const; void TopicInfoIsCurrent(); }; // EOF of class CTopicInCatalog. // This class was created utilizing CTopicInCatalog as a model. We might in the // future revisit these two classes and abstract the common functionality into a // base class. RAB-981030. typedef counting_ptr CP_TEMPLATE; class CTemplateInCatalog { public: enum TemplateStatus {eNotInited, eFail, eOK}; private: CString m_strTemplate; // name to the template bool m_bInited; // true if we have attempted to build m_cpTemplate. // Mainly, this is here so that if we have tried to build // the relevant CAPGTSHTIReader and failed, we don't waste our // time trying to build it again. If this is true and // m_cpTemplate.IsNull(), then we are unable to build this // troubleshooting template. CP_TEMPLATE m_cpTemplate; // smart (counting) pointer. If non-null, points to a // "published" template, which is guaranteed to persist as // long as this points to it, or as long as a CP_TEMPLATE // copied from this pointer points to it. HANDLE m_hev; // event to trigger when this template is (successfully or // unsuccessfully) loaded. CHourlyDailyCounter m_countLoad; // track attempted loads of this template CHourlyDailyCounter m_countLoadOK; // track successful loads of this template CHourlyDailyCounter m_countEvent; // track: initial placement in catalog, file change, // or operator request for change. More interesting for // first & last times than total number. CHourlyDailyCounter m_countHit; // track user requests for this template... public: CTemplateInCatalog( const CString & strTemplate ); ~CTemplateInCatalog(); const CString & GetTemplateInfo() const; void CountHit( bool bNewCookie ); CP_TEMPLATE & GetTemplateNoWait( CP_TEMPLATE& cpTemplate ) const; CP_TEMPLATE & GetTemplate( CP_TEMPLATE& cpTemplate ) const; void Init( const CAPGTSHTIReader* pTemplate ); void CountChange(); void CountFailed(); TemplateStatus GetTemplateStatus() const; DWORD CountOfFailedLoads() const; }; // EOF of class CTemplateInCatalog. // The only functions which need to lock class CTopicShop itself are those which modify TopicCatalog. // TopicBuildQueue has its own protection. class CTopicShop : public CStateless { public: // although this status pertains to CTopicBuildQueue, it must be declared public at // this level, so that we can pass thread status up out of CTopicShop. enum ThreadStatus{eBeforeInit, eFail, eWait, eRun, eExiting}; static CString ThreadStatusText(ThreadStatus ts); private: typedef map CTopicCatalog; typedef map CTemplateCatalog; // Queue of topics to build class CTopicBuildQueue : public CStateless { protected: enum CatalogCategory {eUnknown, eTopic, eTemplate}; private: CTopicCatalog & m_TopicCatalog; CTemplateCatalog & m_TemplateCatalog; CString m_CurrentlyBuilding; // topic currently being built. Strictly lowercase. // it is assumed/enforced that only one topic at // a time will be built. CatalogCategory m_eCurrentlyBuilding;// Category type currently being built. // All strings in the next 4 vectors are strictly lowercase. vectorm_PriorityBuild; // build these first. Someone's waiting for them. vectorm_NonPriorityBuild; vectorm_PriorityBuildTemplates; vectorm_NonPriorityBuildTemplates; HANDLE m_hThread; HANDLE m_hevBuildRequested; // event to wake up TopicBuilderTask. HANDLE m_hevThreadIsShut; // event just to indicate exit of TopicBuilderTask thread bool m_bShuttingDown; // lets topic builder thread know we're shutting down DWORD m_dwErr; // status from starting the thread ThreadStatus m_ThreadStatus; time_t m_time; // time last changed ThreadStatus. Initialized public: CTopicBuildQueue( CTopicCatalog & TopicCatalog, CTemplateCatalog & TemplateCatalog ); ~CTopicBuildQueue(); void RequestBuild(const CString &strTopic, bool bPriority, CatalogCategory eCat ); DWORD GetStatus(ThreadStatus &ts, DWORD & seconds) const; void GetTopicsStatus(DWORD &Total, DWORD &NoInit, DWORD &Fail, vector*parrstrFail) const; void GetTemplatesStatus( vector*parrstrFail, vector*parrcntFail ) const; // Used to shutdown the topic building thread. void ShutDown(); private: CTopicBuildQueue(); // do not instantiate void SetThreadStatus(ThreadStatus ts); // functions for use by the TopicBuilderTask thread. void Build(); bool GetNextToBuild( CString &strTopic, CatalogCategory &eCat ); void BuildComplete(); void AckShutDown(); // main function of the TopicBuilderTask thread. static UINT WINAPI TopicBuilderTask(LPVOID lpParams); }; // EOF of class CTopicBuildQueue. /* class CTopicShop */ private: CTopicCatalog m_TopicCatalog; CTemplateCatalog m_TemplateCatalog; CTopicBuildQueue m_TopicBuildQueue; HANDLE m_hevShopIsOpen; // so that threads wait till we know our list of topics public: CTopicShop(); virtual ~CTopicShop(); void AddTopic(const CTopicInfo & topicinfo); void AddTemplate( const CString & strTemplateName ); void OpenShop(); void BuildTopic(const CString & strTopic, bool *pbAlreadyInCatalog = NULL); void BuildTemplate(const CString & strTemplate); CP_TOPIC & GetTopic(const CString & strTopic, CP_TOPIC & cpTopic, bool bNewCookie); CP_TEMPLATE & GetTemplate( const CString & strTemplate, CP_TEMPLATE & cpTemplate, bool bNewCookie); void GetListOfTopicNames(vector&arrstrTopic) const; void RebuildAll(); DWORD GetThreadStatus(ThreadStatus &ts, DWORD & seconds) const; void GetTopicsStatus(DWORD &Total, DWORD &NoInit, DWORD &Fail, vector*parrstrFail) const; void GetTemplatesStatus( vector*parrstrFail, vector*parrcntFail ) const; CTopicInCatalog* GetCatalogEntry(const CString& strTopic) const; bool RetTemplateInCatalogStatus( const CString& strTemplate, bool& bValid ) const; private: CTopicInCatalog * GetCatalogEntryPtr(const CString & strTopic) const; CTemplateInCatalog * GetTemplateCatalogEntryPtr(const CString & strTemplate) const; }; // EOF of class CTopicShop. #endif // !defined(AFX_TOPICSHOP_H__0CEED643_48C2_11D2_95F3_00C04FC22ADD__INCLUDED_)