FreeRDP
ObjectPool.c
1 
20 #include <winpr/config.h>
21 
22 #include <winpr/crt.h>
23 #include <winpr/assert.h>
24 
25 #include <winpr/collections.h>
26 
27 struct s_wObjectPool
28 {
29  size_t size;
30  size_t capacity;
31  void** array;
32  CRITICAL_SECTION lock;
33  wObject object;
34  BOOL synchronized;
35 };
36 
46 static void ObjectPool_Lock(wObjectPool* pool)
47 {
48  WINPR_ASSERT(pool);
49  if (pool->synchronized)
50  EnterCriticalSection(&pool->lock);
51 }
52 
53 static void ObjectPool_Unlock(wObjectPool* pool)
54 {
55  WINPR_ASSERT(pool);
56  if (pool->synchronized)
57  LeaveCriticalSection(&pool->lock);
58 }
59 
64 void* ObjectPool_Take(wObjectPool* pool)
65 {
66  void* obj = NULL;
67 
68  ObjectPool_Lock(pool);
69 
70  if (pool->size > 0)
71  obj = pool->array[--(pool->size)];
72 
73  if (!obj)
74  {
75  if (pool->object.fnObjectNew)
76  obj = pool->object.fnObjectNew(NULL);
77  }
78 
79  if (pool->object.fnObjectInit)
80  pool->object.fnObjectInit(obj);
81 
82  ObjectPool_Unlock(pool);
83 
84  return obj;
85 }
86 
91 void ObjectPool_Return(wObjectPool* pool, void* obj)
92 {
93  ObjectPool_Lock(pool);
94 
95  if ((pool->size + 1) >= pool->capacity)
96  {
97  size_t new_cap = 0;
98  void** new_arr = NULL;
99 
100  new_cap = pool->capacity * 2;
101  new_arr = (void**)realloc(pool->array, sizeof(void*) * new_cap);
102  if (!new_arr)
103  goto out;
104 
105  pool->array = new_arr;
106  pool->capacity = new_cap;
107  }
108 
109  pool->array[(pool->size)++] = obj;
110 
111  if (pool->object.fnObjectUninit)
112  pool->object.fnObjectUninit(obj);
113 
114 out:
115  ObjectPool_Unlock(pool);
116 }
117 
118 wObject* ObjectPool_Object(wObjectPool* pool)
119 {
120  WINPR_ASSERT(pool);
121  return &pool->object;
122 }
123 
128 void ObjectPool_Clear(wObjectPool* pool)
129 {
130  ObjectPool_Lock(pool);
131 
132  while (pool->size > 0)
133  {
134  (pool->size)--;
135 
136  if (pool->object.fnObjectFree)
137  pool->object.fnObjectFree(pool->array[pool->size]);
138  }
139 
140  ObjectPool_Unlock(pool);
141 }
142 
147 wObjectPool* ObjectPool_New(BOOL synchronized)
148 {
149  wObjectPool* pool = NULL;
150 
151  pool = (wObjectPool*)calloc(1, sizeof(wObjectPool));
152 
153  if (pool)
154  {
155  pool->capacity = 32;
156  pool->size = 0;
157  pool->array = (void**)calloc(pool->capacity, sizeof(void*));
158  if (!pool->array)
159  {
160  free(pool);
161  return NULL;
162  }
163  pool->synchronized = synchronized;
164 
165  if (pool->synchronized)
166  InitializeCriticalSectionAndSpinCount(&pool->lock, 4000);
167  }
168 
169  return pool;
170 }
171 
172 void ObjectPool_Free(wObjectPool* pool)
173 {
174  if (pool)
175  {
176  ObjectPool_Clear(pool);
177 
178  if (pool->synchronized)
179  DeleteCriticalSection(&pool->lock);
180 
181  free(pool->array);
182 
183  free(pool);
184  }
185 }
This struct contains function pointer to initialize/free objects.
Definition: collections.h:57