OpenNI 1.5.7
XnThreadSafeQueue.h
Go to the documentation of this file.
00001 /*****************************************************************************
00002 *                                                                            *
00003 *  OpenNI 1.x Alpha                                                          *
00004 *  Copyright (C) 2012 PrimeSense Ltd.                                        *
00005 *                                                                            *
00006 *  This file is part of OpenNI.                                              *
00007 *                                                                            *
00008 *  Licensed under the Apache License, Version 2.0 (the "License");           *
00009 *  you may not use this file except in compliance with the License.          *
00010 *  You may obtain a copy of the License at                                   *
00011 *                                                                            *
00012 *      http://www.apache.org/licenses/LICENSE-2.0                            *
00013 *                                                                            *
00014 *  Unless required by applicable law or agreed to in writing, software       *
00015 *  distributed under the License is distributed on an "AS IS" BASIS,         *
00016 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  *
00017 *  See the License for the specific language governing permissions and       *
00018 *  limitations under the License.                                            *
00019 *                                                                            *
00020 *****************************************************************************/
00021 #ifndef __XN_THREAD_SAFE_QUEUE_H__
00022 #define __XN_THREAD_SAFE_QUEUE_H__
00023 
00024 //---------------------------------------------------------------------------
00025 // Includes
00026 //---------------------------------------------------------------------------
00027 #include <XnQueue.h>
00028 #include <XnOS.h>
00029 
00030 //---------------------------------------------------------------------------
00031 // Types
00032 //---------------------------------------------------------------------------
00036 class XnThreadSafeQueue : public XnQueue
00037 {
00038 public:
00039     XnThreadSafeQueue() : m_hLock(NULL) {}
00040 
00041     ~XnThreadSafeQueue()
00042     {
00043         xnOSCloseCriticalSection(&m_hLock);
00044     }
00045 
00046     XnStatus Init()
00047     {
00048         XnStatus nRetVal = XN_STATUS_OK;
00049 
00050         nRetVal = xnOSCreateCriticalSection(&m_hLock);
00051         XN_IS_STATUS_OK(nRetVal);
00052 
00053         return (XN_STATUS_OK);
00054     }
00055 
00056     XnStatus Push(XnValue const& value)
00057     {
00058         XnStatus nRetVal = XN_STATUS_OK;
00059 
00060         nRetVal = xnOSEnterCriticalSection(&m_hLock);
00061         XN_IS_STATUS_OK(nRetVal);
00062 
00063         nRetVal = XnQueue::Push(value);
00064         xnOSLeaveCriticalSection(&m_hLock);
00065 
00066         return nRetVal;
00067     }
00068 
00069     XnStatus Pop(XnValue& value)
00070     {
00071         XnStatus nRetVal = XN_STATUS_OK;
00072 
00073         nRetVal = xnOSEnterCriticalSection(&m_hLock);
00074         XN_IS_STATUS_OK(nRetVal);
00075 
00076         nRetVal = XnQueue::Pop(value);
00077         xnOSLeaveCriticalSection(&m_hLock);
00078 
00079         return nRetVal;
00080     }
00081 
00082     XnUInt32 Size() const
00083     {
00084         xnOSEnterCriticalSection(&m_hLock);
00085         XnUInt32 nSize = XnQueue::Size();
00086         xnOSLeaveCriticalSection(&m_hLock);
00087         return (nSize);
00088     }
00089 
00090 private:
00091     // NOTE: we declare the lock as mutable, as it may change on const methods.
00092     mutable XN_CRITICAL_SECTION_HANDLE m_hLock;
00093 };
00094 
00100 #define XN_DECLARE_THREAD_SAFE_QUEUE_WITH_TRANSLATOR_DECL(decl, Type, ClassName, Translator)    \
00101     class decl ClassName : public XnThreadSafeQueue                                     \
00102     {                                                                                   \
00103     public:                                                                             \
00104         ~ClassName()                                                                    \
00105         {                                                                               \
00106             /* We do this using Pop() to make sure memory is freed. */                  \
00107             Type dummy;                                                                 \
00108             while (Size() != 0)                                                         \
00109                 Pop(dummy);                                                             \
00110         }                                                                               \
00111         XnStatus Push(Type const& value)                                                \
00112         {                                                                               \
00113             XnValue val = Translator::CreateValueCopy(value);                           \
00114             XnStatus nRetVal = XnThreadSafeQueue::Push(val);                            \
00115             if (nRetVal != XN_STATUS_OK)                                                \
00116             {                                                                           \
00117                 Translator::FreeValue(val);                                             \
00118                 return (nRetVal);                                                       \
00119             }                                                                           \
00120             return XN_STATUS_OK;                                                        \
00121         }                                                                               \
00122         XnStatus Pop(Type& value)                                                       \
00123         {                                                                               \
00124             XnValue val;                                                                \
00125             XnStatus nRetVal = XnThreadSafeQueue::Pop(val);                             \
00126             if (nRetVal != XN_STATUS_OK) return (nRetVal);                              \
00127             value = Translator::GetFromValue(val);                                      \
00128             Translator::FreeValue(val);                                                 \
00129             return XN_STATUS_OK;                                                        \
00130         }                                                                               \
00131     };
00132 
00138 #define XN_DECLARE_THREAD_SAFE_QUEUE_WITH_TRANSLATOR(Type, ClassName, Translator)               \
00139     XN_DECLARE_THREAD_SAFE_QUEUE_WITH_TRANSLATOR_DECL(, Type, ClassName, Translator)
00140 
00145 #define XN_DECLARE_THREAD_SAFE_QUEUE_DECL(decl, Type, ClassName)                                            \
00146     XN_DECLARE_DEFAULT_VALUE_TRANSLATOR_DECL(decl, Type, XN_DEFAULT_TRANSLATOR_NAME(ClassName))             \
00147     XN_DECLARE_THREAD_SAFE_QUEUE_WITH_TRANSLATOR_DECL(decl, Type, ClassName, XN_DEFAULT_TRANSLATOR_NAME(ClassName))
00148 
00152 #define XN_DECLARE_THREAD_SAFE_QUEUE(Type, ClassName)       \
00153     XN_DECLARE_THREAD_SAFE_QUEUE_DECL(, Type, ClassName)
00154 
00155 #endif //__XN_THREAD_SAFE_QUEUE_H__