mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
sequencer: add second aux message arg
Since the messages are queued and then read in order from the event loop thread, it's not generally safe to pass pointers to argument structs, since there's no guarantee the lifetime of the thing sending the message lasted until the sequencer read the message. This puts pressure on the single void * argument-passed-as-value... this patch adds a second void * argument-passed-as-value so it's more possible to put what's needed directly in the argument. It's also possible to alloc the argument on the heap and have the sequencer callback free it after it has read it.
This commit is contained in:
parent
20923db2b5
commit
1d954d52a3
7 changed files with 63 additions and 30 deletions
|
@ -70,7 +70,8 @@ typedef struct lws_sequencer lws_sequencer_t; /* opaque */
|
|||
* starting from LWSSEQ_USER_BASE.
|
||||
*/
|
||||
typedef lws_seq_cb_return_t (*lws_seq_event_cb)(struct lws_sequencer *seq,
|
||||
void *user, int event, void *data);
|
||||
void *user, int event, void *data, void *aux);
|
||||
|
||||
typedef struct lws_seq_info {
|
||||
struct lws_context *context; /* lws_context for seq */
|
||||
int tsi; /* thread service idx */
|
||||
|
@ -113,18 +114,25 @@ LWS_VISIBLE LWS_EXTERN void
|
|||
lws_sequencer_destroy(lws_sequencer_t **seq);
|
||||
|
||||
/**
|
||||
* lws_sequencer_event() - queue an event on the given sequencer
|
||||
* lws_sequencer_queue_event() - queue an event on the given sequencer
|
||||
*
|
||||
* \param seq: the opaque sequencer pointer returned by lws_sequencer_create()
|
||||
* \param e: the event index to queue
|
||||
* \param data: associated opaque (to lws) data to provide the callback
|
||||
* \param aux: second opaque data to provide the callback
|
||||
*
|
||||
* This queues the event on a given sequencer. Queued events are delivered one
|
||||
* per sequencer each subsequent time around the event loop, so the cb is called
|
||||
* from the event loop thread context.
|
||||
*
|
||||
* Notice that because the events are delivered in order from the event loop,
|
||||
* the scope of objects pointed to by \p data or \p aux may exceed the lifetime
|
||||
* of the thing containing the pointed-to data. So it's usually better to pass
|
||||
* values here.
|
||||
*/
|
||||
LWS_VISIBLE LWS_EXTERN int
|
||||
lws_sequencer_event(lws_sequencer_t *seq, lws_seq_events_t e, void *data);
|
||||
lws_sequencer_queue_event(lws_sequencer_t *seq, lws_seq_events_t e, void *data,
|
||||
void *aux);
|
||||
|
||||
/**
|
||||
* lws_sequencer_check_wsi() - check if wsi still extant
|
||||
|
@ -210,3 +218,14 @@ lws_sequencer_secs_since_creation(lws_sequencer_t *seq);
|
|||
*/
|
||||
LWS_VISIBLE LWS_EXTERN const char *
|
||||
lws_sequencer_name(lws_sequencer_t *seq);
|
||||
|
||||
/**
|
||||
* lws_sequencer_get_context(): get the lws_context sequencer was created on
|
||||
*
|
||||
* \param seq: pointer to the lws_sequencer_t
|
||||
*
|
||||
* Returns the lws_context. Saves you having to store it if you have a seq
|
||||
* pointer handy.
|
||||
*/
|
||||
LWS_VISIBLE LWS_EXTERN struct lws_context *
|
||||
lws_sequencer_get_context(lws_sequencer_t *seq);
|
||||
|
|
|
@ -88,7 +88,7 @@ unit_test_result_cb(const void *cb_user, int disposition)
|
|||
return -1;
|
||||
}
|
||||
|
||||
lws_sequencer_event(s->unit_test_seq, r, NULL);
|
||||
lws_sequencer_queue_event(s->unit_test_seq, r, NULL, NULL);
|
||||
|
||||
((struct lws_seq_test_sequencer *)s)->instance = NULL;
|
||||
|
||||
|
@ -103,7 +103,8 @@ unit_test_result_cb(const void *cb_user, int disposition)
|
|||
*/
|
||||
|
||||
static lws_seq_cb_return_t
|
||||
test_sequencer_cb(struct lws_sequencer *seq, void *user, int event, void *data)
|
||||
test_sequencer_cb(struct lws_sequencer *seq, void *user, int event, void *data,
|
||||
void *aux)
|
||||
{
|
||||
struct lws_seq_test_sequencer *s =
|
||||
(struct lws_seq_test_sequencer *)user;
|
||||
|
|
|
@ -97,7 +97,8 @@ callback_abs_client_raw_skt(struct lws *wsi, enum lws_callback_reasons reason,
|
|||
* our lifecycle events
|
||||
*/
|
||||
|
||||
lws_sequencer_event(wsi->seq, LWSSEQ_WSI_CONNECTED, wsi);
|
||||
lws_sequencer_queue_event(wsi->seq, LWSSEQ_WSI_CONNECTED,
|
||||
wsi, NULL);
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
|
||||
|
@ -111,8 +112,8 @@ callback_abs_client_raw_skt(struct lws *wsi, enum lws_callback_reasons reason,
|
|||
* our lifecycle events
|
||||
*/
|
||||
|
||||
lws_sequencer_event(wsi->seq, LWSSEQ_WSI_CONN_FAIL,
|
||||
wsi);
|
||||
lws_sequencer_queue_event(wsi->seq, LWSSEQ_WSI_CONN_FAIL,
|
||||
wsi, NULL);
|
||||
|
||||
goto close_path;
|
||||
|
||||
|
@ -127,8 +128,8 @@ callback_abs_client_raw_skt(struct lws *wsi, enum lws_callback_reasons reason,
|
|||
* our lifecycle events
|
||||
*/
|
||||
|
||||
lws_sequencer_event(wsi->seq, LWSSEQ_WSI_CONN_CLOSE,
|
||||
wsi);
|
||||
lws_sequencer_queue_event(wsi->seq, LWSSEQ_WSI_CONN_CLOSE,
|
||||
wsi, NULL);
|
||||
|
||||
close_path:
|
||||
lwsl_debug("LWS_CALLBACK_RAW_CLOSE\n");
|
||||
|
|
|
@ -78,7 +78,8 @@ lws_unit_test_packet_dispose(abs_unit_test_priv_t *priv,
|
|||
|
||||
priv->disposition = disp;
|
||||
|
||||
lws_sequencer_event(priv->seq, UTSEQ_MSG_DISPOSITION_KNOWN, NULL);
|
||||
lws_sequencer_queue_event(priv->seq, UTSEQ_MSG_DISPOSITION_KNOWN,
|
||||
NULL, NULL);
|
||||
|
||||
return disp;
|
||||
}
|
||||
|
@ -125,7 +126,7 @@ process_expect(abs_unit_test_priv_t *priv)
|
|||
|
||||
static lws_seq_cb_return_t
|
||||
unit_test_sequencer_cb(struct lws_sequencer *seq, void *user, int event,
|
||||
void *data)
|
||||
void *data, void *aux)
|
||||
{
|
||||
seq_priv_t *s = (seq_priv_t *)user;
|
||||
abs_unit_test_priv_t *priv = (abs_unit_test_priv_t *)s->ai->ati;
|
||||
|
@ -280,7 +281,7 @@ lws_atcut_close(lws_abs_transport_inst_t *ati)
|
|||
|
||||
lwsl_notice("%s\n", __func__);
|
||||
|
||||
lws_sequencer_event(priv->seq, UTSEQ_MSG_CLOSING, NULL);
|
||||
lws_sequencer_queue_event(priv->seq, UTSEQ_MSG_CLOSING, NULL, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -332,7 +333,7 @@ lws_atcut_tx(lws_abs_transport_inst_t *ati, uint8_t *buf, size_t len)
|
|||
|
||||
priv->expect++;
|
||||
|
||||
lws_sequencer_event(priv->seq, UTSEQ_MSG_POST_TX_KICK, NULL);
|
||||
lws_sequencer_queue_event(priv->seq, UTSEQ_MSG_POST_TX_KICK, NULL, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -382,7 +383,7 @@ lws_atcut_client_conn(const lws_abs_t *abs)
|
|||
lwsl_notice("%s: %s: test '%s': start\n", __func__, abs->ap->name,
|
||||
priv->current_test->name);
|
||||
|
||||
lws_sequencer_event(priv->seq, UTSEQ_MSG_CONNECTING, NULL);
|
||||
lws_sequencer_queue_event(priv->seq, UTSEQ_MSG_CONNECTING, NULL, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -401,7 +402,7 @@ lws_atcut_ask_for_writeable(lws_abs_transport_inst_t *ati)
|
|||
* until we have returned to the event loop, just like a real
|
||||
* callback_on_writable()
|
||||
*/
|
||||
lws_sequencer_event(priv->seq, UTSEQ_MSG_WRITEABLE, NULL);
|
||||
lws_sequencer_queue_event(priv->seq, UTSEQ_MSG_WRITEABLE, NULL, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ typedef struct lws_seq_event {
|
|||
struct lws_dll2 seq_event_list;
|
||||
|
||||
void *data;
|
||||
void *aux;
|
||||
lws_seq_events_t e;
|
||||
} lws_seq_event_t;
|
||||
|
||||
|
@ -81,7 +82,7 @@ lws_sequencer_create(lws_seq_info_t *i)
|
|||
|
||||
/* try to queue the creation cb */
|
||||
|
||||
if (lws_sequencer_event(seq, LWSSEQ_CREATED, NULL)) {
|
||||
if (lws_sequencer_queue_event(seq, LWSSEQ_CREATED, NULL, NULL)) {
|
||||
lws_dll2_remove(&seq->seq_list);
|
||||
lws_free(seq);
|
||||
|
||||
|
@ -111,7 +112,7 @@ lws_sequencer_destroy(lws_sequencer_t **pseq)
|
|||
/* defeat another thread racing to add events while we are destroying */
|
||||
seq->going_down = 1;
|
||||
|
||||
seq->cb(seq, (void *)&seq[1], LWSSEQ_DESTROYED, NULL);
|
||||
seq->cb(seq, (void *)&seq[1], LWSSEQ_DESTROYED, NULL, NULL);
|
||||
|
||||
lws_pt_lock(seq->pt, __func__); /* -------------------------- pt { */
|
||||
|
||||
|
@ -141,7 +142,8 @@ lws_sequencer_destroy_all_on_pt(struct lws_context_per_thread *pt)
|
|||
}
|
||||
|
||||
int
|
||||
lws_sequencer_event(lws_sequencer_t *seq, lws_seq_events_t e, void *data)
|
||||
lws_sequencer_queue_event(lws_sequencer_t *seq, lws_seq_events_t e, void *data,
|
||||
void *aux)
|
||||
{
|
||||
lws_seq_event_t *seqe;
|
||||
|
||||
|
@ -154,6 +156,7 @@ lws_sequencer_event(lws_sequencer_t *seq, lws_seq_events_t e, void *data)
|
|||
|
||||
seqe->e = e;
|
||||
seqe->data = data;
|
||||
seqe->aux = aux;
|
||||
|
||||
// lwsl_notice("%s: seq %s: event %d\n", __func__, seq->name, e);
|
||||
|
||||
|
@ -233,7 +236,7 @@ lws_sequencer_next_event(struct lws_dll2 *d, void *user)
|
|||
dh = lws_dll2_get_head(&seq->seq_event_owner);
|
||||
seqe = lws_container_of(dh, lws_seq_event_t, seq_event_list);
|
||||
|
||||
n = seq->cb(seq, (void *)&seq[1], seqe->e, seqe->data);
|
||||
n = seq->cb(seq, (void *)&seq[1], seqe->e, seqe->data, seqe->aux);
|
||||
|
||||
/* ... have to lock here though, because we will change the list */
|
||||
|
||||
|
@ -342,7 +345,8 @@ lws_sequencer_timeout_check(struct lws_context_per_thread *pt, time_t now)
|
|||
/* seq has timed out... remove him from timeout list */
|
||||
lws_sequencer_timeout(s, 0);
|
||||
/* queue the message to inform the sequencer */
|
||||
lws_sequencer_event(s, LWSSEQ_TIMED_OUT, NULL);
|
||||
lws_sequencer_queue_event(s, LWSSEQ_TIMED_OUT,
|
||||
NULL, NULL);
|
||||
} else
|
||||
/*
|
||||
* No need to look further if we met one later than now:
|
||||
|
@ -360,7 +364,7 @@ lws_sequencer_timeout_check(struct lws_context_per_thread *pt, time_t now)
|
|||
seq_list);
|
||||
|
||||
/* queue the message to inform the sequencer */
|
||||
lws_sequencer_event(s, LWSSEQ_HEARTBEAT, NULL);
|
||||
lws_sequencer_queue_event(s, LWSSEQ_HEARTBEAT, NULL, NULL);
|
||||
|
||||
} lws_end_foreach_dll_safe(p, tp);
|
||||
|
||||
|
@ -388,3 +392,10 @@ lws_sequencer_secs_since_creation(lws_sequencer_t *seq)
|
|||
|
||||
return now - seq->time_created;
|
||||
}
|
||||
|
||||
struct lws_context *
|
||||
lws_sequencer_get_context(lws_sequencer_t *seq)
|
||||
{
|
||||
return seq->pt->context;
|
||||
}
|
||||
|
||||
|
|
|
@ -143,7 +143,7 @@ int lws_context_init_client_ssl(const struct lws_context_creation_info *info,
|
|||
private_key_filepath))
|
||||
return 1;
|
||||
|
||||
lwsl_notice("created client ssl context for %s\n", vhost->name);
|
||||
lwsl_info("created client ssl context for %s\n", vhost->name);
|
||||
|
||||
/*
|
||||
* give him a fake wsi with context set, so he can use
|
||||
|
|
|
@ -35,7 +35,6 @@ enum {
|
|||
*/
|
||||
|
||||
struct myseq {
|
||||
struct lws_context *context;
|
||||
struct lws_vhost *vhost;
|
||||
struct lws *cwsi; /* client wsi for current step if any */
|
||||
|
||||
|
@ -163,7 +162,8 @@ notify:
|
|||
|
||||
lws_set_wsi_user(wsi, NULL);
|
||||
s->cwsi = NULL;
|
||||
lws_sequencer_event(lws_sequencer_from_user(s), seq_msg, NULL);
|
||||
lws_sequencer_queue_event(lws_sequencer_from_user(s), seq_msg,
|
||||
NULL, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -185,7 +185,7 @@ sequencer_start_client(struct myseq *s)
|
|||
lws_strncpy(uri, url_paths[s->state], sizeof(uri));
|
||||
|
||||
memset(&i, 0, sizeof i);
|
||||
i.context = s->context;
|
||||
i.context = lws_sequencer_get_context(lws_sequencer_from_user(s));
|
||||
|
||||
if (lws_parse_uri(uri, &prot, &i.address, &i.port, &path1)) {
|
||||
lwsl_err("%s: uri error %s\n", __func__, uri);
|
||||
|
@ -217,8 +217,8 @@ sequencer_start_client(struct myseq *s)
|
|||
|
||||
/* we couldn't even get started with the client connection */
|
||||
|
||||
lws_sequencer_event(lws_sequencer_from_user(s),
|
||||
SEQ_MSG_CLIENT_FAILED, NULL);
|
||||
lws_sequencer_queue_event(lws_sequencer_from_user(s),
|
||||
SEQ_MSG_CLIENT_FAILED, NULL, NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -238,7 +238,8 @@ sequencer_start_client(struct myseq *s)
|
|||
*/
|
||||
|
||||
static lws_seq_cb_return_t
|
||||
sequencer_cb(struct lws_sequencer *seq, void *user, int event, void *data)
|
||||
sequencer_cb(struct lws_sequencer *seq, void *user, int event,
|
||||
void *data, void *aux)
|
||||
{
|
||||
struct myseq *s = (struct myseq *)user;
|
||||
|
||||
|
@ -382,7 +383,6 @@ main(int argc, const char **argv)
|
|||
lwsl_err("%s: unable to create sequencer\n", __func__);
|
||||
goto bail1;
|
||||
}
|
||||
s->context = context;
|
||||
s->vhost = vh;
|
||||
|
||||
/* the usual lws event loop */
|
||||
|
|
Loading…
Add table
Reference in a new issue