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 
00049 
00050 
00051 class LLWorkerThread : public LLQueuedThread
00052 {
00053 public:
00054         class WorkRequest : public LLQueuedThread::QueuedRequest
00055         {
00056         protected:
00057                 virtual ~WorkRequest(); 
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                  bool processRequest();
00072                  void finishRequest(bool completed);
00073                  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          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); 
00097         S32 getNumDeletes() { return (S32)mDeleteList.size(); } 
00098 };
00099 
00100 
00101 
00102 
00103 
00104 
00105 
00106 
00107 
00108 
00109 
00110 
00111 
00112 
00113 
00114 
00115 
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         
00138         virtual bool doWork(S32 param)=0; 
00139         
00140         virtual void finishWork(S32 param, bool completed); 
00141         
00142         virtual bool deleteOK(); 
00143         
00144         
00145         void scheduleDelete();
00146         
00147         bool haveWork() { return getFlags(WCF_HAVE_WORK); } 
00148         bool isWorking() { return getFlags(WCF_WORKING); }
00149         bool wasAborted() { return getFlags(WCF_ABORT_REQUESTED); }
00150 
00151         
00152         void setPriority(U32 priority);
00153         U32  getPriority() { return mRequestPriority; }
00154                 
00155         const std::string& getName() const { return mWorkerClassName; }
00156 
00157 protected:
00158         
00159         void setWorking(bool working);
00160         
00161         
00162         
00163         
00164         bool yield();
00165         
00166         void setWorkerThread(LLWorkerThread* workerthread);
00167 
00168         
00169         void addWork(S32 param, U32 priority = LLWorkerThread::PRIORITY_NORMAL);
00170 
00171         
00172         void abortWork(bool autocomplete);
00173         
00174         
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         
00185         virtual void startWork(S32 param)=0; 
00186         virtual void endWork(S32 param, bool aborted)=0; 
00187         
00188 protected:
00189         LLWorkerThread* mWorkerThread;
00190         std::string mWorkerClassName;
00191         handle_t mRequestHandle;
00192         U32 mRequestPriority; 
00193 
00194 private:
00195         LLMutex mMutex;
00196         LLAtomicU32 mWorkFlags;
00197 };
00198 
00199 
00200 
00201 
00202 #endif // LL_LLWORKERTHREAD_H