OperationThread 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
  2. *
  3. * This library is open source and may be redistributed and/or modified under
  4. * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
  5. * (at your option) any later version. The full license is in LICENSE file
  6. * included with this distribution, and on the openscenegraph.org website.
  7. *
  8. * This library is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * OpenSceneGraph Public License for more details.
  12. */
  13. #ifndef OSG_OPERATIONTHREAD
  14. #define OSG_OPERATIONTHREAD 1
  15. #include <osg/observer_ptr>
  16. #include <osg/Object>
  17. #include <OpenThreads/Thread>
  18. #include <OpenThreads/Barrier>
  19. #include <OpenThreads/Condition>
  20. #include <OpenThreads/Block>
  21. #include <list>
  22. #include <set>
  23. namespace osg {
  24. class RefBlock : virtual public osg::Referenced, public OpenThreads::Block
  25. {
  26. public:
  27. RefBlock():
  28. osg::Referenced(true) {}
  29. };
  30. class RefBlockCount : virtual public osg::Referenced, public OpenThreads::BlockCount
  31. {
  32. public:
  33. RefBlockCount(unsigned blockCount):
  34. osg::Referenced(true),
  35. OpenThreads::BlockCount(blockCount) {}
  36. };
  37. /** Base class for implementing graphics operations.*/
  38. class Operation : virtual public Referenced
  39. {
  40. public:
  41. Operation(const std::string& name, bool keep):
  42. _name(name),
  43. _keep(keep) {}
  44. /** Set the human readable name of the operation.*/
  45. void setName(const std::string& name) { _name = name; }
  46. /** Get the human readable name of the operation.*/
  47. const std::string& getName() const { return _name; }
  48. /** Set whether the operation should be kept once its been applied.*/
  49. void setKeep(bool keep) { _keep = keep; }
  50. /** Get whether the operation should be kept once its been applied.*/
  51. bool getKeep() const { return _keep; }
  52. /** if this operation is a barrier then release it.*/
  53. virtual void release() {}
  54. /** Do the actual task of this operation.*/
  55. virtual void operator () (Object*) = 0;
  56. protected:
  57. Operation():
  58. _keep(false) {}
  59. virtual ~Operation() {}
  60. std::string _name;
  61. bool _keep;
  62. };
  63. class OperationThread;
  64. class OSG_EXPORT OperationQueue : public Referenced
  65. {
  66. public:
  67. OperationQueue();
  68. /** Get the next operation from the operation queue.
  69. * Return null ref_ptr<> if no operations are left in queue. */
  70. osg::ref_ptr<Operation> getNextOperation(bool blockIfEmpty = false);
  71. /** Return true if the operation queue is empty. */
  72. bool empty();
  73. /** Return the num of pending operations that are sitting in the OperationQueue.*/
  74. unsigned int getNumOperationsInQueue();
  75. /** Add operation to end of OperationQueue, this will be
  76. * executed by the operation thread once this operation gets to the head of the queue.*/
  77. void add(Operation* operation);
  78. /** Remove operation from OperationQueue.*/
  79. void remove(Operation* operation);
  80. /** Remove named operation from OperationQueue.*/
  81. void remove(const std::string& name);
  82. /** Remove all operations from OperationQueue.*/
  83. void removeAllOperations();
  84. /** Run the operations. */
  85. void runOperations(Object* callingObject=0);
  86. /** Call release on all operations. */
  87. void releaseAllOperations();
  88. /** Release operations block that is used to block threads that are waiting on an empty operations queue.*/
  89. void releaseOperationsBlock();
  90. typedef std::set<OperationThread*> OperationThreads;
  91. /** Get the set of OperationThreads that are sharing this OperationQueue. */
  92. const OperationThreads& getOperationThreads() const { return _operationThreads; }
  93. protected:
  94. virtual ~OperationQueue();
  95. friend class OperationThread;
  96. void addOperationThread(OperationThread* thread);
  97. void removeOperationThread(OperationThread* thread);
  98. typedef std::list< osg::ref_ptr<Operation> > Operations;
  99. OpenThreads::Mutex _operationsMutex;
  100. osg::ref_ptr<osg::RefBlock> _operationsBlock;
  101. Operations _operations;
  102. Operations::iterator _currentOperationIterator;
  103. OperationThreads _operationThreads;
  104. };
  105. /** OperationThread is a helper class for running Operation within a single thread.*/
  106. class OSG_EXPORT OperationThread : public Referenced, public OpenThreads::Thread
  107. {
  108. public:
  109. OperationThread();
  110. void setParent(Object* parent) { _parent = parent; }
  111. Object* getParent() { return _parent.get(); }
  112. const Object* getParent() const { return _parent.get(); }
  113. /** Set the OperationQueue. */
  114. void setOperationQueue(OperationQueue* opq);
  115. /** Get the OperationQueue. */
  116. OperationQueue* getOperationQueue() { return _operationQueue.get(); }
  117. /** Get the const OperationQueue. */
  118. const OperationQueue* getOperationQueue() const { return _operationQueue.get(); }
  119. /** Add operation to end of OperationQueue, this will be
  120. * executed by the graphics thread once this operation gets to the head of the queue.*/
  121. void add(Operation* operation);
  122. /** Remove operation from OperationQueue.*/
  123. void remove(Operation* operation);
  124. /** Remove named operation from OperationQueue.*/
  125. void remove(const std::string& name);
  126. /** Remove all operations from OperationQueue.*/
  127. void removeAllOperations();
  128. /** Get the operation currently being run.*/
  129. osg::ref_ptr<Operation> getCurrentOperation() { return _currentOperation; }
  130. /** Run does the opertion thread run loop.*/
  131. virtual void run();
  132. void setDone(bool done);
  133. bool getDone() const { return _done!=0; }
  134. /** Cancel this graphics thread.*/
  135. virtual int cancel();
  136. protected:
  137. virtual ~OperationThread();
  138. observer_ptr<Object> _parent;
  139. OpenThreads::Atomic _done;
  140. OpenThreads::Mutex _threadMutex;
  141. osg::ref_ptr<OperationQueue> _operationQueue;
  142. osg::ref_ptr<Operation> _currentOperation;
  143. };
  144. typedef OperationThread OperationsThread;
  145. }
  146. #endif