-#ifdef WIN32
-#define _WIN32_WINNT 0x0501
-#include <ws2tcpip.h>
-#else
-#include <netdb.h>
-#endif
+#include "platform_api.h"
#include <msp/core/systemerror.h>
#include <msp/strings/format.h>
#include "sockaddr_private.h"
SockAddr *resolve(const string &host, const string &serv, Family family)
{
- const char *chost = (host.empty() ? 0 : host.c_str());
- const char *cserv = (serv.empty() ? 0 : serv.c_str());
+ const char *chost = (host.empty() ? nullptr : host.c_str());
+ const char *cserv = (serv.empty() ? nullptr : serv.c_str());
int flags = 0;
if(host=="*")
{
flags = AI_PASSIVE;
- chost = 0;
+ chost = nullptr;
}
- addrinfo hints = { flags, family_to_sys(family), 0, 0, 0, 0, 0, 0 };
+ addrinfo hints = { flags, family_to_sys(family), 0, 0, 0, nullptr, nullptr, nullptr };
addrinfo *res;
int err = getaddrinfo(chost, cserv, &hints, &res);
return addr;
}
else
-#ifdef WIN32
+#ifdef _WIN32
throw system_error("getaddrinfo", WSAGetLastError());
#else
throw system_error("getaddrinfo", gai_strerror(err));
}
-Resolver::Resolver():
- event_disp(0),
- next_tag(1)
+Resolver::Resolver()
{
thread.get_notify_pipe().signal_data_available.connect(sigc::mem_fun(this, &Resolver::task_done));
}
task.host = host;
task.serv = serv;
task.family = family;
- thread.add_task(task);
+ thread.add_task(move(task));
return task.tag;
}
if(task->addr)
signal_address_resolved.emit(task->tag, *task->addr);
else if(task->error)
+ {
+ if(signal_resolve_failed.empty())
+ {
+ unique_ptr<runtime_error> err = move(task->error);
+ thread.pop_complete_task();
+ throw *err;
+ }
signal_resolve_failed.emit(task->tag, *task->error);
+ }
thread.pop_complete_task();
}
}
-Resolver::Task::Task():
- tag(0),
- family(UNSPEC),
- addr(0),
- error(0)
-{ }
-
-
Resolver::WorkerThread::WorkerThread():
Thread("Resolver"),
- sem(1),
- done(false)
+ sem(1)
{
launch();
}
join();
}
-void Resolver::WorkerThread::add_task(const Task &t)
+void Resolver::WorkerThread::add_task(Task &&t)
{
MutexLock lock(queue_mutex);
bool was_starved = (queue.empty() || queue.back().is_complete());
- queue.push_back(t);
+ queue.push_back(move(t));
if(was_starved)
sem.signal();
}
if(!queue.empty() && queue.front().is_complete())
return &queue.front();
else
- return 0;
+ return nullptr;
}
void Resolver::WorkerThread::pop_complete_task()
{
MutexLock lock(queue_mutex);
if(!queue.empty() && queue.front().is_complete())
- {
- delete queue.front().addr;
- delete queue.front().error;
queue.pop_front();
- }
}
void Resolver::WorkerThread::main()
sem.wait();
wait = false;
- Task *task = 0;
+ Task *task = nullptr;
{
MutexLock lock(queue_mutex);
- for(list<Task>::iterator i=queue.begin(); (!task && i!=queue.end()); ++i)
+ for(auto i=queue.begin(); (!task && i!=queue.end()); ++i)
if(!i->is_complete())
task = &*i;
}
{
try
{
- SockAddr *addr = Net::resolve(task->host, task->serv, task->family);
+ unique_ptr<SockAddr> addr(Net::resolve(task->host, task->serv, task->family));
{
MutexLock lock(queue_mutex);
- task->addr = addr;
+ task->addr = move(addr);
}
}
catch(const runtime_error &e)
{
MutexLock lock(queue_mutex);
- task->error = new runtime_error(e);
+ task->error = make_unique<runtime_error>(e);
}
notify_pipe.put(1);
}
}
}
- /*sockaddr sa;
- unsigned size = fill_sockaddr(sa);
- char hst[128];
- char srv[128];
- int err = getnameinfo(&sa, size, hst, 128, srv, 128, 0);
- if(err==0)
- {
- host = hst;
- serv = srv;
- }*/
-
} // namespace Net
} // namespace Msp