Commit 64f0dc1a authored by Wandenberg Peixoto's avatar Wandenberg Peixoto

unifying types: ngx_http_push_stream_worker_subscriber_t and...

unifying types: ngx_http_push_stream_worker_subscriber_t and ngx_http_push_stream_subscriber_t to reduce memory consumption
parent 486d49fa
...@@ -31,6 +31,11 @@ ...@@ -31,6 +31,11 @@
#include <ngx_http.h> #include <ngx_http.h>
#include <nginx.h> #include <nginx.h>
typedef struct {
ngx_queue_t queue;
void *value;
} ngx_http_push_stream_queue_elem_t;
// template queue // template queue
typedef struct { typedef struct {
ngx_queue_t queue; // this MUST be first ngx_queue_t queue; // this MUST be first
...@@ -95,19 +100,13 @@ typedef struct { ...@@ -95,19 +100,13 @@ typedef struct {
} ngx_http_push_stream_msg_t; } ngx_http_push_stream_msg_t;
typedef struct ngx_http_push_stream_subscriber_cleanup_s ngx_http_push_stream_subscriber_cleanup_t; typedef struct ngx_http_push_stream_subscriber_cleanup_s ngx_http_push_stream_subscriber_cleanup_t;
typedef struct ngx_http_push_stream_subscriber_s ngx_http_push_stream_subscriber_t;
// subscriber request queue
typedef struct {
ngx_queue_t queue; // this MUST be first
ngx_http_request_t *request;
ngx_flag_t longpolling;
} ngx_http_push_stream_subscriber_t;
typedef struct { typedef struct {
ngx_queue_t queue; ngx_queue_t queue;
pid_t pid; pid_t pid;
ngx_int_t slot; ngx_int_t slot;
ngx_http_push_stream_subscriber_t subscriber_sentinel; ngx_http_push_stream_queue_elem_t subscribers_sentinel;
} ngx_http_push_stream_pid_queue_t; } ngx_http_push_stream_pid_queue_t;
// our typecast-friendly rbtree node (channel) // our typecast-friendly rbtree node (channel)
...@@ -140,16 +139,17 @@ typedef struct { ...@@ -140,16 +139,17 @@ typedef struct {
ngx_queue_t queue; ngx_queue_t queue;
ngx_http_push_stream_subscriber_t *subscriber; ngx_http_push_stream_subscriber_t *subscriber;
ngx_http_push_stream_channel_t *channel; ngx_http_push_stream_channel_t *channel;
ngx_http_push_stream_queue_elem_t *channel_subscriber_element_ref;
} ngx_http_push_stream_subscription_t; } ngx_http_push_stream_subscription_t;
typedef struct { struct ngx_http_push_stream_subscriber_s {
ngx_queue_t queue; // this MUST be first
ngx_http_request_t *request; ngx_http_request_t *request;
ngx_http_push_stream_subscription_t subscriptions_sentinel; ngx_http_push_stream_subscription_t subscriptions_sentinel;
ngx_http_push_stream_subscriber_cleanup_t *clndata; ngx_http_push_stream_subscriber_cleanup_t *clndata;
ngx_pid_t worker_subscribed_pid; ngx_pid_t worker_subscribed_pid;
ngx_flag_t longpolling; ngx_flag_t longpolling;
} ngx_http_push_stream_worker_subscriber_t; ngx_http_push_stream_queue_elem_t *worker_subscriber_element_ref;
};
typedef struct { typedef struct {
ngx_event_t *disconnect_timer; ngx_event_t *disconnect_timer;
...@@ -159,7 +159,7 @@ typedef struct { ...@@ -159,7 +159,7 @@ typedef struct {
// cleaning supplies // cleaning supplies
struct ngx_http_push_stream_subscriber_cleanup_s { struct ngx_http_push_stream_subscriber_cleanup_s {
ngx_http_push_stream_worker_subscriber_t *worker_subscriber; ngx_http_push_stream_subscriber_t *worker_subscriber;
}; };
// messages to worker processes // messages to worker processes
...@@ -168,12 +168,12 @@ typedef struct { ...@@ -168,12 +168,12 @@ typedef struct {
ngx_http_push_stream_msg_t *msg; // ->shared memory ngx_http_push_stream_msg_t *msg; // ->shared memory
ngx_pid_t pid; ngx_pid_t pid;
ngx_http_push_stream_channel_t *channel; // ->shared memory ngx_http_push_stream_channel_t *channel; // ->shared memory
ngx_http_push_stream_subscriber_t *subscriber_sentinel; // ->a worker's local pool ngx_http_push_stream_queue_elem_t *subscribers_sentinel; // ->a worker's local pool
} ngx_http_push_stream_worker_msg_t; } ngx_http_push_stream_worker_msg_t;
typedef struct { typedef struct {
ngx_http_push_stream_worker_msg_t *messages_queue; ngx_http_push_stream_worker_msg_t *messages_queue;
ngx_http_push_stream_worker_subscriber_t *worker_subscribers_sentinel; ngx_http_push_stream_queue_elem_t *subscribers_sentinel;
ngx_uint_t subscribers; // # of subscribers in the worker ngx_uint_t subscribers; // # of subscribers in the worker
time_t startup; time_t startup;
pid_t pid; pid_t pid;
......
...@@ -56,7 +56,7 @@ static ngx_int_t ngx_http_push_stream_alert_worker(ngx_pid_t pid, ngx_int ...@@ -56,7 +56,7 @@ static ngx_int_t ngx_http_push_stream_alert_worker(ngx_pid_t pid, ngx_int
#define ngx_http_push_stream_alert_worker_census_subscribers(pid, slot, log) ngx_http_push_stream_alert_worker(pid, slot, log, NGX_CMD_HTTP_PUSH_STREAM_CENSUS_SUBSCRIBERS); #define ngx_http_push_stream_alert_worker_census_subscribers(pid, slot, log) ngx_http_push_stream_alert_worker(pid, slot, log, NGX_CMD_HTTP_PUSH_STREAM_CENSUS_SUBSCRIBERS);
#define ngx_http_push_stream_alert_worker_delete_channel(pid, slot, log) ngx_http_push_stream_alert_worker(pid, slot, log, NGX_CMD_HTTP_PUSH_STREAM_DELETE_CHANNEL); #define ngx_http_push_stream_alert_worker_delete_channel(pid, slot, log) ngx_http_push_stream_alert_worker(pid, slot, log, NGX_CMD_HTTP_PUSH_STREAM_DELETE_CHANNEL);
static ngx_int_t ngx_http_push_stream_send_worker_message(ngx_http_push_stream_channel_t *channel, ngx_http_push_stream_subscriber_t *subscriber_sentinel, ngx_pid_t pid, ngx_int_t worker_slot, ngx_http_push_stream_msg_t *msg, ngx_log_t *log); static ngx_int_t ngx_http_push_stream_send_worker_message(ngx_http_push_stream_channel_t *channel, ngx_http_push_stream_queue_elem_t *subscribers_sentinel, ngx_pid_t pid, ngx_int_t worker_slot, ngx_http_push_stream_msg_t *msg, ngx_log_t *log);
static ngx_int_t ngx_http_push_stream_init_ipc(ngx_cycle_t *cycle, ngx_int_t workers); static ngx_int_t ngx_http_push_stream_init_ipc(ngx_cycle_t *cycle, ngx_int_t workers);
static void ngx_http_push_stream_ipc_exit_worker(ngx_cycle_t *cycle); static void ngx_http_push_stream_ipc_exit_worker(ngx_cycle_t *cycle);
...@@ -67,6 +67,6 @@ static void ngx_http_push_stream_channel_handler(ngx_event_t *ev); ...@@ -67,6 +67,6 @@ static void ngx_http_push_stream_channel_handler(ngx_event_t *ev);
static ngx_inline void ngx_http_push_stream_process_worker_message(void); static ngx_inline void ngx_http_push_stream_process_worker_message(void);
static ngx_inline void ngx_http_push_stream_census_worker_subscribers(void); static ngx_inline void ngx_http_push_stream_census_worker_subscribers(void);
static ngx_int_t ngx_http_push_stream_respond_to_subscribers(ngx_http_push_stream_channel_t *channel, ngx_http_push_stream_subscriber_t *sentinel, ngx_http_push_stream_msg_t *msg); static ngx_int_t ngx_http_push_stream_respond_to_subscribers(ngx_http_push_stream_channel_t *channel, ngx_http_push_stream_queue_elem_t *subscribers_sentinel, ngx_http_push_stream_msg_t *msg);
#endif /* NGX_HTTP_PUSH_STREAM_MODULE_IPC_H_ */ #endif /* NGX_HTTP_PUSH_STREAM_MODULE_IPC_H_ */
...@@ -241,7 +241,7 @@ static void ngx_http_push_stream_timer_reset(ngx_msec_t timer_in ...@@ -241,7 +241,7 @@ static void ngx_http_push_stream_timer_reset(ngx_msec_t timer_in
#define ngx_http_push_stream_memory_cleanup_timer_set() ngx_http_push_stream_timer_set(ngx_http_push_stream_module_main_conf->memory_cleanup_interval, &ngx_http_push_stream_memory_cleanup_event, ngx_http_push_stream_memory_cleanup_timer_wake_handler, 1); #define ngx_http_push_stream_memory_cleanup_timer_set() ngx_http_push_stream_timer_set(ngx_http_push_stream_module_main_conf->memory_cleanup_interval, &ngx_http_push_stream_memory_cleanup_event, ngx_http_push_stream_memory_cleanup_timer_wake_handler, 1);
#define ngx_http_push_stream_buffer_cleanup_timer_set(pslcf) ngx_http_push_stream_timer_set(ngx_http_push_stream_module_main_conf->buffer_cleanup_interval, &ngx_http_push_stream_buffer_cleanup_event, ngx_http_push_stream_buffer_timer_wake_handler, pslcf->store_messages); #define ngx_http_push_stream_buffer_cleanup_timer_set(pslcf) ngx_http_push_stream_timer_set(ngx_http_push_stream_module_main_conf->buffer_cleanup_interval, &ngx_http_push_stream_buffer_cleanup_event, ngx_http_push_stream_buffer_timer_wake_handler, pslcf->store_messages);
static void ngx_http_push_stream_worker_subscriber_cleanup_locked(ngx_http_push_stream_worker_subscriber_t *worker_subscriber); static void ngx_http_push_stream_worker_subscriber_cleanup_locked(ngx_http_push_stream_subscriber_t *worker_subscriber);
static ngx_str_t * ngx_http_push_stream_create_str(ngx_pool_t *pool, uint len); static ngx_str_t * ngx_http_push_stream_create_str(ngx_pool_t *pool, uint len);
static void ngx_http_push_stream_mark_message_to_delete_locked(ngx_http_push_stream_msg_t *msg); static void ngx_http_push_stream_mark_message_to_delete_locked(ngx_http_push_stream_msg_t *msg);
......
This diff is collapsed.
...@@ -737,7 +737,7 @@ ngx_http_push_stream_init_shm_zone(ngx_shm_zone_t *shm_zone, void *data) ...@@ -737,7 +737,7 @@ ngx_http_push_stream_init_shm_zone(ngx_shm_zone_t *shm_zone, void *data)
d->ipc[i].startup = 0; d->ipc[i].startup = 0;
d->ipc[i].subscribers = 0; d->ipc[i].subscribers = 0;
d->ipc[i].messages_queue = NULL; d->ipc[i].messages_queue = NULL;
d->ipc[i].worker_subscribers_sentinel = NULL; d->ipc[i].subscribers_sentinel = NULL;
} }
d->startup = ngx_time(); d->startup = ngx_time();
......
...@@ -59,10 +59,10 @@ ngx_http_push_stream_delete_unrecoverable_channels(ngx_http_push_stream_shm_data ...@@ -59,10 +59,10 @@ ngx_http_push_stream_delete_unrecoverable_channels(ngx_http_push_stream_shm_data
{ {
ngx_http_push_stream_channel_t *channel; ngx_http_push_stream_channel_t *channel;
ngx_http_push_stream_pid_queue_t *cur_worker; ngx_http_push_stream_pid_queue_t *cur_worker;
ngx_http_push_stream_subscriber_t *cur; ngx_http_push_stream_queue_elem_t *cur;
ngx_http_push_stream_worker_data_t *workers_data = ((ngx_http_push_stream_shm_data_t *) ngx_http_push_stream_shm_zone->data)->ipc; ngx_http_push_stream_worker_data_t *workers_data = ((ngx_http_push_stream_shm_data_t *) ngx_http_push_stream_shm_zone->data)->ipc;
ngx_http_push_stream_worker_data_t *thisworker_data = workers_data + ngx_process_slot; ngx_http_push_stream_worker_data_t *thisworker_data = workers_data + ngx_process_slot;
ngx_http_push_stream_worker_subscriber_t *worker_subscriber; ngx_http_push_stream_queue_elem_t *cur_subscriber;
ngx_http_push_stream_subscription_t *cur_subscription; ngx_http_push_stream_subscription_t *cur_subscription;
channel = (ngx_http_push_stream_channel_t *) node; channel = (ngx_http_push_stream_channel_t *) node;
...@@ -87,13 +87,15 @@ ngx_http_push_stream_delete_unrecoverable_channels(ngx_http_push_stream_shm_data ...@@ -87,13 +87,15 @@ ngx_http_push_stream_delete_unrecoverable_channels(ngx_http_push_stream_shm_data
if (cur_worker->slot == ngx_process_slot) { if (cur_worker->slot == ngx_process_slot) {
// to each subscriber of this channel in this worker // to each subscriber of this channel in this worker
while(!ngx_queue_empty(&cur_worker->subscriber_sentinel.queue)) { while(!ngx_queue_empty(&cur_worker->subscribers_sentinel.queue)) {
cur = (ngx_http_push_stream_subscriber_t *) ngx_queue_next(&cur_worker->subscriber_sentinel.queue); cur = (ngx_http_push_stream_queue_elem_t *) ngx_queue_next(&cur_worker->subscribers_sentinel.queue);
ngx_http_push_stream_subscriber_t *subscriber = (ngx_http_push_stream_subscriber_t *) cur->value;
// find the subscriber subscriptions on the worker // find the subscriber subscriptions on the worker
worker_subscriber = thisworker_data->worker_subscribers_sentinel; cur_subscriber = thisworker_data->subscribers_sentinel;
while ((worker_subscriber = (ngx_http_push_stream_worker_subscriber_t *) ngx_queue_next(&worker_subscriber->queue)) != thisworker_data->worker_subscribers_sentinel) { while ((cur_subscriber = (ngx_http_push_stream_queue_elem_t *) ngx_queue_next(&cur_subscriber->queue)) != thisworker_data->subscribers_sentinel) {
if (worker_subscriber->request == cur->request) { ngx_http_push_stream_subscriber_t *worker_subscriber = (ngx_http_push_stream_subscriber_t *) cur_subscriber->value;
if (worker_subscriber->request == subscriber->request) {
// find the subscription for the channel being deleted // find the subscription for the channel being deleted
cur_subscription = &worker_subscriber->subscriptions_sentinel; cur_subscription = &worker_subscriber->subscriptions_sentinel;
...@@ -108,7 +110,7 @@ ngx_http_push_stream_delete_unrecoverable_channels(ngx_http_push_stream_shm_data ...@@ -108,7 +110,7 @@ ngx_http_push_stream_delete_unrecoverable_channels(ngx_http_push_stream_shm_data
ngx_queue_remove(&cur->queue); ngx_queue_remove(&cur->queue);
ngx_shmtx_unlock(&shpool->mutex); ngx_shmtx_unlock(&shpool->mutex);
ngx_http_push_stream_send_response_message(cur->request, channel, channel->channel_deleted_message); ngx_http_push_stream_send_response_message(subscriber->request, channel, channel->channel_deleted_message);
break; break;
} }
...@@ -638,19 +640,17 @@ ngx_http_push_stream_free_memory_of_expired_messages_and_channels(ngx_flag_t for ...@@ -638,19 +640,17 @@ ngx_http_push_stream_free_memory_of_expired_messages_and_channels(ngx_flag_t for
{ {
ngx_slab_pool_t *shpool = (ngx_slab_pool_t *) ngx_http_push_stream_shm_zone->shm.addr; ngx_slab_pool_t *shpool = (ngx_slab_pool_t *) ngx_http_push_stream_shm_zone->shm.addr;
ngx_http_push_stream_shm_data_t *data = (ngx_http_push_stream_shm_data_t *) ngx_http_push_stream_shm_zone->data; ngx_http_push_stream_shm_data_t *data = (ngx_http_push_stream_shm_data_t *) ngx_http_push_stream_shm_zone->data;
ngx_http_push_stream_msg_t *sentinel, *cur, *next; ngx_http_push_stream_msg_t *cur, *prev;
sentinel = &data->messages_to_delete;
ngx_shmtx_lock(&shpool->mutex); ngx_shmtx_lock(&shpool->mutex);
cur = (ngx_http_push_stream_msg_t *)ngx_queue_next(&sentinel->queue); cur = &data->messages_to_delete;
while (cur != sentinel) { while ((cur = (ngx_http_push_stream_msg_t *)ngx_queue_next(&cur->queue)) != &data->messages_to_delete) {
next = (ngx_http_push_stream_msg_t *)ngx_queue_next(&cur->queue);
if ((ngx_time() > cur->expires) || force) { if ((ngx_time() > cur->expires) || force) {
prev = (ngx_http_push_stream_msg_t *)ngx_queue_prev(&cur->queue);
ngx_queue_remove(&cur->queue); ngx_queue_remove(&cur->queue);
ngx_http_push_stream_free_message_memory_locked(shpool, cur); ngx_http_push_stream_free_message_memory_locked(shpool, cur);
cur = prev;
} }
cur = next;
} }
ngx_http_push_stream_free_memory_of_expired_channels_locked(&data->channels_to_delete, shpool, data->channels_to_delete.root, force); ngx_http_push_stream_free_memory_of_expired_channels_locked(&data->channels_to_delete, shpool, data->channels_to_delete.root, force);
ngx_shmtx_unlock(&shpool->mutex); ngx_shmtx_unlock(&shpool->mutex);
...@@ -665,7 +665,7 @@ ngx_http_push_stream_free_message_memory_locked(ngx_slab_pool_t *shpool, ngx_htt ...@@ -665,7 +665,7 @@ ngx_http_push_stream_free_message_memory_locked(ngx_slab_pool_t *shpool, ngx_htt
u_int i; u_int i;
if (msg->formatted_messages != NULL) { if (msg->formatted_messages != NULL) {
for(i = 0; i < ngx_http_push_stream_module_main_conf->qtd_templates; i++) { for (i = 0; i < ngx_http_push_stream_module_main_conf->qtd_templates; i++) {
ngx_str_t *formmated = (msg->formatted_messages + i); ngx_str_t *formmated = (msg->formatted_messages + i);
if ((formmated != NULL) && (formmated->data != NULL)) { if ((formmated != NULL) && (formmated->data != NULL)) {
ngx_slab_free_locked(shpool, formmated->data); ngx_slab_free_locked(shpool, formmated->data);
...@@ -860,7 +860,7 @@ ngx_http_push_stream_format_message(ngx_http_push_stream_channel_t *channel, ngx ...@@ -860,7 +860,7 @@ ngx_http_push_stream_format_message(ngx_http_push_stream_channel_t *channel, ngx
static void static void
ngx_http_push_stream_worker_subscriber_cleanup_locked(ngx_http_push_stream_worker_subscriber_t *worker_subscriber) ngx_http_push_stream_worker_subscriber_cleanup_locked(ngx_http_push_stream_subscriber_t *worker_subscriber)
{ {
ngx_http_push_stream_subscription_t *cur, *sentinel; ngx_http_push_stream_subscription_t *cur, *sentinel;
ngx_http_push_stream_shm_data_t *data = (ngx_http_push_stream_shm_data_t *) ngx_http_push_stream_shm_zone->data; ngx_http_push_stream_shm_data_t *data = (ngx_http_push_stream_shm_data_t *) ngx_http_push_stream_shm_zone->data;
...@@ -880,12 +880,12 @@ ngx_http_push_stream_worker_subscriber_cleanup_locked(ngx_http_push_stream_worke ...@@ -880,12 +880,12 @@ ngx_http_push_stream_worker_subscriber_cleanup_locked(ngx_http_push_stream_worke
while ((cur = (ngx_http_push_stream_subscription_t *) ngx_queue_next(&sentinel->queue)) != sentinel) { while ((cur = (ngx_http_push_stream_subscription_t *) ngx_queue_next(&sentinel->queue)) != sentinel) {
NGX_HTTP_PUSH_STREAM_DECREMENT_COUNTER(cur->channel->subscribers); NGX_HTTP_PUSH_STREAM_DECREMENT_COUNTER(cur->channel->subscribers);
ngx_queue_remove(&cur->subscriber->queue); ngx_queue_remove(&cur->channel_subscriber_element_ref->queue);
ngx_queue_remove(&cur->queue); ngx_queue_remove(&cur->queue);
} }
ngx_queue_init(&sentinel->queue); ngx_queue_init(&sentinel->queue);
ngx_queue_remove(&worker_subscriber->queue); ngx_queue_remove(&worker_subscriber->worker_subscriber_element_ref->queue);
ngx_queue_init(&worker_subscriber->queue); ngx_queue_init(&worker_subscriber->worker_subscriber_element_ref->queue);
worker_subscriber->clndata->worker_subscriber = NULL; worker_subscriber->clndata->worker_subscriber = NULL;
NGX_HTTP_PUSH_STREAM_DECREMENT_COUNTER(data->subscribers); NGX_HTTP_PUSH_STREAM_DECREMENT_COUNTER(data->subscribers);
NGX_HTTP_PUSH_STREAM_DECREMENT_COUNTER((data->ipc + ngx_process_slot)->subscribers); NGX_HTTP_PUSH_STREAM_DECREMENT_COUNTER((data->ipc + ngx_process_slot)->subscribers);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment