Skip to content

Commit 0c2c52d

Browse files
author
Sebastiano Merlino
committed
http_response_ptr is now thread safe using atomic
1 parent cccacb6 commit 0c2c52d

File tree

1 file changed

+47
-50
lines changed

1 file changed

+47
-50
lines changed

src/httpserver/details/http_response_ptr.hpp

Lines changed: 47 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,26 @@
2525
#ifndef _HTTP_RESPONSE_PTR_HPP_
2626
#define _HTTP_RESPONSE_PTR_HPP_
2727

28+
#include "http_response.hpp"
29+
30+
#if defined(__CLANG_ATOMICS)
31+
32+
#define atomic_increment(object) \
33+
__c11_atomicadd_fetch(object, 1, __ATOMIC_RELAXED)
34+
35+
#define atomic_decrement(object) \
36+
__c11_atomic_sub_fetch(object, 1, __ATOMIC_ACQ_REL)
37+
38+
#else
39+
40+
#define atomic_increment(object) \
41+
__atomic_add_fetch(object, 1, __ATOMIC_RELAXED)
42+
43+
#define atomic_decrement(object) \
44+
__atomic_sub_fetch(object, 1, __ATOMIC_ACQ_REL)
45+
46+
#endif
47+
2848
namespace httpserver
2949
{
3050

@@ -36,78 +56,55 @@ namespace details
3656
struct http_response_ptr
3757
{
3858
public:
39-
http_response_ptr():
40-
res(0x0),
41-
num_references(0x0)
42-
{
43-
num_references = new int(0);
44-
}
45-
http_response_ptr(http_response* res):
46-
res(res),
47-
num_references(0x0)
59+
http_response_ptr(http_response* res = 0x0):
60+
res(res)
4861
{
49-
num_references = new int(0);
62+
num_references = new int(1);
5063
}
64+
5165
http_response_ptr(const http_response_ptr& b):
5266
res(b.res),
5367
num_references(b.num_references)
5468
{
55-
(*num_references)++;
69+
atomic_increment(b.num_references);
5670
}
71+
5772
~http_response_ptr()
5873
{
59-
if(num_references)
60-
{
61-
if((*num_references) == 0)
62-
{
63-
if(res && res->is_autodelete())
64-
{
65-
delete res;
66-
res = 0x0;
67-
}
68-
delete num_references;
69-
}
70-
else
71-
(*num_references)--;
72-
}
74+
if (atomic_decrement(num_references) != 0 || res == 0x0) return;
75+
76+
delete res;
77+
delete num_references;
78+
79+
res = 0x0;
80+
num_references = 0x0;
81+
}
82+
83+
http_response_ptr& operator=(http_response_ptr b)
84+
{
85+
using std::swap;
86+
87+
swap(this->num_references, b.num_references);
88+
swap(this->res, b.res);
89+
90+
return *this;
7391
}
92+
7493
http_response& operator* ()
7594
{
7695
return *res;
7796
}
97+
7898
http_response* operator-> ()
7999
{
80100
return res;
81101
}
102+
82103
http_response* ptr()
83104
{
84105
return res;
85106
}
86-
http_response_ptr& operator= (const http_response_ptr& b)
87-
{
88-
if( this != &b)
89-
{
90-
if(num_references)
91-
{
92-
if((*num_references) == 0)
93-
{
94-
if(res && res->autodelete)
95-
{
96-
delete res;
97-
res = 0x0;
98-
}
99-
delete num_references;
100-
}
101-
else
102-
(*num_references)--;
103-
}
104-
105-
res = b.res;
106-
num_references = b.num_references;
107-
(*num_references)++;
108-
}
109-
return *this;
110-
}
107+
111108
private:
112109
http_response* res;
113110
int* num_references;

0 commit comments

Comments
 (0)