forked from tjanczuk/iisnode
/
cconnectionpool.cpp
91 lines (74 loc) · 1.78 KB
/
cconnectionpool.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include "precomp.h"
CConnectionPool::CConnectionPool()
: count(0), list(NULL)
{
}
HRESULT CConnectionPool::Initialize(IHttpContext* ctx)
{
HRESULT hr;
ErrorIf(NULL == (this->list = (PSLIST_HEADER)_aligned_malloc(sizeof(SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT)), ERROR_NOT_ENOUGH_MEMORY);
this->maxPoolSize = 512; // TODO, expose configuration for this
this->maxAge = 30000; // TODO, expose configuration for this
InitializeSListHead(this->list);
return S_OK;
Error:
return hr;
}
CConnectionPool::~CConnectionPool()
{
PSLIST_ENTRY entry;
if (this->list)
{
while (NULL != (entry = InterlockedPopEntrySList(this->list)))
{
CloseHandle(((PCONNECTION_ENTRY)entry)->connection);
_aligned_free(entry);
}
_aligned_free(this->list);
this->list = NULL;
}
}
HRESULT CConnectionPool::Return(HANDLE connection)
{
HRESULT hr;
PCONNECTION_ENTRY entry = NULL;
if (this->count >= this->maxPoolSize)
{
CloseHandle(connection);
}
else
{
ErrorIf(NULL == (entry = (PCONNECTION_ENTRY)_aligned_malloc(sizeof(CONNECTION_ENTRY), MEMORY_ALLOCATION_ALIGNMENT)), ERROR_NOT_ENOUGH_MEMORY);
entry->connection = connection;
entry->timestamp = GetTickCount();
InterlockedPushEntrySList(this->list, &(entry->listEntry));
InterlockedIncrement(&this->count);
}
return S_OK;
Error:
return hr;
}
HANDLE CConnectionPool::Take()
{
HANDLE result = INVALID_HANDLE_VALUE;
PCONNECTION_ENTRY entry;
DWORD now = GetTickCount();
while (NULL != (entry = (PCONNECTION_ENTRY)InterlockedPopEntrySList(this->list)))
{
InterlockedDecrement(&this->count);
if ((now - entry->timestamp) < this->maxAge)
{
result = entry->connection;
}
else
{
CloseHandle(entry->connection);
}
_aligned_free(entry);
if (INVALID_HANDLE_VALUE != result)
{
break;
}
}
return result;
}