//
//  Copyright © 2001 - 2002, RESON Inc. All Rights Reserved.
//
//  No part of this file may be reproduced or transmitted in any form or by
//  any means, electronic or mechanical, including photocopy, recording, or
//  information storage or retrieval system, without permission in writing
//  from RESON Inc.
//
//  Filename:   BaseThread.h
//
//  Project:    6046.
//
//  Author(s):  W. Arcus
//
//  Purpose:    Defines a base class to provide worker thread functionality.
//
//  Notes:      1)  Internal worker thread function executes virtual WatchCycle() that 
//                  typically gets overridden to do message processing etc in a loop until
//                  terminated.
//
//              2)  Worker gets created in a suspended state. Clients need to call CBaseThread::ResumeThread()
//                  to start execution after construction.

#if !defined(AFX_BASETHREAD_H__F9383942_A4A8_4671_BF0A_CF29492F841D__INCLUDED_)
#define AFX_BASETHREAD_H__F9383942_A4A8_4671_BF0A_CF29492F841D__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "Critical.h"

class EXPORT_DLL CBaseThread
{
public:

    // Defintions.

    enum ThreadMessages                                 // Messages specific to this base class.
    {
        threadMessageNoOp       = WM_APP,               // General no-op... used internally ONLY.
        threadMessageTerminate                          // Terminate thread.

        // Inheriting classes should define specific messages starting at threadMessageTerminate + 1.
    };

    // Construction destruction and validation.

                            CBaseThread             (   DWORD               dwDwellPeriod   = INFINITE,
                                                        int                 iPriority       = THREAD_PRIORITY_NORMAL );

    virtual                ~CBaseThread             (   void );

    virtual bool            IsInitialized           (   void ) const;

    DWORD                   ResumeThread            (   void );

    // Thread messaging services.

    BOOL                    PostThreadMessage       (   UINT                uiMsg,
                                                        WPARAM              wParam = 0,
                                                        LPARAM              lParam = 0 );

protected:

    ///////////////
    // Attributes.

    const DWORD             m_dwResumeFailCode;         // ResumeThread() failure code.

    volatile DWORD          m_dwThreadID;               // ID of the watch thread.
    DWORD                   m_dwDwellPeriod;            // Watch thread timeout in ms.

    HANDLE                  m_hThread;                  // The thread handle.

    mutable CCritical       m_StateGuard;               // Critical section object.
    CWinThread             *m_pThread;                  // The thread object.

    ///////////////
    // Services.

    // Virtual overrides.

    virtual void            WatchCycle              (   void );
    virtual BOOL            ProcessMessage          (   MSG        *psMsg );
    virtual BOOL            TerminateThread         (   DWORD       dwTimeOut );

    // Non-overrideable services.

    void                    PumpMessages            (   void );

    BOOL                    WaitForThreadTermination(   DWORD       dwTimeOut = 2000 );

    BOOL                    IsActive                (   void );
    BOOL                    IsInactive              (   void );
    void                    SetActive               (   BOOL        bActive );

private:

    ///////////////
    // Attributes.

    const DWORD             m_dwMessageQueueTimeout;

    BOOL                    m_bActive;                  // Flag used to signal thread termination.
    bool                    m_bInitialized;             // Flag indicating construction was successful.
    HANDLE                  m_hMessageQueueEvent;       // Win32 event handle to signal message queue is ready to recieve posted messages.

    ///////////////
    // Services.

    DWORD                   ThreadID                (   void )  const;

    static UINT             ThreadProc              (   LPVOID              lpvParam );

                            CBaseThread             (   const CBaseThread  &rRhs );     // Not implemented, thus private.
    CBaseThread &           operator =              (   const CBaseThread  &rRhs );     // Not implemented, thus private.

};

#endif // !defined(AFX_BASETHREAD_H__F9383942_A4A8_4671_BF0A_CF29492F841D__INCLUDED_)
