diff options
Diffstat (limited to 'indra/llcommon/llworkerthread.h')
-rw-r--r-- | indra/llcommon/llworkerthread.h | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/indra/llcommon/llworkerthread.h b/indra/llcommon/llworkerthread.h new file mode 100644 index 0000000000..bf5887e797 --- /dev/null +++ b/indra/llcommon/llworkerthread.h @@ -0,0 +1,168 @@ +/** + * @file llworkerthread.h + * + * Copyright (c) 2004-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#ifndef LL_LLWORKERTHREAD_H +#define LL_LLWORKERTHREAD_H + +#include <queue> +#include <string> +#include <map> +#include <set> + +#include "llqueuedthread.h" + +#define USE_FRAME_CALLBACK_MANAGER 0 + +//============================================================================ + +class LLWorkerClass; + +//============================================================================ +// Note: ~LLWorkerThread is O(N) N=# of worker threads, assumed to be small +// It is assumed that LLWorkerThreads are rarely created/destroyed. + +class LLWorkerThread : public LLQueuedThread +{ +public: + class Request : public LLQueuedThread::QueuedRequest + { + protected: + ~Request() {}; // use deleteRequest() + + public: + Request(handle_t handle, U32 priority, LLWorkerClass* workerclass, S32 param); + + S32 getParam() + { + return mParam; + } + LLWorkerClass* getWorkerClass() + { + return mWorkerClass; + } + + /*virtual*/ void deleteRequest(); + + private: + LLWorkerClass* mWorkerClass; + S32 mParam; + }; + +public: + LLWorkerThread(bool threaded = true, bool runalways = true); + ~LLWorkerThread(); + +protected: + /*virtual*/ bool processRequest(QueuedRequest* req); + +public: + handle_t add(LLWorkerClass* workerclass, S32 param, U32 priority = PRIORITY_NORMAL); + + static void initClass(bool local_is_threaded = true, bool local_run_always = true); // Setup sLocal + static S32 updateClass(U32 ms_elapsed); + static S32 getAllPending(); + static void pauseAll(); + static void waitOnAllPending(); + static void cleanupClass(); // Delete sLocal + +public: + static LLWorkerThread* sLocal; // Default worker thread + static std::set<LLWorkerThread*> sThreadList; // array of threads (includes sLocal) +}; + +//============================================================================ + +// This is a base class which any class with worker functions should derive from. +// Example Usage: +// LLMyWorkerClass* foo = new LLMyWorkerClass(); +// foo->fetchData(); // calls addWork() +// while(1) // main loop +// { +// if (foo->hasData()) // calls checkWork() +// foo->processData(); +// } +// +// WorkerClasses only have one set of work functions. If they need to do multiple +// background tasks, use 'param' to switch amnong them. +// Only one background task can be active at a time (per instance). +// i.e. don't call addWork() if haveWork() returns true + +class LLWorkerClass +{ +public: + typedef LLWorkerThread::handle_t handle_t; + enum FLAGS + { + WCF_WORKING = 0x01, + WCF_ABORT_REQUESTED = 0x80 + }; + +public: + LLWorkerClass(LLWorkerThread* workerthread, const std::string& name); + virtual ~LLWorkerClass(); + + // pure virtual, called from WORKER THREAD, returns TRUE if done + virtual bool doWork(S32 param)=0; // Called from LLWorkerThread::processRequest() + + // called from WORKER THREAD + void setWorking(bool working) { working ? setFlags(WCF_WORKING) : clearFlags(WCF_WORKING); } + + bool isWorking() { return getFlags(WCF_WORKING); } + bool wasAborted() { return getFlags(WCF_ABORT_REQUESTED); } + + const std::string& getName() const { return mWorkerClassName; } + +protected: + // Call from doWork only to avoid eating up cpu time. + // Returns true if work has been aborted + // yields the current thread and calls mWorkerThread->checkPause() + bool yield(); + + void setWorkerThread(LLWorkerThread* workerthread); + + // addWork(): calls startWork, adds doWork() to queue + void addWork(S32 param, U32 priority = LLWorkerThread::PRIORITY_NORMAL); + + // abortWork(): requests that work be aborted + void abortWork(); + + // checkWork(): if doWork is complete or aborted, call endWork() and return true + bool checkWork(); + + // haveWork(): return true if mWorkHandle != null + bool haveWork() { return mWorkHandle != LLWorkerThread::nullHandle(); } + + // killWork(): aborts work and waits for the abort to process + void killWork(); + + // setPriority(): changes the priority of a request + void setPriority(U32 priority); + +private: + void setFlags(U32 flags) { mWorkFlags = mWorkFlags | flags; } + void clearFlags(U32 flags) { mWorkFlags = mWorkFlags & ~flags; } + U32 getFlags() { return mWorkFlags; } + bool getFlags(U32 flags) { return mWorkFlags & flags ? true : false; } + +private: + // pure virtuals + virtual void startWork(S32 param)=0; // called from addWork() (MAIN THREAD) + virtual void endWork(S32 param, bool aborted)=0; // called from doWork() (MAIN THREAD) + +protected: + LLWorkerThread* mWorkerThread; + std::string mWorkerClassName; + handle_t mWorkHandle; + +private: + LLAtomicU32 mWorkFlags; +}; + +//============================================================================ + + +#endif // LL_LLWORKERTHREAD_H |