aboutsummaryrefslogtreecommitdiff
path: root/src/lib/daemon_get_fdset.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/daemon_get_fdset.c')
-rw-r--r--src/lib/daemon_get_fdset.c166
1 files changed, 164 insertions, 2 deletions
diff --git a/src/lib/daemon_get_fdset.c b/src/lib/daemon_get_fdset.c
index afbf3d6b..c3b0dbd9 100644
--- a/src/lib/daemon_get_fdset.c
+++ b/src/lib/daemon_get_fdset.c
@@ -62,7 +62,142 @@ MHD_daemon_get_fdset (struct MHD_Daemon *daemon,
62 fd_set *except_fd_set, 62 fd_set *except_fd_set,
63 MHD_socket *max_fd) 63 MHD_socket *max_fd)
64{ 64{
65 return -1; 65 return MHD_daemon_get_fdset2 (daemon,
66 read_fd_set,
67 write_fd_set,
68 except_fd_set,
69 max_fd,
70 _MHD_SYS_DEFAULT_FD_SETSIZE);
71}
72
73
74/**
75 * Internal version of #MHD_daemon_get_fdset2().
76 *
77 * @param daemon daemon to get sets from
78 * @param read_fd_set read set
79 * @param write_fd_set write set
80 * @param except_fd_set except set
81 * @param max_fd increased to largest FD added (if larger
82 * than existing value); can be NULL
83 * @param fd_setsize value of FD_SETSIZE
84 * @return #MHD_SC_OK on success
85 * @ingroup event
86 */
87static enum MHD_StatusCode
88internal_get_fdset2 (struct MHD_Daemon *daemon,
89 fd_set *read_fd_set,
90 fd_set *write_fd_set,
91 fd_set *except_fd_set,
92 MHD_socket *max_fd,
93 unsigned int fd_setsize)
94
95{
96 struct MHD_Connection *pos;
97 struct MHD_Connection *posn;
98 int result = MHD_YES;
99 MHD_socket ls;
100
101 if (daemon->shutdown)
102 return MHD_NO;
103
104 ls = daemon->listen_socket;
105 if ( (MHD_INVALID_SOCKET != ls) &&
106 (! daemon->was_quiesced) &&
107 (! MHD_add_to_fd_set_ (ls,
108 read_fd_set,
109 max_fd,
110 fd_setsize)) )
111 result = MHD_NO;
112
113 /* Add all sockets to 'except_fd_set' as well to watch for
114 * out-of-band data. However, ignore errors if INFO_READ
115 * or INFO_WRITE sockets will not fit 'except_fd_set'. */
116 /* Start from oldest connections. Make sense for W32 FDSETs. */
117 for (pos = daemon->connections_tail; NULL != pos; pos = posn)
118 {
119 posn = pos->prev;
120
121 switch (pos->request.event_loop_info)
122 {
123 case MHD_EVENT_LOOP_INFO_READ:
124 if (! MHD_add_to_fd_set_ (pos->socket_fd,
125 read_fd_set,
126 max_fd,
127 fd_setsize))
128 result = MHD_NO;
129#ifdef MHD_POSIX_SOCKETS
130 MHD_add_to_fd_set_ (pos->socket_fd,
131 except_fd_set,
132 max_fd,
133 fd_setsize);
134#endif /* MHD_POSIX_SOCKETS */
135 break;
136 case MHD_EVENT_LOOP_INFO_WRITE:
137 if (! MHD_add_to_fd_set_ (pos->socket_fd,
138 write_fd_set,
139 max_fd,
140 fd_setsize))
141 result = MHD_NO;
142#ifdef MHD_POSIX_SOCKETS
143 MHD_add_to_fd_set_ (pos->socket_fd,
144 except_fd_set,
145 max_fd,
146 fd_setsize);
147#endif /* MHD_POSIX_SOCKETS */
148 break;
149 case MHD_EVENT_LOOP_INFO_BLOCK:
150 if ( (NULL == except_fd_set) ||
151 ! MHD_add_to_fd_set_ (pos->socket_fd,
152 except_fd_set,
153 max_fd,
154 fd_setsize))
155 result = MHD_NO;
156 break;
157 case MHD_EVENT_LOOP_INFO_CLEANUP:
158 /* this should never happen */
159 break;
160 }
161 }
162#ifdef MHD_WINSOCK_SOCKETS
163 /* W32 use limited array for fd_set so add INFO_READ/INFO_WRITE sockets
164 * only after INFO_BLOCK sockets to ensure that INFO_BLOCK sockets will
165 * not be pushed out. */
166 for (pos = daemon->connections_tail; NULL != pos; pos = posn)
167 {
168 posn = pos->prev;
169 MHD_add_to_fd_set_ (pos->socket_fd,
170 except_fd_set,
171 max_fd,
172 fd_setsize);
173 }
174#endif /* MHD_WINSOCK_SOCKETS */
175#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
176 {
177 struct MHD_UpgradeResponseHandle *urh;
178
179 for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev)
180 {
181 if (MHD_NO ==
182 urh_to_fdset (urh,
183 read_fd_set,
184 write_fd_set,
185 except_fd_set,
186 max_fd,
187 fd_setsize))
188 result = MHD_NO;
189 }
190 }
191#endif
192#if DEBUG_CONNECT
193#ifdef HAVE_MESSAGES
194 if (NULL != max_fd)
195 MHD_DLOG (daemon,
196 _("Maximum socket in select set: %d\n"),
197 *max_fd);
198#endif
199#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
200 return result;
66} 201}
67 202
68 203
@@ -101,7 +236,34 @@ MHD_daemon_get_fdset2 (struct MHD_Daemon *daemon,
101 MHD_socket *max_fd, 236 MHD_socket *max_fd,
102 unsigned int fd_setsize) 237 unsigned int fd_setsize)
103{ 238{
104 return -1; 239 if ( (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_model) ||
240 (MHD_ELS_POLL == daemon->event_loop_syscall) )
241 return MHD_SC_CONFIGURATION_MISSMATCH_FOR_GET_FDSET;
242
243#ifdef EPOLL_SUPPORT
244 if (MHD_ELS_EPOLL == daemon->event_loop_syscall)
245 {
246 if (daemon->shutdown)
247 return MHD_SC_DAEMON_ALREADY_SHUTDOWN;
248
249 /* we're in epoll mode, use the epoll FD as a stand-in for
250 the entire event set */
251
252 return MHD_add_to_fd_set_ (daemon->epoll_fd,
253 read_fd_set,
254 max_fd,
255 fd_setsize)
256 ? MHD_SC_OK
257 : MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
258 }
259#endif
260
261 return internal_get_fdset2 (daemon,
262 read_fd_set,
263 write_fd_set,
264 except_fd_set,
265 max_fd,
266 fd_setsize);
105} 267}
106 268
107/* end of daemon_get_fdset.c */ 269/* end of daemon_get_fdset.c */