PageRenderTime 24ms CodeModel.GetById 11ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llcommon/llworkerthread.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 204 lines | 104 code | 43 blank | 57 comment | 0 complexity | 15db6209ceff5ab600569813cb84f17b MD5 | raw file
  1/** 
  2 * @file llworkerthread.h
  3 *
  4 * $LicenseInfo:firstyear=2004&license=viewerlgpl$
  5 * Second Life Viewer Source Code
  6 * Copyright (C) 2010, Linden Research, Inc.
  7 * 
  8 * This library is free software; you can redistribute it and/or
  9 * modify it under the terms of the GNU Lesser General Public
 10 * License as published by the Free Software Foundation;
 11 * version 2.1 of the License only.
 12 * 
 13 * This library is distributed in the hope that it will be useful,
 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 16 * Lesser General Public License for more details.
 17 * 
 18 * You should have received a copy of the GNU Lesser General Public
 19 * License along with this library; if not, write to the Free Software
 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 21 * 
 22 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 23 * $/LicenseInfo$
 24 */
 25
 26#ifndef LL_LLWORKERTHREAD_H
 27#define LL_LLWORKERTHREAD_H
 28
 29#include <queue>
 30#include <string>
 31#include <map>
 32#include <set>
 33
 34#include "llqueuedthread.h"
 35#include "llapr.h"
 36
 37#define USE_FRAME_CALLBACK_MANAGER 0
 38
 39//============================================================================
 40
 41class LLWorkerClass;
 42
 43//============================================================================
 44// Note: ~LLWorkerThread is O(N) N=# of worker threads, assumed to be small
 45//   It is assumed that LLWorkerThreads are rarely created/destroyed.
 46
 47class LL_COMMON_API LLWorkerThread : public LLQueuedThread
 48{
 49	friend class LLWorkerClass;
 50public:
 51	class WorkRequest : public LLQueuedThread::QueuedRequest
 52	{
 53	protected:
 54		virtual ~WorkRequest(); // use deleteRequest()
 55		
 56	public:
 57		WorkRequest(handle_t handle, U32 priority, LLWorkerClass* workerclass, S32 param);
 58
 59		S32 getParam()
 60		{
 61			return mParam;
 62		}
 63		LLWorkerClass* getWorkerClass()
 64		{
 65			return mWorkerClass;
 66		}
 67
 68		/*virtual*/ bool processRequest();
 69		/*virtual*/ void finishRequest(bool completed);
 70		/*virtual*/ void deleteRequest();
 71		
 72	private:
 73		LLWorkerClass* mWorkerClass;
 74		S32 mParam;
 75	};
 76
 77protected:
 78	void clearDeleteList() ;
 79
 80private:
 81	typedef std::list<LLWorkerClass*> delete_list_t;
 82	delete_list_t mDeleteList;
 83	LLMutex* mDeleteMutex;
 84	
 85public:
 86	LLWorkerThread(const std::string& name, bool threaded = true, bool should_pause = false);
 87	~LLWorkerThread();
 88
 89	/*virtual*/ S32 update(F32 max_time_ms);
 90	
 91	handle_t addWorkRequest(LLWorkerClass* workerclass, S32 param, U32 priority = PRIORITY_NORMAL);
 92	
 93	S32 getNumDeletes() { return (S32)mDeleteList.size(); } // debug
 94
 95private:
 96	void deleteWorker(LLWorkerClass* workerclass); // schedule for deletion
 97	
 98};
 99
100//============================================================================
101
102// This is a base class which any class with worker functions should derive from.
103// Example Usage:
104//  LLMyWorkerClass* foo = new LLMyWorkerClass();
105//  foo->fetchData(); // calls addWork()
106//  while(1) // main loop
107//  {
108//     if (foo->hasData()) // calls checkWork()
109//        foo->processData();
110//  }
111//
112// WorkerClasses only have one set of work functions. If they need to do multiple
113//  background tasks, use 'param' to switch amnong them.
114// Only one background task can be active at a time (per instance).
115//  i.e. don't call addWork() if haveWork() returns true
116
117class LL_COMMON_API LLWorkerClass
118{
119	friend class LLWorkerThread;
120	friend class LLWorkerThread::WorkRequest;
121
122public:
123	typedef LLWorkerThread::handle_t handle_t;
124	enum FLAGS
125	{
126		WCF_HAVE_WORK = 0x01,
127		WCF_WORKING = 0x02,
128		WCF_WORK_FINISHED = 0x10,
129		WCF_WORK_ABORTED = 0x20,
130		WCF_DELETE_REQUESTED = 0x40,
131		WCF_ABORT_REQUESTED = 0x80
132	};
133	
134public:
135	LLWorkerClass(LLWorkerThread* workerthread, const std::string& name);
136	virtual ~LLWorkerClass();
137
138	// pure virtual, called from WORKER THREAD, returns TRUE if done
139	virtual bool doWork(S32 param)=0; // Called from WorkRequest::processRequest()
140	// virtual, called from finishRequest() after completed or aborted
141	virtual void finishWork(S32 param, bool completed); // called from finishRequest() (WORK THREAD)
142	// virtual, returns true if safe to delete the worker
143	virtual bool deleteOK(); // called from update() (WORK THREAD)
144	
145	// schedlueDelete(): schedules deletion once aborted or completed
146	void scheduleDelete();
147	
148	bool haveWork() { return getFlags(WCF_HAVE_WORK); } // may still be true if aborted
149	bool isWorking() { return getFlags(WCF_WORKING); }
150	bool wasAborted() { return getFlags(WCF_ABORT_REQUESTED); }
151
152	// setPriority(): changes the priority of a request
153	void setPriority(U32 priority);
154	U32  getPriority() { return mRequestPriority; }
155		
156	const std::string& getName() const { return mWorkerClassName; }
157
158protected:
159	// called from WORKER THREAD
160	void setWorking(bool working);
161	
162	// Call from doWork only to avoid eating up cpu time.
163	// Returns true if work has been aborted
164	// yields the current thread and calls mWorkerThread->checkPause()
165	bool yield();
166	
167	void setWorkerThread(LLWorkerThread* workerthread);
168
169	// addWork(): calls startWork, adds doWork() to queue
170	void addWork(S32 param, U32 priority = LLWorkerThread::PRIORITY_NORMAL);
171
172	// abortWork(): requests that work be aborted
173	void abortWork(bool autocomplete);
174	
175	// checkWork(): if doWork is complete or aborted, call endWork() and return true
176	bool checkWork(bool aborting = false);
177
178private:
179	void setFlags(U32 flags) { mWorkFlags = mWorkFlags | flags; }
180	void clearFlags(U32 flags) { mWorkFlags = mWorkFlags & ~flags; }
181	U32  getFlags() { return mWorkFlags; }
182public:
183	bool getFlags(U32 flags) { return mWorkFlags & flags ? true : false; }
184	
185private:
186	// pure virtuals
187	virtual void startWork(S32 param)=0; // called from addWork() (MAIN THREAD)
188	virtual void endWork(S32 param, bool aborted)=0; // called from doWork() (MAIN THREAD)
189	
190protected:
191	LLWorkerThread* mWorkerThread;
192	std::string mWorkerClassName;
193	handle_t mRequestHandle;
194	U32 mRequestPriority; // last priority set
195
196private:
197	LLMutex mMutex;
198	LLAtomicU32 mWorkFlags;
199};
200
201//============================================================================
202
203
204#endif // LL_LLWORKERTHREAD_H