OGRE  1.9.0
OgreWorkQueue.h
Go to the documentation of this file.
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4(Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2014 Torus Knot Software Ltd
8
9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal
11in the Software without restriction, including without limitation the rights
12to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13copies of the Software, and to permit persons to whom the Software is
14furnished to do so, subject to the following conditions:
15
16The above copyright notice and this permission notice shall be included in
17all copies or substantial portions of the Software.
18
19THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25THE SOFTWARE.
26-----------------------------------------------------------------------------
27*/
28#ifndef __OgreWorkQueue_H__
29#define __OgreWorkQueue_H__
30
31#include "OgrePrerequisites.h"
32#include "OgreAny.h"
33#include "OgreSharedPtr.h"
35#include "OgreHeaderPrefix.h"
36
37namespace Ogre
38{
71 {
72 protected:
77 public:
79 typedef unsigned long long int RequestID;
80
84 {
85 friend class WorkQueue;
86 protected:
98 mutable bool mAborted;
99
100 public:
105 void abortRequest() const { mAborted = true; }
107 uint16 getChannel() const { return mChannel; }
109 uint16 getType() const { return mType; }
111 const Any& getData() const { return mData; }
113 uint8 getRetryCount() const { return mRetryCount; }
115 RequestID getID() const { return mID; }
117 bool getAborted() const { return mAborted; }
118 };
119
123 {
132
133 public:
134 Response(const Request* rq, bool success, const Any& data, const String& msg = StringUtil::BLANK);
137 const Request* getRequest() const { return mRequest; }
139 bool succeeded() const { return mSuccess; }
141 const String& getMessages() const { return mMessages; }
143 const Any& getData() const { return mData; }
145 void abortRequest() { mRequest->abortRequest(); mData.destroy(); }
146 };
147
162 {
163 public:
165 virtual ~RequestHandler() {}
166
173 virtual bool canHandleRequest(const Request* req, const WorkQueue* srcQ)
174 { (void)srcQ; return !req->getAborted(); }
175
186 virtual Response* handleRequest(const Request* req, const WorkQueue* srcQ) = 0;
187 };
188
197 {
198 public:
200 virtual ~ResponseHandler() {}
201
208 virtual bool canHandleResponse(const Response* res, const WorkQueue* srcQ)
209 { (void)srcQ; return !res->getRequest()->getAborted(); }
210
218 virtual void handleResponse(const Response* res, const WorkQueue* srcQ) = 0;
219 };
220
221 WorkQueue() : mNextChannel(0) {}
222 virtual ~WorkQueue() {}
223
228 virtual void startup(bool forceRestart = true) = 0;
241
254
273 bool forceSynchronous = false, bool idleThread = false) = 0;
274
280 virtual void abortRequest(RequestID id) = 0;
281
289
297
302 virtual void abortAllRequests() = 0;
303
309 virtual void setPaused(bool pause) = 0;
311 virtual bool isPaused() const = 0;
312
317 virtual void setRequestsAccepted(bool accept) = 0;
319 virtual bool getRequestsAccepted() const = 0;
320
329 virtual void processResponses() = 0;
330
334 virtual unsigned long getResponseProcessingTimeLimit() const = 0;
335
341 virtual void setResponseProcessingTimeLimit(unsigned long ms) = 0;
342
345 virtual void shutdown() = 0;
346
355
356 };
357
361 {
362 public:
363
368 DefaultWorkQueueBase(const String& name = StringUtil::BLANK);
371 const String& getName() const;
375 virtual size_t getWorkerThreadCount() const;
376
382 virtual void setWorkerThreadCount(size_t c);
383
394
395
408
416 virtual void _processNextRequest();
417
419 virtual void _threadMain() = 0;
420
422 virtual bool isShuttingDown() const { return mShuttingDown; }
423
432
435 bool forceSynchronous = false, bool idleThread = false);
437 virtual void abortRequest(RequestID id);
443 virtual void abortAllRequests();
445 virtual void setPaused(bool pause);
447 virtual bool isPaused() const;
449 virtual void setRequestsAccepted(bool accept);
451 virtual bool getRequestsAccepted() const;
453 virtual void processResponses();
455 virtual unsigned long getResponseProcessingTimeLimit() const { return mResposeTimeLimitMS; }
457 virtual void setResponseProcessingTimeLimit(unsigned long ms) { mResposeTimeLimitMS = ms; }
458 protected:
463 unsigned long mResposeTimeLimitMS;
464
467 RequestQueue mRequestQueue; // Guarded by mRequestMutex
468 RequestQueue mProcessQueue; // Guarded by mProcessMutex
469 ResponseQueue mResponseQueue; // Guarded by mResponseMutex
470
473 {
475
477 : mQueue(q) {}
478
480
481 void operator()() const;
482
483 void run();
484 };
485 WorkerFunc* mWorkerFunc;
486
492 {
493 protected:
496 public:
498 : mHandler(handler) {}
499
500 // Disconnect the handler to allow it to be destroyed
502 {
503 // write lock - must wait for all requests to finish
505 mHandler = 0;
506 }
507
511 RequestHandler* getHandler() { return mHandler; }
512
517 {
518 // Read mutex so that multiple requests can be processed by the
519 // same handler in parallel if required
521 Response* response = 0;
522 if (mHandler)
523 {
524 if (mHandler->canHandleRequest(req, srcQ))
525 {
526 response = mHandler->handleRequest(req, srcQ);
527 }
528 }
529 return response;
530 }
531
532 };
533 // Hold these by shared pointer so they can be copied keeping same instance
535
540
543 RequestID mRequestCount; // Guarded by mRequestMutex
547
548 //NOTE: If you lock multiple mutexes at the same time, the order is important!
549 // For example if threadA locks mIdleMutex first then tries to lock mProcessMutex,
550 // and threadB locks mProcessMutex first, then mIdleMutex. In this case you can get livelock and the system is dead!
551 //RULE: Lock mProcessMutex before other mutex, to prevent livelocks
557
558
559 void processRequestResponse(Request* r, bool synchronous);
563 virtual void notifyWorkers() = 0;
566
567 RequestQueue mIdleRequestQueue; // Guarded by mIdleMutex
568 bool mIdleThreadRunning; // Guarded by mIdleMutex
569 Request* mIdleProcessed; // Guarded by mProcessMutex
570
571
573 };
574
575
576
577
578
582}
583
584#include "OgreHeaderSuffix.h"
585
586#endif
587
#define _OgreExport
#define OGRE_LOCK_RW_MUTEX_WRITE(name)
#define OGRE_LOCK_RW_MUTEX_READ(name)
Superclass for all objects that wish to use custom memory allocators when their new / delete operator...
Variant type that can hold Any other type.
Definition OgreAny.h:57
void destroy()
Definition OgreAny.h:122
Intermediate structure to hold a pointer to a request handler which provides insurance against the ha...
RequestHandler * getHandler()
Get handler pointer - note, only use this for == comparison or similar, do not attempt to call it as ...
Response * handleRequest(const Request *req, const WorkQueue *srcQ)
Process a request if possible.
Base for a general purpose request / response style background work queue.
virtual void processResponses()
Process the responses in the queue.
virtual void abortAllRequests()
Abort all previously issued requests.
deque< Request * >::type RequestQueue
virtual bool isShuttingDown() const
Returns whether the queue is trying to shut down.
void processResponse(Response *r)
virtual void removeRequestHandler(uint16 channel, RequestHandler *rh)
Remove a request handler.
virtual void setRequestsAccepted(bool accept)
Set whether to accept new requests or not.
void addRequestWithRID(RequestID rid, uint16 channel, uint16 requestType, const Any &rData, uint8 retryCount)
Put a Request on the queue with a specific RequestID.
deque< Response * >::type ResponseQueue
DefaultWorkQueueBase(const String &name=StringUtil::BLANK)
Constructor.
void processRequestResponse(Request *r, bool synchronous)
const String & getName() const
Get the name of the work queue.
SharedPtr< RequestHandlerHolder > RequestHandlerHolderPtr
virtual void _threadMain()=0
Main function for each thread spawned.
virtual void setWorkersCanAccessRenderSystem(bool access)
Set whether worker threads will be allowed to access render system resources.
map< uint16, RequestHandlerList >::type RequestHandlerListByChannel
OGRE_MUTEX(mResponseMutex)
virtual void abortRequest(RequestID id)
Abort a previously issued request.
virtual void setResponseProcessingTimeLimit(unsigned long ms)
Set the time limit imposed on the processing of responses in a single frame, in milliseconds (0 indic...
virtual void setWorkerThreadCount(size_t c)
Set the number of worker threads that this queue will start when startup() is called (default 1).
virtual void setPaused(bool pause)
Set whether to pause further processing of any requests.
virtual void addRequestHandler(uint16 channel, RequestHandler *rh)
Add a request handler instance to the queue.
list< ResponseHandler * >::type ResponseHandlerList
list< RequestHandlerHolderPtr >::type RequestHandlerList
virtual unsigned long getResponseProcessingTimeLimit() const
Get the time limit imposed on the processing of responses in a single frame, in milliseconds (0 indic...
virtual void addResponseHandler(uint16 channel, ResponseHandler *rh)
Add a response handler instance to the queue.
virtual void notifyWorkers()=0
Notify workers about a new request.
virtual bool isPaused() const
Return whether the queue is paused ie not sending more work to workers.
virtual bool getRequestsAccepted() const
Returns whether requests are being accepted right now.
map< uint16, ResponseHandlerList >::type ResponseHandlerListByChannel
virtual bool getWorkersCanAccessRenderSystem() const
Get whether worker threads will be allowed to access render system resources.
ResponseHandlerListByChannel mResponseHandlers
virtual size_t getWorkerThreadCount() const
Get the number of worker threads that this queue will start when startup() is called.
virtual void abortPendingRequestsByChannel(uint16 channel)
Abort all previously issued requests in a given channel.
virtual RequestID addRequest(uint16 channel, uint16 requestType, const Any &rData, uint8 retryCount=0, bool forceSynchronous=false, bool idleThread=false)
Add a new request to the queue.
Response * processRequest(Request *r)
RequestHandlerListByChannel mRequestHandlers
unsigned long mResposeTimeLimitMS
virtual void removeResponseHandler(uint16 channel, ResponseHandler *rh)
Remove a Response handler.
virtual void abortRequestsByChannel(uint16 channel)
Abort all previously issued requests in a given channel.
OGRE_RW_MUTEX(mRequestHandlerMutex)
virtual void _processNextRequest()
Process the next request on the queue.
Reference-counted shared pointer, used for objects where implicit destruction is required.
Interface definition for a handler of requests.
virtual Response * handleRequest(const Request *req, const WorkQueue *srcQ)=0
The handler method every subclass must implement.
virtual bool canHandleRequest(const Request *req, const WorkQueue *srcQ)
Return whether this handler can process a given request.
General purpose request structure.
uint16 getChannel() const
Get the request channel (top level categorisation)
uint8 getRetryCount() const
Get the remaining retry count.
uint16 mType
The request type, as an integer within the channel (user can define enumerations on this)
RequestID mID
Identifier (assigned by the system)
uint16 getType() const
Get the type of this request within the given channel.
bool getAborted() const
Get the abort flag.
RequestID getID() const
Get the identifier of this request.
const Any & getData() const
Get the user details of this request.
bool mAborted
Abort Flag.
void abortRequest() const
Set the abort flag.
uint16 mChannel
The request channel, as an integer.
uint8 mRetryCount
Retry count - set this to non-zero to have the request try again on failure.
Any mData
The details of the request (user defined)
Request(uint16 channel, uint16 rtype, const Any &rData, uint8 retry, RequestID rid)
Constructor.
Interface definition for a handler of responses.
virtual bool canHandleResponse(const Response *res, const WorkQueue *srcQ)
Return whether this handler can process a given response.
virtual void handleResponse(const Response *res, const WorkQueue *srcQ)=0
The handler method every subclass must implement.
Interface to a general purpose request / response style background work queue.
unsigned long long int RequestID
Numeric identifier for a request.
virtual void setRequestsAccepted(bool accept)=0
Set whether to accept new requests or not.
virtual ~WorkQueue()
virtual void setPaused(bool pause)=0
Set whether to pause further processing of any requests.
virtual void shutdown()=0
Shut down the queue.
ChannelMap mChannelMap
virtual void abortRequest(RequestID id)=0
Abort a previously issued request.
map< String, uint16 >::type ChannelMap
virtual bool isPaused() const =0
Return whether the queue is paused ie not sending more work to workers.
virtual uint16 getChannel(const String &channelName)
Get a channel ID for a given channel name.
virtual unsigned long getResponseProcessingTimeLimit() const =0
Get the time limit imposed on the processing of responses in a single frame, in milliseconds (0 indic...
virtual void setResponseProcessingTimeLimit(unsigned long ms)=0
Set the time limit imposed on the processing of responses in a single frame, in milliseconds (0 indic...
virtual void addRequestHandler(uint16 channel, RequestHandler *rh)=0
Add a request handler instance to the queue.
virtual void processResponses()=0
Process the responses in the queue.
OGRE_MUTEX(mChannelMapMutex)
virtual void removeRequestHandler(uint16 channel, RequestHandler *rh)=0
Remove a request handler.
virtual void abortAllRequests()=0
Abort all previously issued requests.
virtual void removeResponseHandler(uint16 channel, ResponseHandler *rh)=0
Remove a Response handler.
virtual bool getRequestsAccepted() const =0
Returns whether requests are being accepted right now.
virtual void addResponseHandler(uint16 channel, ResponseHandler *rh)=0
Add a response handler instance to the queue.
virtual void abortRequestsByChannel(uint16 channel)=0
Abort all previously issued requests in a given channel.
virtual RequestID addRequest(uint16 channel, uint16 requestType, const Any &rData, uint8 retryCount=0, bool forceSynchronous=false, bool idleThread=false)=0
Add a new request to the queue.
virtual void startup(bool forceRestart=true)=0
Start up the queue with the options that have been set.
virtual void abortPendingRequestsByChannel(uint16 channel)=0
Abort all previously issued requests in a given channel.
unsigned char uint8
unsigned short uint16
_StringBase String
General purpose response structure.
Any mData
Data associated with the result of the process.
const String & getMessages() const
Get any diagnostic messages about the process.
const Request * getRequest() const
Get the request that this is a response to (NB destruction destroys this)
Response(const Request *rq, bool success, const Any &data, const String &msg=StringUtil::BLANK)
void abortRequest()
Abort the request.
String mMessages
Any diagnostic messages.
bool mSuccess
Whether the work item succeeded or not.
bool succeeded() const
Return whether this is a successful response.
const Any & getData() const
Return the response data (user defined, only valid on success)
const Request * mRequest
Pointer to the request that this response is in relation to.
std::deque< T, A > type
std::list< T, A > type
std::map< K, V, P, A > type