windows-nt/Source/XPSP1/NT/enduser/troubleshoot/tshoot/topicshop.h
2020-09-26 16:20:57 +08:00

234 lines
9.2 KiB
C++

//
// 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 <map>
#pragma warning(disable:4786)
#define LSTFILENAME _T("apgts.lst")
typedef counting_ptr<CTopic> 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<CAPGTSHTIReader> 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<CString, CTopicInCatalog*> CTopicCatalog;
typedef map<CString, CTemplateInCatalog*> 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.
vector<CString>m_PriorityBuild; // build these first. Someone's waiting for them.
vector<CString>m_NonPriorityBuild;
vector<CString>m_PriorityBuildTemplates;
vector<CString>m_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<CString>*parrstrFail) const;
void GetTemplatesStatus( vector<CString>*parrstrFail, vector<DWORD>*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<CString>&arrstrTopic) const;
void RebuildAll();
DWORD GetThreadStatus(ThreadStatus &ts, DWORD & seconds) const;
void GetTopicsStatus(DWORD &Total, DWORD &NoInit, DWORD &Fail, vector<CString>*parrstrFail) const;
void GetTemplatesStatus( vector<CString>*parrstrFail, vector<DWORD>*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_)