lws_timed_callback_vh_protocol

This commit is contained in:
Andy Green 2017-12-07 10:16:17 +08:00
parent 7d59122b5f
commit db04a40b5c
5 changed files with 149 additions and 1 deletions

View file

@ -1443,6 +1443,13 @@ lws_vhost_destroy1(struct lws_vhost *vh)
}
}
/*
* destroy any pending timed events
*/
while (vh->timed_vh_protocol_list)
lws_timed_callback_remove(vh, vh->timed_vh_protocol_list);
/*
* let the protocols destroy the per-vhost protocol objects
*/

View file

@ -235,6 +235,42 @@ lws_set_timeout(struct lws *wsi, enum pending_timeout reason, int secs)
lws_remove_from_timeout_list(wsi);
}
int
lws_timed_callback_remove(struct lws_vhost *vh, struct lws_timed_vh_protocol *p)
{
lws_start_foreach_llp(struct lws_timed_vh_protocol **, pt,
vh->timed_vh_protocol_list) {
if (*pt == p) {
*pt = p->next;
lws_free(p);
return 0;
}
} lws_end_foreach_llp(pt, next);
return 1;
}
LWS_VISIBLE LWS_EXTERN int
lws_timed_callback_vh_protocol(struct lws_vhost *vh, const struct lws_protocols *prot,
int reason, int secs)
{
struct lws_timed_vh_protocol *p = (struct lws_timed_vh_protocol *)
lws_malloc(sizeof(*p), "timed_vh");
if (!p)
return 1;
p->protocol = prot;
p->reason = reason;
p->time = lws_now_secs() + secs;
p->next = vh->timed_vh_protocol_list;
vh->timed_vh_protocol_list = p;
return 0;
}
static void
lws_remove_child_from_any_parent(struct lws *wsi)
{
@ -1197,6 +1233,29 @@ lws_callback_vhost_protocols(struct lws *wsi, int reason, void *in, int len)
return 0;
}
LWS_VISIBLE LWS_EXTERN int
lws_callback_vhost_protocols_vhost(struct lws_vhost *vh, int reason, void *in,
size_t len)
{
int n;
struct lws *wsi = lws_zalloc(sizeof(*wsi), "fake wsi");
wsi->context = vh->context;
wsi->vhost = vh;
for (n = 0; n < wsi->vhost->count_protocols; n++) {
wsi->protocol = &vh->protocols[n];
if (wsi->protocol->callback(wsi, reason, NULL, in, len)) {
lws_free(wsi);
return 1;
}
}
lws_free(wsi);
return 0;
}
LWS_VISIBLE LWS_EXTERN void
lws_set_fops(struct lws_context *context, const struct lws_plat_file_ops *fops)
{

View file

@ -4426,6 +4426,26 @@ lws_set_timeout(struct lws *wsi, enum pending_timeout reason, int secs);
LWS_VISIBLE LWS_EXTERN void
lws_set_timer(struct lws *wsi, int secs);
/*
* lws_timed_callback_vh_protocol() - calls back a protocol on a vhost after
* the specified delay
*
* \param vh: the vhost to call back
* \param protocol: the protocol to call back
* \param reason: callback reason
* \param secs: how many seconds in the future to do the callback. Set to
* -1 to cancel the timer callback.
*
* Callback the specified protocol with a fake wsi pointing to the specified
* vhost and protocol, with the specified reason, at the specified time in the
* future.
*
* Returns 0 if OK.
*/
LWS_VISIBLE LWS_EXTERN int
lws_timed_callback_vh_protocol(struct lws_vhost *vh,
const struct lws_protocols *prot,
int reason, int secs);
///@}
/*! \defgroup sending-data Sending data
@ -4750,9 +4770,31 @@ lws_callback_all_protocol_vhost_args(struct lws_vhost *vh,
* - Which: connections using this protocol on same VHOST as wsi ONLY
* - When: now
* - What: reason
*
* This is deprecated since v2.5, use lws_callback_vhost_protocols_vhost()
* which takes the pointer to the vhost directly without using or needing the
* wsi.
*/
LWS_VISIBLE LWS_EXTERN int
lws_callback_vhost_protocols(struct lws *wsi, int reason, void *in, int len);
lws_callback_vhost_protocols(struct lws *wsi, int reason, void *in, int len)
LWS_WARN_DEPRECATED;
/**
* lws_callback_vhost_protocols_vhost() - Callback all protocols enabled on a vhost
* with the given reason
*
* \param vh: vhost that will get callbacks
* \param reason: Callback reason index
* \param in: in argument to callback
* \param len: len argument to callback
*
* - Which: connections using this protocol on same VHOST as wsi ONLY
* - When: now
* - What: reason
*/
LWS_VISIBLE LWS_EXTERN int
lws_callback_vhost_protocols_vhost(struct lws_vhost *vh, int reason, void *in,
size_t len);
LWS_VISIBLE LWS_EXTERN int
lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason,

View file

@ -898,6 +898,13 @@ struct http2_settings {
uint32_t s[H2SET_COUNT];
};
struct lws_timed_vh_protocol {
struct lws_timed_vh_protocol *next;
const struct lws_protocols *protocol;
time_t time;
int reason;
};
/*
* virtual host -related context information
* vhostwide SSL context
@ -958,6 +965,7 @@ struct lws_vhost {
#ifndef LWS_NO_EXTENSIONS
const struct lws_extension *extensions;
#endif
struct lws_timed_vh_protocol *timed_vh_protocol_list;
void *user;
int listen_port;
@ -2048,6 +2056,9 @@ lws_b64_selftest(void);
LWS_EXTERN int
lws_service_flag_pending(struct lws_context *context, int tsi);
LWS_EXTERN int
lws_timed_callback_remove(struct lws_vhost *vh, struct lws_timed_vh_protocol *p);
#if defined(_WIN32)
LWS_EXTERN struct lws *
wsi_from_fd(const struct lws_context *context, lws_sockfd_type fd);

View file

@ -1176,6 +1176,35 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd,
lwsl_notice("load: %s\n", s);
}
#endif
/*
* Phase 4: vhost / protocol timer callbacks
*/
wsi = NULL;
lws_start_foreach_ll(struct lws_vhost *, v,
context->vhost_list) {
struct lws_timed_vh_protocol *nx;
if (v->timed_vh_protocol_list) {
lws_start_foreach_ll(struct lws_timed_vh_protocol *,
q, v->timed_vh_protocol_list) {
if (now >= q->time) {
if (!wsi)
wsi = lws_zalloc(sizeof(*wsi), "cbwsi");
wsi->context = context;
wsi->vhost = v;
wsi->protocol = q->protocol;
lwsl_notice("timed cb: vh %s, protocol %s, reason %d\n", v->name, q->protocol->name, q->reason);
q->protocol->callback(wsi, q->reason, NULL, NULL, 0);
nx = q->next;
lws_timed_callback_remove(v, q);
q = nx;
continue; /* we pointed ourselves to the next from the now-deleted guy */
}
} lws_end_foreach_ll(q, next);
}
} lws_end_foreach_ll(v, vhost_next);
if (wsi)
lws_free(wsi);
}
/*