1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

lws_sul: make it clear NULL no longer valid in lws_service_fd

This commit is contained in:
Andy Green 2019-09-12 11:14:14 +01:00
parent 0250eac9a0
commit 0f983d0aca
2 changed files with 68 additions and 2 deletions

62
READMEs/README.lws_sul.md Normal file
View file

@ -0,0 +1,62 @@
# `lws_sul` scheduler api
Since v3.2 lws no longer requires periodic checking for timeouts and
other events. A new system was refactored in where future events are
scheduled on to a single, unified, sorted linked-list in time order,
with everything at us resolution.
This makes it very cheap to know when the next scheduled event is
coming and restrict the poll wait to match, or for event libraries
set a timer to wake at the earliest event when returning to the
event loop.
Everything that was checked periodically was converted to use `lws_sul`
and schedule its own later event. The end result is when lws is idle,
it will stay asleep in the poll wait until a network event or the next
scheduled `lws_sul` event happens, which is optimal for power.
# Side effect for older code
If your older code uses `lws_service_fd()`, it used to be necessary
to call this with a NULL pollfd periodically to indicate you wanted
to let the background checks happen. `lws_sul` eliminates the whole
concept of periodic checking and NULL is no longer a valid pollfd
value for this and related apis.
# Using `lws_sul` in user code
See `minimal-http-client-multi` for an example of using the `lws_sul`
scheduler from your own code; it uses it to spread out connection
attempts so they are staggered in time. You must create an
`lws_sorted_usec_list_t` object somewhere, eg, in you own existing object.
```
static lws_sorted_usec_list_t sul_stagger;
```
Create your own callback for the event... the argument points to the sul object
used when the callback was scheduled. You can use pointer arithmetic to translate
that to your own struct when the `lws_sorted_usec_list_t` was a member of the
same struct.
```
static void
stagger_cb(lws_sorted_usec_list_t *sul)
{
...
}
```
When you want to schedule the callback, use `lws_sul_schedule()`... this will call
it 10ms in the future
```
lws_sul_schedule(context, 0, &sul_stagger, stagger_cb, 10 * LWS_US_PER_MS);
```
In the case you destroy your object and need to cancel the scheduled callback, use
```
lws_sul_schedule(context, 0, &sul_stagger, NULL, LWS_SET_TIMER_USEC_CANCEL);
```

View file

@ -44,7 +44,7 @@
* 2) Call the receive callback for incoming frame data received by
* server or client connections.
*
* Since v4.0 internally the timeout wait is ignored, the lws scheduler is
* Since v3.2 internally the timeout wait is ignored, the lws scheduler is
* smart enough to stay asleep until an event is queued.
*/
LWS_VISIBLE LWS_EXTERN int
@ -93,7 +93,7 @@ lws_cancel_service(struct lws_context *context);
* lws_service_fd() - Service polled socket with something waiting
* \param context: Websocket context
* \param pollfd: The pollfd entry describing the socket fd and which events
* happened, or NULL to tell lws to do only timeout servicing.
* happened
*
* This function takes a pollfd that has POLLIN or POLLOUT activity and
* services it according to the state of the associated
@ -110,6 +110,10 @@ lws_cancel_service(struct lws_context *context);
* If the socket is foreign to lws, it leaves revents alone. So you can
* see if you should service yourself by checking the pollfd revents
* after letting lws try to service it.
*
* lws before v3.2 allowed pollfd to be NULL, to indicate that background
* periodic processing should be done. Since v3.2, lws schedules any items
* that need handling in the future using lws_sul and NULL is no longer valid.
*/
LWS_VISIBLE LWS_EXTERN int
lws_service_fd(struct lws_context *context, struct lws_pollfd *pollfd);