]> git.tdb.fi Git - libs/net.git/blob - source/net/resolve.h
Use deque instead of list for resolver task queue
[libs/net.git] / source / net / resolve.h
1 #ifndef MSP_NET_RESOLVE_H_
2 #define MSP_NET_RESOLVE_H_
3
4 #include <deque>
5 #include <string>
6 #include <msp/core/mutex.h>
7 #include <msp/core/semaphore.h>
8 #include <msp/core/thread.h>
9 #include <msp/io/eventdispatcher.h>
10 #include <msp/io/pipe.h>
11 #include "constants.h"
12
13 namespace Msp {
14 namespace Net {
15
16 class SockAddr;
17
18 /** Resolves host and service names into a socket address.  If host is empty,
19 the loopback address will be used.  If host is "*", the wildcard address will
20 be used.  If service is empty, a socket address with a null service will be
21 returned.  With the IP families, these are not very useful. */
22 SockAddr *resolve(const std::string &, const std::string &, Family = UNSPEC);
23
24 /** And overload of resolve() that takes host and service as a single string,
25 separated by a colon.  If the host part contains colons, such as is the case
26 with a numeric IPv6 address, it must be enclosed in brackets. */
27 SockAddr *resolve(const std::string &, Family = UNSPEC);
28
29
30 /**
31 An asynchronous name resolver.  Blocking calls are performed in a thread and
32 completion is notified with one of the two signals.
33 */
34 class Resolver
35 {
36 private:
37         struct Task
38         {
39                 unsigned tag;
40                 std::string host;
41                 std::string serv;
42                 Family family;
43                 SockAddr *addr;
44                 std::runtime_error *error;
45
46                 Task();
47
48                 bool is_complete() const { return addr || error; }
49         };
50
51         class WorkerThread: public Thread
52         {
53         private:
54                 std::deque<Task> queue;
55                 Mutex queue_mutex;
56                 Semaphore sem;
57                 IO::Pipe notify_pipe;
58                 bool done;
59
60         public:
61                 WorkerThread();
62                 ~WorkerThread();
63
64                 void add_task(const Task &);
65                 Task *get_complete_task();
66                 void pop_complete_task();
67
68                 IO::Pipe &get_notify_pipe() { return notify_pipe; }
69
70         private:
71                 virtual void main();
72         };
73
74 public:
75         sigc::signal<void, unsigned, const SockAddr &> signal_address_resolved;
76         sigc::signal<void, unsigned, const std::exception &> signal_resolve_failed;
77
78 private:
79         IO::EventDispatcher *event_disp;
80         WorkerThread thread;
81         unsigned next_tag;
82
83 public:
84         Resolver();
85
86         /** Sets the event dispatcher to use.  With no event dispatcher, tick() must
87         be called regularly to emit the completion signals. */
88         void use_event_dispatcher(IO::EventDispatcher *);
89
90         /** Resolves host and service names into a socket address.  Semantics are
91         the same as the namespace-scope resolve function. */
92         unsigned resolve(const std::string &, const std::string &, Family = UNSPEC);
93
94         unsigned resolve(const std::string &, Family = UNSPEC);
95
96         /** Checks for any completed tasks and emits the appropriate singals. */
97         void tick();
98
99 private:
100         void task_done();
101 };
102
103 } // namespace Net
104 } // namespace Msp
105
106 #endif