diff --git a/include/libwebsockets/lws-sequencer.h b/include/libwebsockets/lws-sequencer.h index 923ce2254..db84325fc 100644 --- a/include/libwebsockets/lws-sequencer.h +++ b/include/libwebsockets/lws-sequencer.h @@ -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); diff --git a/lib/abstract/test-sequencer.c b/lib/abstract/test-sequencer.c index 92387054c..89eefb3fd 100644 --- a/lib/abstract/test-sequencer.c +++ b/lib/abstract/test-sequencer.c @@ -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; diff --git a/lib/abstract/transports/raw-skt.c b/lib/abstract/transports/raw-skt.c index f51d73fa1..683efad98 100644 --- a/lib/abstract/transports/raw-skt.c +++ b/lib/abstract/transports/raw-skt.c @@ -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"); diff --git a/lib/abstract/transports/unit-test.c b/lib/abstract/transports/unit-test.c index c8a8860f5..3be03ed33 100644 --- a/lib/abstract/transports/unit-test.c +++ b/lib/abstract/transports/unit-test.c @@ -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; } diff --git a/lib/core-net/sequencer.c b/lib/core-net/sequencer.c index 713783c3c..1312d50ed 100644 --- a/lib/core-net/sequencer.c +++ b/lib/core-net/sequencer.c @@ -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; +} + diff --git a/lib/tls/tls-client.c b/lib/tls/tls-client.c index 99349c865..45911bd24 100644 --- a/lib/tls/tls-client.c +++ b/lib/tls/tls-client.c @@ -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 diff --git a/minimal-examples/api-tests/api-test-lws_sequencer/main.c b/minimal-examples/api-tests/api-test-lws_sequencer/main.c index af058f667..7924c0c5d 100644 --- a/minimal-examples/api-tests/api-test-lws_sequencer/main.c +++ b/minimal-examples/api-tests/api-test-lws_sequencer/main.c @@ -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 */