cscg24-guacamole

CSCG 2024 Challenge 'Guacamole Mashup'
git clone https://git.sinitax.com/sinitax/cscg24-guacamole
Log | Files | Refs | sfeed.txt

lws-sequencer.h (9540B)


      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 * lws_sequencer is intended to help implement sequences that:
     25 *
     26 *  - outlive a single connection lifetime,
     27 *  - are not associated with a particular protocol,
     28 *  - are not associated with a particular vhost,
     29 *  - must receive and issue events inside the event loop
     30 *
     31 * lws_sequencer-s are bound to a pt (per-thread) which for the default case of
     32 * one service thread is the same as binding to an lws_context.
     33 */
     34/*
     35 * retry backoff table... retry n happens after .retry_ms_table[n] ms, with
     36 * the last entry used if n is greater than the number of entries.
     37 *
     38 * The first .conceal_count retries are concealed, but after that the failures
     39 * are reported.
     40 */
     41
     42typedef enum {
     43	LWSSEQ_CREATED,		/* sequencer created */
     44	LWSSEQ_DESTROYED,	/* sequencer destroyed */
     45	LWSSEQ_TIMED_OUT,	/* sequencer timeout */
     46	LWSSEQ_HEARTBEAT,	/* 1Hz callback */
     47
     48	LWSSEQ_WSI_CONNECTED,	/* wsi we bound to us has connected */
     49	LWSSEQ_WSI_CONN_FAIL,	/* wsi we bound to us has failed to connect */
     50	LWSSEQ_WSI_CONN_CLOSE,	/* wsi we bound to us has closed */
     51
     52
     53	LWSSEQ_SS_STATE_BASE,	/* secure streams owned by a sequencer provide
     54				 * automatic messages about state changes on
     55				 * the sequencer, passing the oridinal in the
     56				 * event argument field.  The message index is
     57				 * LWSSEQ_SS_STATE_BASE + the enum from
     58				 * lws_ss_constate_t */
     59
     60	LWSSEQ_USER_BASE = 100	/* define your events from here */
     61} lws_seq_events_t;
     62
     63typedef enum lws_seq_cb_return {
     64	LWSSEQ_RET_CONTINUE,
     65	LWSSEQ_RET_DESTROY
     66} lws_seq_cb_return_t;
     67
     68/*
     69 * handler for this sequencer.  Return 0 if OK else nonzero to destroy the
     70 * sequencer.  LWSSEQ_DESTROYED will be called back to the handler so it can
     71 * close / destroy any private assets associated with the sequence.
     72 *
     73 * The callback may return either LWSSEQ_RET_CONTINUE for the sequencer to
     74 * resume or LWSSEQ_RET_DESTROY to indicate the sequence is finished.
     75 *
     76 * Event indexes consist of some generic ones but mainly user-defined ones
     77 * starting from LWSSEQ_USER_BASE.
     78 */
     79typedef lws_seq_cb_return_t (*lws_seq_event_cb)(struct lws_sequencer *seq,
     80			     void *user, int event, void *data, void *aux);
     81
     82typedef struct lws_seq_info {
     83	struct lws_context		*context;   /* lws_context for seq */
     84	int				tsi;	    /* thread service idx */
     85	size_t				user_size;  /* size of user alloc */
     86	void				**puser;    /* place ptr to user */
     87	lws_seq_event_cb		cb;	    /* seq callback */
     88	const char			*name;	    /* seq name */
     89	const lws_retry_bo_t		*retry;	    /* retry policy */
     90	uint8_t				wakesuspend:1; /* important enough to
     91						     * wake system */
     92} lws_seq_info_t;
     93
     94/**
     95 * lws_seq_create() - create and bind sequencer to a pt
     96 *
     97 * \param info:	information about sequencer to create
     98 *
     99 * This binds an abstract sequencer to a per-thread (by default, the single
    100 * event loop of an lws_context).  After the event loop starts, the sequencer
    101 * will receive an LWSSEQ_CREATED event on its callback from the event loop
    102 * context, where it can begin its sequence flow.
    103 *
    104 * Lws itself will only call the callback subsequently with LWSSEQ_DESTROYED
    105 * when the sequencer is being destroyed.
    106 *
    107 * pt locking is used to protect the related data structures.
    108 */
    109LWS_VISIBLE LWS_EXTERN struct lws_sequencer *
    110lws_seq_create(lws_seq_info_t *info);
    111
    112/**
    113 * lws_seq_destroy() - destroy the sequencer
    114 *
    115 * \param seq: pointer to the the opaque sequencer pointer returned by
    116 *	       lws_seq_create()
    117 *
    118 * This proceeds to destroy the sequencer, calling LWSSEQ_DESTROYED and then
    119 * freeing the sequencer object itself.  The pointed-to seq pointer will be
    120 * set to NULL.
    121 */
    122LWS_VISIBLE LWS_EXTERN void
    123lws_seq_destroy(struct lws_sequencer **seq);
    124
    125/**
    126 * lws_seq_queue_event() - queue an event on the given sequencer
    127 *
    128 * \param seq: the opaque sequencer pointer returned by lws_seq_create()
    129 * \param e: the event index to queue
    130 * \param data: associated opaque (to lws) data to provide the callback
    131 * \param aux: second opaque data to provide the callback
    132 *
    133 * This queues the event on a given sequencer.  Queued events are delivered one
    134 * per sequencer each subsequent time around the event loop, so the cb is called
    135 * from the event loop thread context.
    136 *
    137 * Notice that because the events are delivered in order from the event loop,
    138 * the scope of objects pointed to by \p data or \p aux may exceed the lifetime
    139 * of the thing containing the pointed-to data.  So it's usually better to pass
    140 * values here.
    141 */
    142LWS_VISIBLE LWS_EXTERN int
    143lws_seq_queue_event(struct lws_sequencer *seq, lws_seq_events_t e, void *data,
    144			  void *aux);
    145
    146/**
    147 * lws_seq_check_wsi() - check if wsi still extant
    148 *
    149 * \param seq: the sequencer interested in the wsi
    150 * \param wsi: the wsi we want to confirm hasn't closed yet
    151 *
    152 * Check if wsi still extant, by peeking in the message queue for a
    153 * LWSSEQ_WSI_CONN_CLOSE message about wsi.  (Doesn't need to do the same for
    154 * CONN_FAIL since that will never have produced any messages prior to that).
    155 *
    156 * Use this to avoid trying to perform operations on wsi that have already
    157 * closed but we didn't get to that message yet.
    158 *
    159 * Returns 0 if not closed yet or 1 if it has closed but we didn't process the
    160 * close message yet.
    161 */
    162LWS_VISIBLE LWS_EXTERN int
    163lws_seq_check_wsi(struct lws_sequencer *seq, struct lws *wsi);
    164
    165#define LWSSEQTO_NONE 0
    166
    167/**
    168 * lws_seq_timeout_us() - set a timeout by which the sequence must have
    169 *				completed by a different event or inform the
    170 *				sequencer
    171 *
    172 * \param seq: The sequencer to set the timeout on
    173 * \param us: How many us in the future to fire the timeout
    174 *		LWS_SET_TIMER_USEC_CANCEL = cancel any existing timeout
    175 *
    176 * This api allows the sequencer to ask to be informed if it has not completed
    177 * or disabled its timeout after secs seconds.  Lws will send a LWSSEQ_TIMED_OUT
    178 * event to the sequencer if the timeout expires.
    179 *
    180 * Typically the sequencer sets the timeout when starting a step, then waits to
    181 * hear a queued event informing it the step completed or failed.  The timeout
    182 * provides a way to deal with the case the step neither completed nor failed
    183 * within the timeout period.
    184 *
    185 * Lws wsi timeouts are not really suitable for this since they are focused on
    186 * short-term protocol timeout protection and may be set and reset many times
    187 * in one transaction.  Wsi timeouts also enforce closure of the wsi when they
    188 * trigger, sequencer timeouts have no side effect except to queue the
    189 * LWSSEQ_TIMED_OUT message and leave it to the sequencer to decide how to
    190 * react appropriately.
    191 */
    192LWS_VISIBLE LWS_EXTERN int
    193lws_seq_timeout_us(struct lws_sequencer *seq, lws_usec_t us);
    194
    195/**
    196 * lws_seq_from_user(): get the lws_seq_t pointer from the user ptr
    197 *
    198 * \param u: the sequencer user allocation returned by lws_seq_create() or
    199 *	     provided in the sequencer callback
    200 *
    201 * This gets the lws_seq_t * from the sequencer user allocation pointer.
    202 * Actually these are allocated at the same time in one step, with the user
    203 * allocation immediately after the lws_seq_t, so lws can compute where
    204 * the lws_seq_t is from having the user allocation pointer.  Since the
    205 * size of the lws_seq_t is unknown to user code, this helper does it for
    206 * you.
    207 */
    208LWS_VISIBLE LWS_EXTERN struct lws_sequencer *
    209lws_seq_from_user(void *u);
    210
    211/**
    212 * lws_seq_us_since_creation(): elapsed seconds since sequencer created
    213 *
    214 * \param seq: pointer to the lws_seq_t
    215 *
    216 * Returns the number of us elapsed since the lws_seq_t was
    217 * created.  This is useful to calculate sequencer timeouts for the current
    218 * step considering a global sequencer lifetime limit.
    219 */
    220LWS_VISIBLE LWS_EXTERN lws_usec_t
    221lws_seq_us_since_creation(struct lws_sequencer *seq);
    222
    223/**
    224 * lws_seq_name(): get the name of this sequencer
    225 *
    226 * \param seq: pointer to the lws_seq_t
    227 *
    228 * Returns the name given when the sequencer was created.  This is useful to
    229 * annotate logging when then are multiple sequencers in play.
    230 */
    231LWS_VISIBLE LWS_EXTERN const char *
    232lws_seq_name(struct lws_sequencer *seq);
    233
    234/**
    235 * lws_seq_get_context(): get the lws_context sequencer was created on
    236 *
    237 * \param seq: pointer to the lws_seq_t
    238 *
    239 * Returns the lws_context.  Saves you having to store it if you have a seq
    240 * pointer handy.
    241 */
    242LWS_VISIBLE LWS_EXTERN struct lws_context *
    243lws_seq_get_context(struct lws_sequencer *seq);