/** \file
 *
 *  Contains the ThreadHandler class declaration
 *
 *  Copyright (c) 2007,2008,2009 MBARI
 *  MBARI Proprietary Information.  All Rights Reserved
 */

#ifndef THREADHANDLER_H_
#define THREADHANDLER_H_

#include <pthread.h>
#include "Handler.h"
#include "utils/Mutex.h"

/**
 *  A ThreadHandler is a Handler which runs in its own thread.
 *
 *  This is the primary abstraction for a "thread" in this software.
 *  When wrapped around a Component, this handler spins off a separate thread
 *  and executes the component in it.
 *
 *  \ingroup process
 */
class ThreadHandler : public Handler
{
public:

    static int PthreadJoinTimeout( pthread_t wid, unsigned int msecs, Component &component );

    /// Constructor
    ///
    /// \param inComponent  Component being handled, passed to Handler
    /// \param name  Name for this (fed to its logger_)
    /// \param idleThread  true if the thread wrapper for the component should be ile priority
    ThreadHandler( Component &inComponent, const Str& name, bool idleThread, bool controlThread = false );

    /// Destructor
    virtual ~ThreadHandler();

    /// Overrides Handler::run().  Contains the actual launch of the new
    /// thread, then returns.
    virtual void run();

    /// The entry point for the new thread.  A static function.
    static void *ThreadEntryPoint( void *me );

    /// A static entry point for a cleanup callback.
    static void ThreadCleanup( void *me );

    /// A member function for the cleanup callback (called from threadCleanup)
    void cleanup( void );

    /// The new replacement for Handler::run() which runs in the thread.,
    /// Run from the static threadEntryPoint.  This in turn runs Handler::run()
    /// with some thread-specific entry and exit code.
    virtual void runInThread();

    /// Evaluates additional thread-specific continue conditions.
    virtual bool continueLoop( void );

    /// Cleanup the component (typically called from outside component)
    virtual void shutdown( void );

    //=== Functions primarily for running within the thread ===

    /// Called by the thread to end itself (pthread_Exit)
    void exitThread( void );

    //=== Functions primarily for running _outside_ the thread ===

    /// A "soft exit", requests the thread end on next loop.
    void cancelThread( void );

    /// Join the thread
    void joinThread( void );

    /// End the thread immediately (uses pthread_cancel)
    void killThread( void );

    const pthread_t& getThreadId()
    {
        return threadID_;
    }

protected:

    /// Keeps track of the "cancelled" signal from cancelThread
    bool cancelled_;

private:

    //bool running;
    //Mutex runningMutex;

    /// The thread ID
    pthread_t threadID_;

    /// the thread attributes
    pthread_attr_t threadAttributes_;

};

#endif /*THREADHANDLER_H_*/
