static ngx_http_push_stream_channel_t * ngx_http_push_stream_find_channel(ngx_str_t *id, ngx_log_t *log, ngx_http_push_stream_main_conf_t *mcf) { ngx_http_push_stream_shm_data_t *data = mcf->shm_data; ngx_http_push_stream_channel_t *channel = NULL; if (id == NULL) { ngx_log_error(NGX_LOG_ERR, log, 0, "push stream module: tried to find a channel with a null id"); return NULL; } ngx_shmtx_lock(&data->channels_queue_mutex); channel = ngx_http_push_stream_find_channel_on_tree(id, log, &data->tree); ngx_shmtx_unlock(&data->channels_queue_mutex); return channel; }
static ngx_http_push_stream_channel_t * ngx_http_push_stream_find_channel(ngx_str_t *id, ngx_log_t *log) { 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_channel_t *channel = NULL; if (id == NULL) { ngx_log_error(NGX_LOG_ERR, log, 0, "push stream module: tried to find a channel with a null id"); return NULL; } channel = ngx_http_push_stream_find_channel_on_tree(id, log, &data->tree); if ((channel == NULL) || channel->deleted) { return NULL; } return channel; }
// find a channel by id. if channel not found, make one, insert it, and return that. static ngx_http_push_stream_channel_t * ngx_http_push_stream_get_channel(ngx_str_t *id, ngx_log_t *log, ngx_http_push_stream_main_conf_t *mcf) { ngx_http_push_stream_shm_data_t *data = mcf->shm_data; ngx_http_push_stream_channel_t *channel; ngx_slab_pool_t *shpool = mcf->shpool; ngx_flag_t is_wildcard_channel = 0; if (id == NULL) { ngx_log_error(NGX_LOG_ERR, log, 0, "push stream module: tried to create a channel with a null id"); return NULL; } ngx_shmtx_lock(&data->channels_queue_mutex); // check again to see if any other worker didn't create the channel channel = ngx_http_push_stream_find_channel_on_tree(id, log, &data->tree); if (channel != NULL) { // we found our channel ngx_shmtx_unlock(&data->channels_queue_mutex); return channel; } if ((mcf->wildcard_channel_prefix.len > 0) && (ngx_strncmp(id->data, mcf->wildcard_channel_prefix.data, mcf->wildcard_channel_prefix.len) == 0)) { is_wildcard_channel = 1; } if (((!is_wildcard_channel) && (mcf->max_number_of_channels != NGX_CONF_UNSET_UINT) && (mcf->max_number_of_channels == data->channels)) || ((is_wildcard_channel) && (mcf->max_number_of_wildcard_channels != NGX_CONF_UNSET_UINT) && (mcf->max_number_of_wildcard_channels == data->wildcard_channels))) { ngx_shmtx_unlock(&data->channels_queue_mutex); ngx_log_error(NGX_LOG_ERR, log, 0, "push stream module: number of channels were exceeded"); return NGX_HTTP_PUSH_STREAM_NUMBER_OF_CHANNELS_EXCEEDED; } if ((channel = ngx_slab_alloc(shpool, sizeof(ngx_http_push_stream_channel_t))) == NULL) { ngx_shmtx_unlock(&data->channels_queue_mutex); ngx_log_error(NGX_LOG_ERR, log, 0, "push stream module: unable to allocate memory for new channel"); return NULL; } if ((channel->id.data = ngx_slab_alloc(shpool, id->len + 1)) == NULL) { ngx_slab_free(shpool, channel); ngx_shmtx_unlock(&data->channels_queue_mutex); ngx_log_error(NGX_LOG_ERR, log, 0, "push stream module: unable to allocate memory for new channel id"); return NULL; } channel->id.len = id->len; ngx_memcpy(channel->id.data, id->data, channel->id.len); channel->id.data[channel->id.len] = '\0'; channel->wildcard = is_wildcard_channel; channel->channel_deleted_message = NULL; channel->last_message_id = 0; channel->last_message_time = 0; channel->last_message_tag = 0; channel->stored_messages = 0; channel->subscribers = 0; channel->deleted = 0; channel->expires = ngx_time() + mcf->channel_inactivity_time; ngx_queue_init(&channel->message_queue); ngx_queue_init(&channel->workers_with_subscribers); channel->node.key = ngx_crc32_short(channel->id.data, channel->id.len); ngx_rbtree_insert(&data->tree, &channel->node); ngx_queue_insert_tail(&data->channels_queue, &channel->queue); (channel->wildcard) ? data->wildcard_channels++ : data->channels++; channel->mutex = &data->channels_mutex[data->mutex_round_robin++ % 9]; ngx_shmtx_unlock(&data->channels_queue_mutex); return channel; }