llworkerthread.h

Go to the documentation of this file.
00001 
00031 #ifndef LL_LLWORKERTHREAD_H
00032 #define LL_LLWORKERTHREAD_H
00033 
00034 #include <queue>
00035 #include <string>
00036 #include <map>
00037 #include <set>
00038 
00039 #include "llqueuedthread.h"
00040 
00041 #define USE_FRAME_CALLBACK_MANAGER 0
00042 
00043 //============================================================================
00044 
00045 class LLWorkerClass;
00046 
00047 //============================================================================
00048 // Note: ~LLWorkerThread is O(N) N=# of worker threads, assumed to be small
00049 //   It is assumed that LLWorkerThreads are rarely created/destroyed.
00050 
00051 class LLWorkerThread : public LLQueuedThread
00052 {
00053 public:
00054         class WorkRequest : public LLQueuedThread::QueuedRequest
00055         {
00056         protected:
00057                 virtual ~WorkRequest(); // use deleteRequest()
00058                 
00059         public:
00060                 WorkRequest(handle_t handle, U32 priority, LLWorkerClass* workerclass, S32 param);
00061 
00062                 S32 getParam()
00063                 {
00064                         return mParam;
00065                 }
00066                 LLWorkerClass* getWorkerClass()
00067                 {
00068                         return mWorkerClass;
00069                 }
00070 
00071                 /*virtual*/ bool processRequest();
00072                 /*virtual*/ void finishRequest(bool completed);
00073                 /*virtual*/ void deleteRequest();
00074                 
00075         private:
00076                 LLWorkerClass* mWorkerClass;
00077                 S32 mParam;
00078         };
00079 
00080 private:
00081         typedef std::list<LLWorkerClass*> delete_list_t;
00082         delete_list_t mDeleteList;
00083         LLMutex* mDeleteMutex;
00084         apr_pool_t* mWorkerAPRPoolp;
00085         
00086 public:
00087         LLWorkerThread(const std::string& name, bool threaded = true);
00088         ~LLWorkerThread();
00089 
00090         apr_pool_t* getWorkerAPRPool() { return mWorkerAPRPoolp; }
00091         
00092         /*virtual*/ S32 update(U32 max_time_ms);
00093         
00094         handle_t addWorkRequest(LLWorkerClass* workerclass, S32 param, U32 priority = PRIORITY_NORMAL);
00095         
00096         void deleteWorker(LLWorkerClass* workerclass); // schedule for deletion
00097         S32 getNumDeletes() { return (S32)mDeleteList.size(); } // debug
00098 };
00099 
00100 //============================================================================
00101 
00102 // This is a base class which any class with worker functions should derive from.
00103 // Example Usage:
00104 //  LLMyWorkerClass* foo = new LLMyWorkerClass();
00105 //  foo->fetchData(); // calls addWork()
00106 //  while(1) // main loop
00107 //  {
00108 //     if (foo->hasData()) // calls checkWork()
00109 //        foo->processData();
00110 //  }
00111 //
00112 // WorkerClasses only have one set of work functions. If they need to do multiple
00113 //  background tasks, use 'param' to switch amnong them.
00114 // Only one background task can be active at a time (per instance).
00115 //  i.e. don't call addWork() if haveWork() returns true
00116 
00117 class LLWorkerClass
00118 {
00119         friend class LLWorkerThread;
00120         friend class LLWorkerThread::WorkRequest;
00121 public:
00122         typedef LLWorkerThread::handle_t handle_t;
00123         enum FLAGS
00124         {
00125                 WCF_HAVE_WORK = 0x01,
00126                 WCF_WORKING = 0x02,
00127                 WCF_WORK_FINISHED = 0x10,
00128                 WCF_WORK_ABORTED = 0x20,
00129                 WCF_DELETE_REQUESTED = 0x40,
00130                 WCF_ABORT_REQUESTED = 0x80
00131         };
00132         
00133 public:
00134         LLWorkerClass(LLWorkerThread* workerthread, const std::string& name);
00135         virtual ~LLWorkerClass();
00136 
00137         // pure virtual, called from WORKER THREAD, returns TRUE if done
00138         virtual bool doWork(S32 param)=0; // Called from WorkRequest::processRequest()
00139         // virtual, called from finishRequest() after completed or aborted
00140         virtual void finishWork(S32 param, bool completed); // called from finishRequest() (WORK THREAD)
00141         // virtual, returns true if safe to delete the worker
00142         virtual bool deleteOK(); // called from update() (WORK THREAD)
00143         
00144         // schedlueDelete(): schedules deletion once aborted or completed
00145         void scheduleDelete();
00146         
00147         bool haveWork() { return getFlags(WCF_HAVE_WORK); } // may still be true if aborted
00148         bool isWorking() { return getFlags(WCF_WORKING); }
00149         bool wasAborted() { return getFlags(WCF_ABORT_REQUESTED); }
00150 
00151         // setPriority(): changes the priority of a request
00152         void setPriority(U32 priority);
00153         U32  getPriority() { return mRequestPriority; }
00154                 
00155         const std::string& getName() const { return mWorkerClassName; }
00156 
00157 protected:
00158         // called from WORKER THREAD
00159         void setWorking(bool working);
00160         
00161         // Call from doWork only to avoid eating up cpu time.
00162         // Returns true if work has been aborted
00163         // yields the current thread and calls mWorkerThread->checkPause()
00164         bool yield();
00165         
00166         void setWorkerThread(LLWorkerThread* workerthread);
00167 
00168         // addWork(): calls startWork, adds doWork() to queue
00169         void addWork(S32 param, U32 priority = LLWorkerThread::PRIORITY_NORMAL);
00170 
00171         // abortWork(): requests that work be aborted
00172         void abortWork(bool autocomplete);
00173         
00174         // checkWork(): if doWork is complete or aborted, call endWork() and return true
00175         bool checkWork(bool aborting = false);
00176 
00177 private:
00178         void setFlags(U32 flags) { mWorkFlags = mWorkFlags | flags; }
00179         void clearFlags(U32 flags) { mWorkFlags = mWorkFlags & ~flags; }
00180         U32  getFlags() { return mWorkFlags; }
00181         bool getFlags(U32 flags) { return mWorkFlags & flags ? true : false; }
00182         
00183 private:
00184         // pure virtuals
00185         virtual void startWork(S32 param)=0; // called from addWork() (MAIN THREAD)
00186         virtual void endWork(S32 param, bool aborted)=0; // called from doWork() (MAIN THREAD)
00187         
00188 protected:
00189         LLWorkerThread* mWorkerThread;
00190         std::string mWorkerClassName;
00191         handle_t mRequestHandle;
00192         U32 mRequestPriority; // last priority set
00193 
00194 private:
00195         LLMutex mMutex;
00196         LLAtomicU32 mWorkFlags;
00197 };
00198 
00199 //============================================================================
00200 
00201 
00202 #endif // LL_LLWORKERTHREAD_H

Generated on Thu Jul 1 06:09:47 2010 for Second Life Viewer by  doxygen 1.4.7