1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

smp: lws_timed_callback_vh_protocol: request sets handler tsi and other fixes

This commit is contained in:
Andy Green 2018-11-15 16:33:54 +08:00
parent 8750582fc6
commit b2b58b5b14
6 changed files with 69 additions and 18 deletions

View file

@ -1369,7 +1369,7 @@ __lws_vhost_destroy2(struct lws_vhost *vh)
*/
while (vh->timed_vh_protocol_list)
lws_timed_callback_remove(vh, 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

@ -120,8 +120,10 @@ lws_vhost_bind_wsi(struct lws_vhost *vh, struct lws *wsi)
{
if (wsi->vhost == vh)
return;
lws_context_lock(vh->context, __func__); /* ---------- context { */
wsi->vhost = vh;
vh->count_bound_wsi++;
lws_context_unlock(vh->context); /* } context ---------- */
lwsl_info("%s: vh %s: count_bound_wsi %d\n",
__func__, vh->name, vh->count_bound_wsi);
assert(wsi->vhost->count_bound_wsi > 0);
@ -487,8 +489,10 @@ lws_set_timeout(struct lws *wsi, enum pending_timeout reason, int secs)
lws_pt_unlock(pt);
}
/* requires context + vh lock */
int
lws_timed_callback_remove(struct lws_vhost *vh, struct lws_timed_vh_protocol *p)
__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) {
@ -503,9 +507,30 @@ lws_timed_callback_remove(struct lws_vhost *vh, struct lws_timed_vh_protocol *p)
return 1;
}
int
lws_pthread_self_to_tsi(struct lws_context *context)
{
#if LWS_MAX_SMP > 1
pthread_t ps = pthread_self();
struct lws_context_per_thread *pt = &context->pt[0];
int n;
for (n = 0; n < context->count_threads; n++) {
if (pthread_equal(ps, pt->self))
return n;
pt++;
}
return -1;
#else
return 0;
#endif
}
LWS_VISIBLE LWS_EXTERN int
lws_timed_callback_vh_protocol(struct lws_vhost *vh, const struct lws_protocols *prot,
int reason, int secs)
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");
@ -513,12 +538,22 @@ lws_timed_callback_vh_protocol(struct lws_vhost *vh, const struct lws_protocols
if (!p)
return 1;
p->tsi_req = lws_pthread_self_to_tsi(vh->context);
if (p->tsi_req < 0) /* not called from a service thread --> tsi 0 */
p->tsi_req = 0;
lws_context_lock(vh->context, __func__); /* context ----------------- */
p->protocol = prot;
p->reason = reason;
p->time = lws_now_secs() + secs;
p->next = vh->timed_vh_protocol_list;
lws_vhost_lock(vh); /* vhost ---------------------------------------- */
p->next = vh->timed_vh_protocol_list;
vh->timed_vh_protocol_list = p;
lws_vhost_unlock(vh); /* -------------------------------------- vhost */
lws_context_unlock(vh->context); /* ------------------------- context */
return 0;
}

View file

