2 * libwebsockets - small server side websockets and web server implementation
4 * Copyright (C) 2010-2019 Andy Green <andy@warmcat.com>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation:
9 * version 2.1 of the License.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
23 #include "core/private.h"
26 wsi_from_fd(const struct lws_context *context, int fd)
28 struct lws **p, **done;
30 if (!context->max_fds_unrelated_to_ulimit)
31 return context->lws_lookup[fd - lws_plat_socket_offset()];
33 /* slow fds handling */
35 p = context->lws_lookup;
36 done = &p[context->max_fds];
39 if (*p && (*p)->desc.sockfd == fd)
48 insert_wsi(const struct lws_context *context, struct lws *wsi)
50 struct lws **p, **done;
52 if (!context->max_fds_unrelated_to_ulimit) {
53 assert(context->lws_lookup[wsi->desc.sockfd -
54 lws_plat_socket_offset()] == 0);
56 context->lws_lookup[wsi->desc.sockfd - \
57 lws_plat_socket_offset()] = wsi;
62 /* slow fds handling */
64 p = context->lws_lookup;
65 done = &p[context->max_fds];
69 /* confirm it doesn't already exist */
71 while (p != done && *p != wsi)
75 p = context->lws_lookup;
77 /* confirm fd doesn't already exist */
79 while (p != done && (!*p || (*p && (*p)->desc.sockfd != wsi->desc.sockfd)))
83 lwsl_err("%s: wsi %p already says it has fd %d\n",
84 __func__, *p, wsi->desc.sockfd);
87 p = context->lws_lookup;
90 /* find an empty slot */
92 while (p != done && *p)
96 lwsl_err("%s: reached max fds\n", __func__);
106 delete_from_fd(const struct lws_context *context, int fd)
109 struct lws **p, **done;
111 if (!context->max_fds_unrelated_to_ulimit) {
112 context->lws_lookup[fd - lws_plat_socket_offset()] = NULL;
117 /* slow fds handling */
119 p = context->lws_lookup;
120 done = &p[context->max_fds];
124 while (p != done && (!*p || (*p && (*p)->desc.sockfd != fd)))
128 lwsl_err("%s: fd %d not found\n", __func__, fd);
133 p = context->lws_lookup;
134 while (p != done && (!*p || (*p && (*p)->desc.sockfd != fd)))
138 lwsl_err("%s: fd %d in lws_lookup again at %d\n", __func__,
139 fd, (int)(p - context->lws_lookup));
146 lws_plat_insert_socket_into_fds(struct lws_context *context, struct lws *wsi)
148 struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
150 if (context->event_loop_ops->io)
151 context->event_loop_ops->io(wsi, LWS_EV_START | LWS_EV_READ);
153 pt->fds[pt->fds_count++].revents = 0;
157 lws_plat_delete_socket_from_fds(struct lws_context *context,
158 struct lws *wsi, int m)
160 struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
162 if (context->event_loop_ops->io)
163 context->event_loop_ops->io(wsi,
164 LWS_EV_STOP | LWS_EV_READ | LWS_EV_WRITE);
170 lws_plat_change_pollfd(struct lws_context *context,
171 struct lws *wsi, struct lws_pollfd *pfd)