Esempio n. 1
0
void ngx_rpc_notify_free(ngx_rpc_notify_t* notify)
{
   // free task

   // free lock
    ngx_slab_free(notify->shpool, notify);
}
Esempio n. 2
0
ngx_rpc_notify_t *ngx_rpc_notify_create(ngx_slab_pool_t *shpool)
{

    ngx_rpc_notify_t *notify = ngx_slab_alloc(shpool, sizeof(ngx_rpc_notify_t));

    notify->shpool = shpool;
    notify->log = ngx_cycle->log;


    if(ngx_shmtx_create(&notify->queue_lock, &notify->queue_sh, NULL) != NGX_OK)
    {
        ngx_log_error(NGX_LOG_ERR, notify->log, 0, "ngx_shmtx_create failed");
        ngx_slab_free(shpool, notify);
        return NULL;
    }

    notify->event_fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);

    ngx_queue_init(&notify->queue_head);

    ngx_queue_init(&notify->idles);

    return notify;
}
// 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;
}