@ -351,6 +351,7 @@ struct lws_context_per_thread {
#if LWS_MAX_SMP > 1
pthread_mutex_t lock_stats;
struct lws_mutex_refcount mr;
pthread_t self;
#endif
struct lws_context *context;
@ -445,6 +446,7 @@ struct lws_timed_vh_protocol {
struct lws_vhost *vhost; /* only used for pending processing */
time_t time;
int reason;
int tsi_req;
};
/*
@ -1097,7 +1099,7 @@ 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);
__lws_timed_callback_remove(struct lws_vhost *vh, struct lws_timed_vh_protocol *p);
LWS_EXTERN int LWS_WARN_UNUSED_RESULT
__insert_wsi_socket_into_fds(struct lws_context *context, struct lws *wsi);
@ -1437,6 +1439,10 @@ LWS_EXTERN int
lws_plat_service(struct lws_context *context, int timeout_ms);
LWS_EXTERN LWS_VISIBLE int
_lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi);
LWS_EXTERN int
lws_pthread_self_to_tsi(struct lws_context *context);
LWS_EXTERN int
lws_plat_init(struct lws_context *context,
const struct lws_context_creation_info *info);

View file

@ -658,7 +658,7 @@ lws_service_periodic_checks(struct lws_context *context,
our_fd = pollfd->fd;
/*
* Phase 1: check every wsi on the timeout check list
* Phase 1: check every wsi on our pt's timeout check list
*/
lws_pt_lock(pt, __func__);
@ -792,7 +792,7 @@ lws_service_periodic_checks(struct lws_context *context,
lws_start_foreach_ll_safe(struct lws_timed_vh_protocol *,
q, v->timed_vh_protocol_list, next) {
if (now >= q->time)
if (now >= q->time && q->tsi_req == tsi)
n++;
} lws_end_foreach_ll_safe(q);
}
@ -839,6 +839,8 @@ lws_service_periodic_checks(struct lws_context *context,
if (v->timed_vh_protocol_list) {
lws_vhost_lock(v); /* vhost ------------------------- */
lws_start_foreach_ll_safe(struct lws_timed_vh_protocol *,
q, v->timed_vh_protocol_list, next) {
@ -846,7 +848,7 @@ lws_service_periodic_checks(struct lws_context *context,
if (m == n)
break;
if (now >= q->time) {
if (now >= q->time && q->tsi_req == tsi) {
/*
* tmr is an allocated array.
@ -858,10 +860,12 @@ lws_service_periodic_checks(struct lws_context *context,
/* take the timer out now we took
* responsibility */
lws_timed_callback_remove(v, q);
__lws_timed_callback_remove(v, q);
}
} lws_end_foreach_ll_safe(q);
lws_vhost_unlock(v); /* ----------------------- vhost */
}
} lws_end_foreach_ll(v, vhost_next);
@ -1085,6 +1089,9 @@ lws_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
int n;
pt->inside_service = 1;
#if LWS_MAX_SMP > 1
pt->self = pthread_self();
#endif
if (context->event_loop_ops->run_pt) {
/* we are configured for an event loop */

View file

@ -697,6 +697,7 @@ lws_http_serve(struct lws *wsi, char *uri, const char *origin,
p = (unsigned char *)args.p;
}
*p = '\0';
n = lws_serve_http_file(wsi, path, mimetype, (char *)start,
lws_ptr_diff(p, start));
@ -2299,8 +2300,8 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type,
/* Only add cache control if its not specified by any other_headers. */
if (!other_headers ||
(!strstr(other_headers, "cache-control") &&
!strstr(other_headers, "Cache-Control"))) {
(!strstr(other_headers, "cache-control") &&
!strstr(other_headers, "Cache-Control"))) {
if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CACHE_CONTROL,
(unsigned char *)cc, cclen, &p, end))
return -1;

View file

@ -79,8 +79,8 @@ rops_handle_POLLIN_listen(struct lws_context_per_thread *pt, struct lws *wsi,
* block the connect queue for other legit peers.
*/
accept_fd = accept((int)pollfd->fd,
(struct sockaddr *)&cli_addr, &clilen);
accept_fd = accept((int)pollfd->fd,
(struct sockaddr *)&cli_addr, &clilen);
lws_latency(context, wsi, "listener accept",
(int)accept_fd, accept_fd != LWS_SOCK_INVALID);
if (accept_fd == LWS_SOCK_INVALID) {
@ -88,9 +88,8 @@ rops_handle_POLLIN_listen(struct lws_context_per_thread *pt, struct lws *wsi,
LWS_ERRNO == LWS_EWOULDBLOCK) {
break;
}
lwsl_err("ERROR on accept: %s\n",
strerror(LWS_ERRNO));
break;
lwsl_err("accept: %s\n", strerror(LWS_ERRNO));
return LWS_HPI_RET_HANDLED;
}
lws_plat_set_socket_options(wsi->vhost, accept_fd, 0);
@ -130,9 +129,12 @@ rops_handle_POLLIN_listen(struct lws_context_per_thread *pt, struct lws *wsi,
fd.sockfd = accept_fd;
cwsi = lws_adopt_descriptor_vhost(wsi->vhost, opts, fd,
NULL, NULL);
if (!cwsi)
if (!cwsi) {
lwsl_err("%s: lws_adopt_descriptor_vhost failed\n",
__func__);
/* already closed cleanly as necessary */
return LWS_HPI_RET_WSI_ALREADY_DIED;
}
if (lws_server_socket_service_ssl(cwsi, accept_fd)) {
lws_close_free_wsi(cwsi, LWS_CLOSE_STATUS_NOSTATUS,