12
12
13
13
class hostname_resolver {
14
14
public:
15
- hostname_resolver () {}
15
+ ~hostname_resolver () {
16
+ Log::d (" releasing waiters" );
17
+ queue.release_waiters ();
18
+
19
+ for (auto &w : workers) {
20
+ w->join ();
21
+ }
22
+ }
16
23
17
24
hostname_resolver (int threads) {
18
25
for (int i = 0 ; i < threads; i++) {
19
- workers.push_back (std::make_shared <worker>(this ));
26
+ workers.push_back (std::make_unique <worker>(this ));
20
27
}
21
28
}
22
29
23
- void add_task (std::string hostname, std::function<void (my_addrinfo * )> task, std::function<void()> on_fail) {
30
+ void add_task (std::string hostname, std::function<void (std::shared_ptr< my_addrinfo> )> task, std::function<void()> on_fail) {
24
31
queue.push (resolver_task (hostname, task, on_fail));
25
32
}
26
33
27
- void terminate () {
28
- Log::d (" releasing waiters" );
29
- queue.release_waiters ();
30
-
31
- for (auto &w : workers) {
32
- w->join ();
33
- }
34
- }
35
-
36
34
private:
37
35
struct resolver_task {
38
36
resolver_task () { }
39
37
40
- resolver_task (std::string hostname, std::function<void (my_addrinfo * )> task, std::function<void ()> on_fail)
38
+ resolver_task (std::string hostname, std::function<void (std::shared_ptr< my_addrinfo> )> task, std::function<void ()> on_fail)
41
39
: hostname(hostname), task(task), on_fail(on_fail) { }
42
40
43
41
std::string hostname;
44
- std::function<void (my_addrinfo * )> task;
42
+ std::function<void (std::shared_ptr< my_addrinfo> )> task;
45
43
std::function<void ()> on_fail;
46
44
};
47
45
@@ -50,20 +48,20 @@ class hostname_resolver {
50
48
// worker &operator=(const worker &) = delete;
51
49
52
50
hostname_resolver *resolver;
53
- std::shared_ptr <std::thread> thread;
51
+ std::unique_ptr <std::thread> thread;
54
52
55
53
public:
56
54
57
55
worker (hostname_resolver *_resolver) : resolver(_resolver) {
58
- thread = std::make_shared <std::thread>((std::function<void ()>) ([this ] {
56
+ thread = std::make_unique <std::thread>((std::function<void ()>) ([this ] {
59
57
Log::d (" RESOLVER: resolver thread id: " + inttostr ((int ) pthread_self ()));
60
58
while (1 ) {
61
59
resolver_task task;
62
60
if (!resolver->queue .pop (task)) {
63
61
return ;
64
62
}
65
- my_addrinfo * addrinfo;
66
- if (resolve_hostname (task.hostname , & addrinfo)) {
63
+ std::shared_ptr< my_addrinfo> addrinfo;
64
+ if (resolve_hostname (task.hostname , addrinfo)) {
67
65
task.task (addrinfo);
68
66
} else {
69
67
task.on_fail ();
@@ -83,7 +81,7 @@ class hostname_resolver {
83
81
thread->join ();
84
82
}
85
83
86
- bool resolve_hostname (std::string hostname, my_addrinfo ** result) {
84
+ bool resolve_hostname (std::string hostname, std::shared_ptr< my_addrinfo> & result) {
87
85
Log::d (" RESOLVER: \t Resolving hostname \" " + hostname + " \" " );
88
86
uint16_t port = 80 ;
89
87
@@ -95,10 +93,10 @@ class hostname_resolver {
95
93
96
94
Log::d (" RESOLVER: \t hostname is " + new_hostname + " , port is " + inttostr (port));
97
95
98
- auto it = resolver->cashed_hostnames .find (new_hostname );
96
+ auto it = resolver->cashed_hostnames .find (hostname );
99
97
if (it != resolver->cashed_hostnames .end ()) {
100
98
Log::d (" RESOLVER: taking " + new_hostname + " from cash" );
101
- * result = & it->second ;
99
+ result = it->second ;
102
100
return true ;
103
101
}
104
102
@@ -110,29 +108,35 @@ class hostname_resolver {
110
108
hints.ai_socktype = SOCK_STREAM;
111
109
112
110
if (getaddrinfo (new_hostname.c_str (), inttostr (port).c_str (), &hints, &_servinfo) != 0 ) {
111
+ Log::e (" RESOLVER: getaddrinfo error" );
112
+ perror (" getaddrinfo" );
113
113
return false ;
114
114
}
115
115
116
116
std::unique_lock<std::mutex> lock (resolver->cashing_mutex );
117
- it = resolver->cashed_hostnames .find (new_hostname );
117
+ it = resolver->cashed_hostnames .find (hostname );
118
118
if (it == resolver->cashed_hostnames .end ()) {
119
- resolver->cashed_hostnames .insert (std::make_pair (new_hostname, my_addrinfo (_servinfo)));
119
+ Log::d (" RESOLVER: ok, not found in cash" );
120
+ result = std::make_shared<my_addrinfo>(_servinfo);
121
+ resolver->cashed_hostnames .insert (std::make_pair (hostname, result));
120
122
} else {
123
+ Log::d (" RESOLVER: suddenly found in cash" );
121
124
freeaddrinfo (_servinfo);
125
+ result = it->second ;
122
126
}
123
- * result = &it-> second ;
127
+ Log::d ( std::string ( " RESOLVER: result->ptr is " ) + (result-> get_info () == nullptr ? " nullptr?! " : " not nullptr " )) ;
124
128
// *result = new my_addrinfo(_servinfo);
125
129
return true ;
126
130
}
127
131
};
128
132
129
133
concurrent_queue<resolver_task> queue;
130
134
131
- std::map<std::string, my_addrinfo> cashed_hostnames;
135
+ std::map<std::string, std::shared_ptr< my_addrinfo> > cashed_hostnames;
132
136
std::mutex cashing_mutex;
133
137
134
138
// just for cleaning memory up
135
- std::vector<std::shared_ptr <worker>> workers;
139
+ std::vector<std::unique_ptr <worker>> workers;
136
140
};
137
141
138
142
#endif // KIMBERLY_HOSTNAME_RESOLVER_H
0 commit comments