234 lines
9.2 KiB
C++
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
|
|
{
|
|
public:
|
|
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_)
|