libwebsockets
Lightweight C library for HTML5 websockets
Loading...
Searching...
No Matches
Built-in service loop entry

Macros

#define lws_plat_service_tsi   lws_service_tsi

Functions

LWS_VISIBLE LWS_EXTERN int lws_service (struct lws_context *context, int timeout_ms)
LWS_VISIBLE LWS_EXTERN int lws_service_tsi (struct lws_context *context, int timeout_ms, int tsi)
LWS_VISIBLE LWS_EXTERN void lws_cancel_service_pt (struct lws *wsi)
LWS_VISIBLE LWS_EXTERN void lws_cancel_service (struct lws_context *context)
LWS_VISIBLE LWS_EXTERN lws_sockfd_type lws_service_wake_fd (struct lws_context *context, int tsi)
LWS_VISIBLE LWS_EXTERN int lws_service_work_outstanding (struct lws_context *context)
LWS_VISIBLE LWS_EXTERN int lws_service_fd (struct lws_context *context, struct lws_pollfd *pollfd)
LWS_VISIBLE LWS_EXTERN int lws_service_fd_tsi (struct lws_context *context, struct lws_pollfd *pollfd, int tsi)
LWS_VISIBLE LWS_EXTERN int lws_service_adjust_timeout (struct lws_context *context, int timeout_ms, int tsi)
LWS_VISIBLE LWS_EXTERN lws_usec_t lws_service_set_now (struct lws_context *context, int tsi, lws_usec_t now_us, time_t now_wall)
LWS_VISIBLE LWS_EXTERN int lws_handle_POLLOUT_event (struct lws *wsi, struct lws_pollfd *pollfd)

Detailed Description

Built-in service loop entry

If you're not using libev / libuv, these apis are needed to enter the poll() wait in lws and service any connections with pending events.

Macro Definition Documentation

◆ lws_plat_service_tsi

#define lws_plat_service_tsi   lws_service_tsi

#include <lws-service.h>

Definition at line 238 of file lws-service.h.

Function Documentation

◆ lws_service()

LWS_VISIBLE LWS_EXTERN int lws_service ( struct lws_context * context,
int timeout_ms )

#include <lws-service.h>

lws_service() - Service any pending websocket activity

Parameters
contextWebsocket context
timeout_msSet to 0; ignored; for backward compatibility
 This function deals with any pending websocket traffic, for three
 kinds of event.  It handles these events on both server and client
 types of connection the same.

 1) Accept new connections to our context's server

 2) Call the receive callback for incoming frame data received by
     server or client connections.

Since v3.2 internally the timeout wait is ignored, the lws scheduler is smart enough to stay asleep until an event is queued.

