diff options
Diffstat (limited to 'LibOVR/Src/Kernel/OVR_ThreadCommandQueue.h')
-rw-r--r-- | LibOVR/Src/Kernel/OVR_ThreadCommandQueue.h | 318 |
1 files changed, 0 insertions, 318 deletions
diff --git a/LibOVR/Src/Kernel/OVR_ThreadCommandQueue.h b/LibOVR/Src/Kernel/OVR_ThreadCommandQueue.h deleted file mode 100644 index 9c2a7d3..0000000 --- a/LibOVR/Src/Kernel/OVR_ThreadCommandQueue.h +++ /dev/null @@ -1,318 +0,0 @@ -/************************************************************************************ - -PublicHeader: None -Filename : OVR_ThreadCommandQueue.h -Content : Command queue for operations executed on a thread -Created : October 29, 2012 -Author : Michael Antonov - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_ThreadCommandQueue_h -#define OVR_ThreadCommandQueue_h - -#include "../Kernel/OVR_Types.h" -#include "../Kernel/OVR_List.h" -#include "../Kernel/OVR_Atomic.h" -#include "../Kernel/OVR_Threads.h" - -namespace OVR { - -class ThreadCommand; -class ThreadCommandQueue; - - -//------------------------------------------------------------------------------------- -// ***** ThreadCommand - -// ThreadCommand is a base class implementation for commands stored in ThreadCommandQueue. -class ThreadCommand -{ -public: - // NotifyEvent is used by ThreadCommandQueue::PushCallAndWait to notify the - // calling (producer) thread when command is completed or queue slot is available. - class NotifyEvent : public ListNode<NotifyEvent>, public NewOverrideBase - { - Event E; - public: - NotifyEvent() { } - - void Wait() { E.Wait(); } - void PulseEvent() { E.PulseEvent(); } - }; - - // ThreadCommand::PopBuffer is temporary storage for a command popped off - // by ThreadCommandQueue::PopCommand. - class PopBuffer - { - enum { MaxSize = 256 }; - - size_t Size; - union { - uint8_t Buffer[MaxSize]; - size_t Align; - }; - - ThreadCommand* toCommand() const { return (ThreadCommand*)Buffer; } - - public: - PopBuffer() : Size(0) { } - ~PopBuffer(); - - void InitFromBuffer(void* data); - - bool HasCommand() const { return Size != 0; } - size_t GetSize() const { return Size; } - bool NeedsWait() const { return toCommand()->NeedsWait(); } - NotifyEvent* GetEvent() const { return toCommand()->pEvent; } - - // Execute the command and also notifies caller to finish waiting, - // if necessary. - void Execute(); - }; - - uint16_t Size; - bool WaitFlag; - bool ExitFlag; // Marks the last exit command. - NotifyEvent* pEvent; - - ThreadCommand(size_t size, bool waitFlag, bool exitFlag = false) - : Size((uint16_t)size), WaitFlag(waitFlag), ExitFlag(exitFlag), pEvent(0) { } - virtual ~ThreadCommand() { } - - bool NeedsWait() const { return WaitFlag; } - size_t GetSize() const { return Size; } - - virtual void Execute() const = 0; - // Copy constructor used for serializing this to memory buffer. - virtual ThreadCommand* CopyConstruct(void* p) const = 0; -}; - - -//------------------------------------------------------------------------------------- - -// CleanType is a template that strips 'const' and '&' modifiers from the argument type; -// for example, typename CleanType<A&>::Type is equivalent to A. -template<class T> struct CleanType { typedef T Type; }; -template<class T> struct CleanType<T&> { typedef T Type; }; -template<class T> struct CleanType<const T> { typedef T Type; }; -template<class T> struct CleanType<const T&> { typedef T Type; }; - -// SelfType is a template that yields the argument type. This helps avoid conflicts with -// automatic template argument deduction for function calls when identical argument -// is already defined. -template<class T> struct SelfType { typedef T Type; }; - - - -//------------------------------------------------------------------------------------- -// ThreadCommand specializations for member functions with different number of -// arguments and argument types. - -// Used to return nothing from a ThreadCommand, to avoid problems with 'void'. -struct Void -{ - Void() {} - Void(int) {} -}; - -// ThreadCommand for member function with 0 arguments. -template<class C, class R> -class ThreadCommandMF0 : public ThreadCommand -{ - typedef R (C::*FnPtr)(); - C* pClass; - FnPtr pFn; - R* pRet; - - void executeImpl() const - { - pRet ? (void)(*pRet = (pClass->*pFn)()) : - (void)(pClass->*pFn)(); - } - -public: - ThreadCommandMF0(C* pclass, FnPtr fn, R* ret, bool needsWait) - : ThreadCommand(sizeof(ThreadCommandMF0), needsWait), - pClass(pclass), pFn(fn), pRet(ret) { } - - virtual void Execute() const { executeImpl(); } - virtual ThreadCommand* CopyConstruct(void* p) const - { return Construct<ThreadCommandMF0>(p, *this); } -}; - - -// ThreadCommand for member function with 1 argument. -template<class C, class R, class A0> -class ThreadCommandMF1 : public ThreadCommand -{ - typedef R (C::*FnPtr)(A0); - C* pClass; - FnPtr pFn; - R* pRet; - typename CleanType<A0>::Type AVal0; - - void executeImpl() const - { - pRet ? (void)(*pRet = (pClass->*pFn)(AVal0)) : - (void)(pClass->*pFn)(AVal0); - } - -public: - ThreadCommandMF1(C* pclass, FnPtr fn, R* ret, A0 a0, bool needsWait) - : ThreadCommand(sizeof(ThreadCommandMF1), needsWait), - pClass(pclass), pFn(fn), pRet(ret), AVal0(a0) { } - - virtual void Execute() const { executeImpl(); } - virtual ThreadCommand* CopyConstruct(void* p) const - { return Construct<ThreadCommandMF1>(p, *this); } -}; - -// ThreadCommand for member function with 2 arguments. -template<class C, class R, class A0, class A1> -class ThreadCommandMF2 : public ThreadCommand -{ - typedef R (C::*FnPtr)(A0, A1); - C* pClass; - FnPtr pFn; - R* pRet; - typename CleanType<A0>::Type AVal0; - typename CleanType<A1>::Type AVal1; - - void executeImpl() const - { - pRet ? (void)(*pRet = (pClass->*pFn)(AVal0, AVal1)) : - (void)(pClass->*pFn)(AVal0, AVal1); - } - -public: - ThreadCommandMF2(C* pclass, FnPtr fn, R* ret, A0 a0, A1 a1, bool needsWait) - : ThreadCommand(sizeof(ThreadCommandMF2), needsWait), - pClass(pclass), pFn(fn), pRet(ret), AVal0(a0), AVal1(a1) { } - - virtual void Execute() const { executeImpl(); } - virtual ThreadCommand* CopyConstruct(void* p) const - { return Construct<ThreadCommandMF2>(p, *this); } -}; - - -//------------------------------------------------------------------------------------- -// ***** ThreadCommandQueue - -// ThreadCommandQueue is a queue of executable function-call commands intended to be -// serviced by a single consumer thread. Commands are added to the queue with PushCall -// and removed with PopCall; they are processed in FIFO order. Multiple producer threads -// are supported and will be blocked if internal data buffer is full. - -class ThreadCommandQueue -{ -public: - - ThreadCommandQueue(); - virtual ~ThreadCommandQueue(); - - - // Pops the next command from the thread queue, if any is available. - // The command should be executed by calling popBuffer->Execute(). - // Returns 'false' if no command is available at the time of the call. - bool PopCommand(ThreadCommand::PopBuffer* popBuffer); - - // Generic implementaion of PushCommand; enqueues a command for execution. - // Returns 'false' if push failed, usually indicating thread shutdown. - bool PushCommand(const ThreadCommand& command); - - // - void PushExitCommand(bool wait); - - // Returns 'true' once ExitCommand has been processed, so the thread can shut down. - bool IsExiting() const; - - - // These two virtual functions serve as notifications for derived - // thread waiting. - virtual void OnPushNonEmpty_Locked() { } - virtual void OnPopEmpty_Locked() { } - - - // *** PushCall with no result - - // Enqueue a member function of 'this' class to be called on consumer thread. - // By default the function returns immediately; set 'wait' argument to 'true' to - // wait for completion. - template<class C, class R> - bool PushCall(R (C::*fn)(), bool wait = false) - { return PushCommand(ThreadCommandMF0<C,R>(static_cast<C*>(this), fn, 0, wait)); } - template<class C, class R, class A0> - bool PushCall(R (C::*fn)(A0), typename SelfType<A0>::Type a0, bool wait = false) - { return PushCommand(ThreadCommandMF1<C,R,A0>(static_cast<C*>(this), fn, 0, a0, wait)); } - template<class C, class R, class A0, class A1> - bool PushCall(R (C::*fn)(A0, A1), - typename SelfType<A0>::Type a0, typename SelfType<A1>::Type a1, bool wait = false) - { return PushCommand(ThreadCommandMF2<C,R,A0,A1>(static_cast<C*>(this), fn, 0, a0, a1, wait)); } - // Enqueue a specified member function call of class C. - // By default the function returns immediately; set 'wait' argument to 'true' to - // wait for completion. - template<class C, class R> - bool PushCall(C* p, R (C::*fn)(), bool wait = false) - { return PushCommand(ThreadCommandMF0<C,R>(p, fn, 0, wait)); } - template<class C, class R, class A0> - bool PushCall(C* p, R (C::*fn)(A0), typename SelfType<A0>::Type a0, bool wait = false) - { return PushCommand(ThreadCommandMF1<C,R,A0>(p, fn, 0, a0, wait)); } - template<class C, class R, class A0, class A1> - bool PushCall(C* p, R (C::*fn)(A0, A1), - typename SelfType<A0>::Type a0, typename SelfType<A1>::Type a1, bool wait = false) - { return PushCommand(ThreadCommandMF2<C,R,A0,A1>(p, fn, 0, a0, a1, wait)); } - - - // *** PushCall with Result - - // Enqueue a member function of 'this' class call and wait for call to complete - // on consumer thread before returning. - template<class C, class R> - bool PushCallAndWaitResult(R (C::*fn)(), R* ret) - { return PushCommand(ThreadCommandMF0<C,R>(static_cast<C*>(this), fn, ret, true)); } - template<class C, class R, class A0> - bool PushCallAndWaitResult(R (C::*fn)(A0), R* ret, typename SelfType<A0>::Type a0) - { return PushCommand(ThreadCommandMF1<C,R,A0>(static_cast<C*>(this), fn, ret, a0, true)); } - template<class C, class R, class A0, class A1> - bool PushCallAndWaitResult(R (C::*fn)(A0, A1), R* ret, - typename SelfType<A0>::Type a0, typename SelfType<A1>::Type a1) - { return PushCommand(ThreadCommandMF2<C,R,A0,A1>(static_cast<C*>(this), fn, ret, a0, a1, true)); } - // Enqueue a member function call for class C and wait for the call to complete - // on consumer thread before returning. - template<class C, class R> - bool PushCallAndWaitResult(C* p, R (C::*fn)(), R* ret) - { return PushCommand(ThreadCommandMF0<C,R>(p, fn, ret, true)); } - template<class C, class R, class A0> - bool PushCallAndWaitResult(C* p, R (C::*fn)(A0), R* ret, typename SelfType<A0>::Type a0) - { return PushCommand(ThreadCommandMF1<C,R,A0>(p, fn, ret, a0, true)); } - template<class C, class R, class A0, class A1> - bool PushCallAndWaitResult(C* p, R (C::*fn)(A0, A1), R* ret, - typename SelfType<A0>::Type a0, typename SelfType<A1>::Type a1) - { return PushCommand(ThreadCommandMF2<C,R,A0,A1>(p, fn, ret, a0, a1, true)); } - -private: - class ThreadCommandQueueImpl* pImpl; -}; - - -} // namespace OVR - -#endif // OVR_ThreadCommandQueue_h |