Click
Loading...
Searching...
No Matches
selectset.hh
1// -*- related-file-name: "../../lib/selectset.cc" -*-
2#ifndef CLICK_SELECTSET_HH
3#define CLICK_SELECTSET_HH 1
4#if !CLICK_USERLEVEL
5# error "<click/selectset.hh> only meaningful at user level"
6#endif
7#include <click/vector.hh>
8#include <click/sync.hh>
9#include <unistd.h>
10#if !HAVE_ALLOW_SELECT && !HAVE_ALLOW_POLL && !HAVE_ALLOW_KQUEUE
11# define HAVE_ALLOW_SELECT 1
12#endif
13#if defined(__APPLE__) && HAVE_ALLOW_SELECT && HAVE_ALLOW_POLL
14// Apple's poll() is often broken
15# undef HAVE_ALLOW_POLL
16#endif
17#if HAVE_POLL_H && HAVE_ALLOW_POLL
18# include <poll.h>
19#else
20# undef HAVE_ALLOW_POLL
21# if !HAVE_ALLOW_SELECT && !HAVE_ALLOW_KQUEUE
22# error "poll is not supported on this system, try --enable-select"
23# endif
24#endif
25#if !HAVE_SYS_EVENT_H || !HAVE_KQUEUE
26# undef HAVE_ALLOW_KQUEUE
27# if !HAVE_ALLOW_SELECT && !HAVE_ALLOW_POLL
28# error "kqueue is not supported on this system, try --enable-select"
29# endif
30#endif
31CLICK_DECLS
32class Element;
33class Router;
34class RouterThread;
35
36class SelectSet { public:
37
38 SelectSet();
39 ~SelectSet();
40
41 void initialize();
42
43 int add_select(int fd, Element *element, int mask);
44 int remove_select(int fd, Element *element, int mask);
45
46 bool run_selects(RouterThread *thread);
47 inline void wake_immediate() {
48 _wake_pipe_pending = true;
49 ignore_result(write(_wake_pipe[1], "", 1));
50 }
51
52 void kill_router(Router *router);
53
54 inline void fence();
55
56 private:
57
58 struct SelectorInfo {
59 Element *read;
60 Element *write;
61 int pollfd;
62 SelectorInfo()
63 : read(0), write(0), pollfd(-1)
64 {
65 }
66 };
67
68 int _wake_pipe[2];
69 volatile bool _wake_pipe_pending;
70#if HAVE_ALLOW_KQUEUE
71 int _kqueue;
72#endif
73#if !HAVE_ALLOW_POLL
74 struct pollfd {
75 int fd;
76 int events;
77 };
78 fd_set _read_select_fd_set;
79 fd_set _write_select_fd_set;
80 int _max_select_fd;
81#endif /* !HAVE_ALLOW_POLL */
82 Vector<struct pollfd> _pollfds;
83 Vector<SelectorInfo> _selinfo;
84#if HAVE_MULTITHREAD
85 SimpleSpinlock _select_lock;
86 click_processor_t _select_processor;
87#endif
88
89 void register_select(int fd, bool add_read, bool add_write);
90 void remove_pollfd(int pi, int event);
91 inline void call_selected(int fd, int mask) const;
92 inline bool post_select(RouterThread *thread, bool acquire);
93#if HAVE_ALLOW_KQUEUE
94 bool run_selects_kqueue(RouterThread *thread);
95#endif
96#if HAVE_ALLOW_POLL
97 bool run_selects_poll(RouterThread *thread);
98#else
99 bool run_selects_select(RouterThread *thread);
100#endif
101
102 inline void lock();
103 inline void unlock();
104
105#if CLICK_DEBUG_MASTER || CLICK_DEBUG_SCHEDULING
106 friend class Master;
107#endif
108
109};
110
111inline void
112SelectSet::lock()
113{
114#if HAVE_MULTITHREAD
115 if (click_get_processor() != _select_processor)
116 _select_lock.acquire();
117#endif
118}
119
120inline void
121SelectSet::unlock()
122{
123#if HAVE_MULTITHREAD
124 if (click_get_processor() != _select_processor)
125 _select_lock.release();
126#endif
127}
128
129inline void
130SelectSet::fence()
131{
132 lock();
133 unlock();
134}
135
136CLICK_ENDDECLS
137#endif
Base class for Click elements.
Definition element.hh:42
A router configuration.
Definition router.hh:28
A set of Tasks scheduled on the same CPU.
Definition routerthread.hh:32
A non-recursive spinlock for SMP Click threads.
Definition sync.hh:587
Vector template.
Definition vector.hh:111
Classes for synchronizing among multiple CPUs, particularly in the Linux kernel.
Click's vector container template.