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 | /** \defgroup service Built-in service loop entry |
26 | * |
27 | * ##Built-in service loop entry |
28 | * |
29 | * If you're not using libev / libuv, these apis are needed to enter the poll() |
30 | * wait in lws and service any connections with pending events. |
31 | */ |
32 | ///@{ |
33 | |
34 | /** |
35 | * lws_service() - Service any pending websocket activity |
36 | * \param context: Websocket context |
37 | * \param timeout_ms: Set to 0; ignored; for backward compatibility |
38 | * |
39 | * This function deals with any pending websocket traffic, for three |
40 | * kinds of event. It handles these events on both server and client |
41 | * types of connection the same. |
42 | * |
43 | * 1) Accept new connections to our context's server |
44 | * |
45 | * 2) Call the receive callback for incoming frame data received by |
46 | * server or client connections. |
47 | * |
48 | * Since v3.2 internally the timeout wait is ignored, the lws scheduler is |
49 | * smart enough to stay asleep until an event is queued. |
50 | */ |
51 | LWS_VISIBLE LWS_EXTERN int |
52 | lws_service(struct lws_context *context, int timeout_ms); |
53 | |
54 | /** |
55 | * lws_service_tsi() - Service any pending websocket activity |
56 | * |
57 | * \param context: Websocket context |
58 | * \param timeout_ms: Set to 0; ignored; for backwards compatibility |
59 | * \param tsi: Thread service index, starting at 0 |
60 | * |
61 | * Same as lws_service(), but for a specific thread service index. Only needed |
62 | * if you are spawning multiple service threads that operate on the same lws_context. |
63 | */ |
64 | LWS_VISIBLE LWS_EXTERN int |
65 | lws_service_tsi(struct lws_context *context, int timeout_ms, int tsi); |
66 | |
67 | /** |
68 | * lws_cancel_service_pt() - Cancel servicing of pending socket activity |
69 | * on one thread |
70 | * \param wsi: Cancel service on the thread this wsi is serviced by |
71 | * |
72 | * Same as lws_cancel_service(), but targets a single service thread, the one |
73 | * the wsi belongs to. You probably want to use lws_cancel_service() instead. |
74 | */ |
75 | LWS_VISIBLE LWS_EXTERN void |
76 | lws_cancel_service_pt(struct lws *wsi); |
77 | |
78 | /** |
79 | * lws_cancel_service() - Cancel wait for new pending socket activity |
80 | * \param context: Websocket context |
81 | * |
82 | * This function creates an immediate "synchronous interrupt" to the lws poll() |
83 | * wait or event loop. As soon as possible in the serialzed service sequencing, |
84 | * a LWS_CALLBACK_EVENT_WAIT_CANCELLED callback is sent to every protocol on |
85 | * every vhost. |
86 | * |
87 | * lws_cancel_service() may be called from another thread while the context |
88 | * exists, and its effect will be immediately serialized. |
89 | */ |
90 | LWS_VISIBLE LWS_EXTERN void |
91 | lws_cancel_service(struct lws_context *context); |
92 | |
93 | /** |
94 | * lws_service_fd() - Service polled socket with something waiting |
95 | * \param context: Websocket context |
96 | * \param pollfd: The pollfd entry describing the socket fd and which events |
97 | * happened |
98 | * |
99 | * This function takes a pollfd that has POLLIN or POLLOUT activity and |
100 | * services it according to the state of the associated |
101 | * struct lws. |
102 | * |
103 | * The one call deals with all "service" that might happen on a socket |
104 | * including listen accepts, http files as well as websocket protocol. |
105 | * |
106 | * If a pollfd says it has something, you can just pass it to |
107 | * lws_service_fd() whether it is a socket handled by lws or not. |
108 | * If it sees it is a lws socket, the traffic will be handled and |
109 | * pollfd->revents will be zeroed now. |
110 | * |
111 | * If the socket is foreign to lws, it leaves revents alone. So you can |
112 | * see if you should service yourself by checking the pollfd revents |
113 | * after letting lws try to service it. |
114 | * |
115 | * lws before v3.2 allowed pollfd to be NULL, to indicate that background |
116 | * periodic processing should be done. Since v3.2, lws schedules any items |
117 | * that need handling in the future using lws_sul and NULL is no longer valid. |
118 | */ |
119 | LWS_VISIBLE LWS_EXTERN int |
120 | lws_service_fd(struct lws_context *context, struct lws_pollfd *pollfd); |
121 | |
122 | /** |
123 | * lws_service_fd_tsi() - Service polled socket in specific service thread |
124 | * \param context: Websocket context |
125 | * \param pollfd: The pollfd entry describing the socket fd and which events |
126 | * happened. |
127 | * \param tsi: thread service index |
128 | * |
129 | * Same as lws_service_fd() but used with multiple service threads |
130 | */ |
131 | LWS_VISIBLE LWS_EXTERN int |
132 | lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, |
133 | int tsi); |
134 | |
135 | /** |
136 | * lws_service_adjust_timeout() - Check for any connection needing forced service |
137 | * \param context: Websocket context |
138 | * \param timeout_ms: The original poll timeout value. You can just set this |
139 | * to 1 if you don't really have a poll timeout. |
140 | * \param tsi: thread service index |
141 | * |
142 | * Under some conditions connections may need service even though there is no |
143 | * pending network action on them, this is "forced service". For default |
144 | * poll() and libuv / libev, the library takes care of calling this and |
145 | * dealing with it for you. But for external poll() integration, you need |
146 | * access to the apis. |
147 | * |
148 | * If anybody needs "forced service", returned timeout is zero. In that case, |
149 | * you can call lws_service_tsi() with a timeout of -1 to only service |
150 | * guys who need forced service. |
151 | */ |
152 | LWS_VISIBLE LWS_EXTERN int |
153 | lws_service_adjust_timeout(struct lws_context *context, int timeout_ms, int tsi); |
154 | |
155 | /* Backwards compatibility */ |
156 | #define lws_plat_service_tsi lws_service_tsi |
157 | |
158 | LWS_VISIBLE LWS_EXTERN int |
159 | lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd); |
160 | |
161 | ///@} |
162 | |
163 | /*! \defgroup uv libuv helpers |
164 | * |
165 | * ##libuv helpers |
166 | * |
167 | * APIs specific to libuv event loop itegration |
168 | */ |
169 | ///@{ |
170 | #if defined(LWS_WITH_LIBUV) && defined(UV_ERRNO_MAP) |
171 | |
172 | /* |
173 | * Any direct libuv allocations in lws protocol handlers must participate in the |
174 | * lws reference counting scheme. Two apis are provided: |
175 | * |
176 | * - lws_libuv_static_refcount_add(handle, context, tsi) to mark the handle with |
177 | * a pointer to the context and increment the global uv object counter |
178 | * |
179 | * - lws_libuv_static_refcount_del() which should be used as the close callback |
180 | * for your own libuv objects declared in the protocol scope. |
181 | * |
182 | * Using the apis allows lws to detach itself from a libuv loop completely |
183 | * cleanly and at the moment all of its libuv objects have completed close. |
184 | */ |
185 | |
186 | LWS_VISIBLE LWS_EXTERN uv_loop_t * |
187 | lws_uv_getloop(struct lws_context *context, int tsi); |
188 | |
189 | LWS_VISIBLE LWS_EXTERN void |
190 | lws_libuv_static_refcount_add(uv_handle_t *, struct lws_context *context, |
191 | int tsi); |
192 | |
193 | LWS_VISIBLE LWS_EXTERN void |
194 | lws_libuv_static_refcount_del(uv_handle_t *); |
195 | |
196 | #endif /* LWS_WITH_LIBUV */ |
197 | |
198 | #if defined(LWS_PLAT_FREERTOS) |
199 | #define lws_libuv_static_refcount_add(_a, _b, _c) |
200 | #define lws_libuv_static_refcount_del NULL |
201 | #endif |
202 | ///@} |
203 | |