• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22  * IN THE SOFTWARE.
23  */
24 
25 #if !defined(_GNU_SOURCE)
26 #define _GNU_SOURCE
27 #endif
28 #include "private-lib-core.h"
29 
30 struct lws *
wsi_from_fd(const struct lws_context * context,int fd)31 wsi_from_fd(const struct lws_context *context, int fd)
32 {
33 	struct lws **p, **done;
34 
35 	if (!context->max_fds_unrelated_to_ulimit)
36 		return context->lws_lookup[fd - lws_plat_socket_offset()];
37 
38 	/* slow fds handling */
39 
40 	p = context->lws_lookup;
41 	done = &p[context->max_fds];
42 
43 	while (p != done) {
44 		if (*p && (*p)->desc.sockfd == fd)
45 			return *p;
46 		p++;
47 	}
48 
49 	return NULL;
50 }
51 
52 int
insert_wsi(const struct lws_context * context,struct lws * wsi)53 insert_wsi(const struct lws_context *context, struct lws *wsi)
54 {
55 	struct lws **p, **done;
56 
57 	if (!context->max_fds_unrelated_to_ulimit) {
58 		assert(context->lws_lookup[wsi->desc.sockfd -
59 		                           lws_plat_socket_offset()] == 0);
60 
61 		context->lws_lookup[wsi->desc.sockfd - \
62 				  lws_plat_socket_offset()] = wsi;
63 
64 		return 0;
65 	}
66 
67 	/* slow fds handling */
68 
69 	p = context->lws_lookup;
70 	done = &p[context->max_fds];
71 
72 #if defined(_DEBUG)
73 
74 	/* confirm it doesn't already exist */
75 
76 	while (p != done && *p != wsi)
77 		p++;
78 
79 	assert(p == done);
80 	p = context->lws_lookup;
81 
82 	/* confirm fd doesn't already exist */
83 
84 	while (p != done && (!*p || (*p)->desc.sockfd != wsi->desc.sockfd))
85 		p++;
86 
87 	if (p != done) {
88 		lwsl_err("%s: wsi %p already says it has fd %d\n",
89 				__func__, *p, wsi->desc.sockfd);
90 		assert(0);
91 	}
92 	p = context->lws_lookup;
93 #endif
94 
95 	/* find an empty slot */
96 
97 	while (p != done && *p)
98 		p++;
99 
100 	if (p == done) {
101 		lwsl_err("%s: reached max fds\n", __func__);
102 		return 1;
103 	}
104 
105 	*p = wsi;
106 
107 	return 0;
108 }
109 
110 void
delete_from_fd(const struct lws_context * context,int fd)111 delete_from_fd(const struct lws_context *context, int fd)
112 {
113 
114 	struct lws **p, **done;
115 
116 	if (!context->max_fds_unrelated_to_ulimit) {
117 		context->lws_lookup[fd - lws_plat_socket_offset()] = NULL;
118 
119 		return;
120 	}
121 
122 	/* slow fds handling */
123 
124 	p = context->lws_lookup;
125 	done = &p[context->max_fds];
126 
127 	/* find the match */
128 
129 	while (p != done && (!*p || (*p)->desc.sockfd != fd))
130 		p++;
131 
132 	if (p == done)
133 		lwsl_err("%s: fd %d not found\n", __func__, fd);
134 	else
135 		*p = NULL;
136 
137 #if defined(_DEBUG)
138 	p = context->lws_lookup;
139 	while (p != done && (!*p || (*p)->desc.sockfd != fd))
140 		p++;
141 
142 	if (p != done) {
143 		lwsl_err("%s: fd %d in lws_lookup again at %d\n", __func__,
144 				fd, (int)(p - context->lws_lookup));
145 		assert(0);
146 	}
147 #endif
148 }
149 
150 void
lws_plat_insert_socket_into_fds(struct lws_context * context,struct lws * wsi)151 lws_plat_insert_socket_into_fds(struct lws_context *context, struct lws *wsi)
152 {
153 	struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
154 
155 	if (context->event_loop_ops->io)
156 		context->event_loop_ops->io(wsi, LWS_EV_START | LWS_EV_READ);
157 
158 	pt->fds[pt->fds_count++].revents = 0;
159 }
160 
161 void
lws_plat_delete_socket_from_fds(struct lws_context * context,struct lws * wsi,int m)162 lws_plat_delete_socket_from_fds(struct lws_context *context,
163 						struct lws *wsi, int m)
164 {
165 	struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
166 
167 	if (context->event_loop_ops->io)
168 		context->event_loop_ops->io(wsi,
169 				LWS_EV_STOP | LWS_EV_READ | LWS_EV_WRITE);
170 
171 	pt->fds_count--;
172 }
173 
174 int
lws_plat_change_pollfd(struct lws_context * context,struct lws * wsi,struct lws_pollfd * pfd)175 lws_plat_change_pollfd(struct lws_context *context,
176 		      struct lws *wsi, struct lws_pollfd *pfd)
177 {
178 	return 0;
179 }
180