Go to the documentation of this file.00001
00002
00003
00004
00005 #ifndef __THREADSAFE_ALLOCATING_QUEUE
00006 #define __THREADSAFE_ALLOCATING_QUEUE
00007
00008 #include "DS_Queue.h"
00009 #include "SimpleMutex.h"
00010 #include "DS_MemoryPool.h"
00011
00012 #if defined(new)
00013 #pragma push_macro("new")
00014 #undef new
00015 #define RMO_NEW_UNDEF_ALLOCATING_QUEUE
00016 #endif
00017
00018 namespace DataStructures
00019 {
00020
00021 template <class structureType>
00022 class RAK_DLL_EXPORT ThreadsafeAllocatingQueue
00023 {
00024 public:
00025
00026 void Push(structureType *s);
00027 structureType *PopInaccurate(void);
00028 structureType *Pop(void);
00029 void SetPageSize(int size);
00030 bool IsEmpty(void);
00031
00032
00033 structureType *Allocate(const char *file, unsigned int line);
00034 void Deallocate(structureType *s, const char *file, unsigned int line);
00035 void Clear(const char *file, unsigned int line);
00036 protected:
00037
00038 MemoryPool<structureType> memoryPool;
00039 SimpleMutex memoryPoolMutex;
00040 Queue<structureType*> queue;
00041 SimpleMutex queueMutex;
00042 };
00043
00044 template <class structureType>
00045 void ThreadsafeAllocatingQueue<structureType>::Push(structureType *s)
00046 {
00047 queueMutex.Lock();
00048 queue.Push(s, __FILE__, __LINE__ );
00049 queueMutex.Unlock();
00050 }
00051
00052 template <class structureType>
00053 structureType *ThreadsafeAllocatingQueue<structureType>::PopInaccurate(void)
00054 {
00055 structureType *s;
00056 if (queue.IsEmpty())
00057 return 0;
00058 queueMutex.Lock();
00059 if (queue.IsEmpty()==false)
00060 s=queue.Pop();
00061 else
00062 s=0;
00063 queueMutex.Unlock();
00064 return s;
00065 }
00066
00067 template <class structureType>
00068 structureType *ThreadsafeAllocatingQueue<structureType>::Pop(void)
00069 {
00070 structureType *s;
00071 queueMutex.Lock();
00072 if (queue.IsEmpty())
00073 {
00074 queueMutex.Unlock();
00075 return 0;
00076 }
00077 s=queue.Pop();
00078 queueMutex.Unlock();
00079 return s;
00080 }
00081
00082 template <class structureType>
00083 structureType *ThreadsafeAllocatingQueue<structureType>::Allocate(const char *file, unsigned int line)
00084 {
00085 structureType *s;
00086 memoryPoolMutex.Lock();
00087 s=memoryPool.Allocate(file, line);
00088 memoryPoolMutex.Unlock();
00089
00090 s = new ((void*)s) structureType;
00091 return s;
00092 }
00093 template <class structureType>
00094 void ThreadsafeAllocatingQueue<structureType>::Deallocate(structureType *s, const char *file, unsigned int line)
00095 {
00096
00097 s->~structureType();
00098 memoryPoolMutex.Lock();
00099 memoryPool.Release(s, file, line);
00100 memoryPoolMutex.Unlock();
00101 }
00102
00103 template <class structureType>
00104 void ThreadsafeAllocatingQueue<structureType>::Clear(const char *file, unsigned int line)
00105 {
00106 memoryPoolMutex.Lock();
00107 for (unsigned int i=0; i < queue.Size(); i++)
00108 {
00109 queue[i]->~structureType();
00110 memoryPool.Release(queue[i], file, line);
00111 }
00112 queue.Clear(file, line);
00113 memoryPoolMutex.Unlock();
00114 memoryPoolMutex.Lock();
00115 memoryPool.Clear(file, line);
00116 memoryPoolMutex.Unlock();
00117 }
00118
00119 template <class structureType>
00120 void ThreadsafeAllocatingQueue<structureType>::SetPageSize(int size)
00121 {
00122 memoryPool.SetPageSize(size);
00123 }
00124
00125 template <class structureType>
00126 bool ThreadsafeAllocatingQueue<structureType>::IsEmpty(void)
00127 {
00128 bool isEmpty;
00129 queueMutex.Lock();
00130 isEmpty=queue.IsEmpty();
00131 queueMutex.Unlock();
00132 return isEmpty;
00133 }
00134
00135 };
00136
00137
00138 #if defined(RMO_NEW_UNDEF_ALLOCATING_QUEUE)
00139 #pragma pop_macro("new")
00140 #undef RMO_NEW_UNDEF_ALLOCATING_QUEUE
00141 #endif
00142
00143 #endif