Returns >= 0 normally, and -1 when the app should leave its service loop and call lws_context_destroy(): either lws_default_loop_exit() was called (from a signal handler or any callback; that is the recommended way for an app that owns its loop to stop, on the poll loop and on an event library's internal loop alike), or the context is being destroyed. On the default poll loop, -1 after a destroy that was deferred from inside a callback means it has already completed and the context pointer is invalid (set info.pcontext to have it NULLed), which is why calling lws_context_destroy() from a callback is not the recommended way to stop. On an event library's internal loop (eg, LWS_SERVER_OPTION_LIBUV), -1 means the loop has exited because a destroy was started, by lws_default_loop_exit(), by lws' own signal handler on the loop or by lws_context_destroy() from a callback, and the app's call to lws_context_destroy() is what completes it.

References LWS_EXTERN, and LWS_VISIBLE.

◆ lws_service_tsi()

LWS_VISIBLE LWS_EXTERN int lws_service_tsi ( struct lws_context * context,
int timeout_ms,
int tsi )

#include <lws-service.h>

lws_service_tsi() - Service any pending websocket activity

Parameters
contextWebsocket context
timeout_msSet to 0; ignored; for backwards compatibility
tsiThread service index, starting at 0

Same as lws_service(), but for a specific thread service index. Only needed if you are spawning multiple service threads that operate on the same lws_context.

References LWS_EXTERN, and LWS_VISIBLE.

◆ lws_cancel_service_pt()

LWS_VISIBLE LWS_EXTERN void lws_cancel_service_pt ( struct lws * wsi)

#include <lws-service.h>

lws_cancel_service_pt() - Cancel servicing of pending socket activity on one thread

Parameters
wsiCancel service on the thread this wsi is serviced by

Same as lws_cancel_service(), but targets a single service thread, the one the wsi belongs to. You probably want to use lws_cancel_service() instead.

References LWS_EXTERN, and LWS_VISIBLE.

◆ lws_cancel_service()

LWS_VISIBLE LWS_EXTERN void lws_cancel_service ( struct lws_context * context)

#include <lws-service.h>

lws_cancel_service() - Cancel wait for new pending socket activity

Parameters
contextWebsocket context

This function creates an immediate "synchronous interrupt" to the lws poll() wait or event loop. As soon as possible in the serialzed service sequencing, a LWS_CALLBACK_EVENT_WAIT_CANCELLED callback is sent to every protocol on every vhost.

lws_cancel_service() may be called from another thread while the context exists, and its effect will be immediately serialized.

References LWS_EXTERN, and LWS_VISIBLE.

◆ lws_service_wake_fd()

LWS_VISIBLE LWS_EXTERN lws_sockfd_type lws_service_wake_fd ( struct lws_context * context,
int tsi )

#include <lws-service.h>

lws_service_wake_fd() - the fd that wakes a service thread

Parameters
contextWebsocket context
tsithread service index

lws_cancel_service() and lws_cancel_service_pt() wake a service thread by making this fd readable. They are how another thread hands work to the service thread: an async worker's finished file read, a message for smd, and the app's own wakes all arrive this way. lws' own event loops watch it; an embedder running its own loop around lws_service_fd() must poll it for POLLIN as well, and pass it to lws_service_fd_tsi() when it is readable, or that work is never picked up. It is not announced by LWS_CALLBACK_ADD_POLL_FD, since it belongs to no vhost.

Returns LWS_SOCK_INVALID when the thread has no such fd, because the platform or event library wakes it some other way.

References LWS_EXTERN, and LWS_VISIBLE.

◆ lws_service_work_outstanding()

LWS_VISIBLE LWS_EXTERN int lws_service_work_outstanding ( struct lws_context * context)

#include <lws-service.h>

lws_service_work_outstanding() - work out on other threads, not back yet

Parameters
contextWebsocket context

Returns how many jobs lws has handed to its async worker threads (LWS_WITH_ASYNC_QUEUE: the file server's reads, tls accepts) whose result a service thread has not picked up yet: queued, being worked on, or done with the service thread's wake fd (lws_service_wake_fd()) signalled. Always 0 in a build without the queue.

A connection waiting on one has nothing to say at its transport until it is back. An embedder that steps lws deterministically, rather than waiting in poll(), can use it to know there is still something to wait for on the wake fd. It is a snapshot: a job may be handed out or come back as soon as it returns.

References LWS_EXTERN, and LWS_VISIBLE.

◆ lws_service_fd()

LWS_VISIBLE LWS_EXTERN int lws_service_fd ( struct lws_context * context,
struct lws_pollfd * pollfd )

#include <lws-service.h>

lws_service_fd() - Service polled socket with something waiting

Parameters
contextWebsocket context
pollfdThe pollfd entry describing the socket fd and which events happened

This function takes a pollfd that has POLLIN or POLLOUT activity and services it according to the state of the associated struct lws.

The one call deals with all "service" that might happen on a socket including listen accepts, http files as well as websocket protocol.

If a pollfd says it has something, you can just pass it to lws_service_fd() whether it is a socket handled by lws or not. If it sees it is a lws socket, the traffic will be handled and pollfd->revents will be zeroed now.

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.

References LWS_EXTERN, lws_pollfd, and LWS_VISIBLE.

◆ lws_service_fd_tsi()

LWS_VISIBLE LWS_EXTERN int lws_service_fd_tsi ( struct lws_context * context,
struct lws_pollfd * pollfd,
int tsi )

#include <lws-service.h>

lws_service_fd_tsi() - Service polled socket in specific service thread

Parameters
contextWebsocket context
pollfdThe pollfd entry describing the socket fd and which events happened.
tsithread service index

Same as lws_service_fd() but used with multiple service threads

References LWS_EXTERN, lws_pollfd, and LWS_VISIBLE.

◆ lws_service_adjust_timeout()

LWS_VISIBLE LWS_EXTERN int lws_service_adjust_timeout ( struct lws_context * context,
int timeout_ms,
int tsi )

#include <lws-service.h>

lws_service_adjust_timeout() - Check for any connection needing forced service

Parameters
contextWebsocket context
timeout_msThe original poll timeout value. You can just set this to 1 if you don't really have a poll timeout.
tsithread service index

Under some conditions connections may need service even though there is no pending network action on them, this is "forced service". For default poll() and libuv / libev, the library takes care of calling this and dealing with it for you. But for external poll() integration, you need access to the apis.

If anybody needs "forced service", returned timeout is zero. In that case, you can call lws_service_tsi() with a timeout of -1 to only service guys who need forced service.

References LWS_EXTERN, and LWS_VISIBLE.

◆ lws_service_set_now()

LWS_VISIBLE LWS_EXTERN lws_usec_t lws_service_set_now ( struct lws_context * context,
int tsi,
lws_usec_t now_us,
time_t now_wall )

#include <lws-service.h>

lws_service_set_now() - the time is this, for an embedder running its own loop

Parameters
contextlws context
tsithread service index
now_usthe monotonic time, in the same units as lws_now_usecs()
now_wallthe wall time, seconds since 1970

Time is an input to lws' protocol half (READMEs/README.sans-io-split.md, "Time"): what it decides by the clock, the timers it schedules and the times it writes are taken from here once this has been called for the service thread, instead of from the platform's clock, and stay at what was given until the next call. So an embedder that is the event loop (the sansIO harness, a replay of recorded traffic) says what the time is before each thing it hands lws, and the same inputs at the same times give the same outputs.

It also runs the timers due by now_us, as lws' own loops do on waking, and returns the time from now_us until the next one is due, or 0 when none is scheduled.

Time only moves forwards: a now_us earlier than the last is taken as the last. Don't mix it with lws_service() on the same thread: lws' own loops keep the platform's clock.

◆ lws_handle_POLLOUT_event()

LWS_VISIBLE LWS_EXTERN int lws_handle_POLLOUT_event ( struct lws * wsi,
struct lws_pollfd * pollfd )

#include <lws-service.h>

References LWS_EXTERN, lws_pollfd, and LWS_VISIBLE.