событие lib — Http-сервер — Обратный вызов прекращается для запуска

#c #httpserver #libevent

Вопрос:

Я разработал http-сервер (rest api) на C с использованием события lib.

Сервер получает http-запросы и отвечает на них, а также выполняет некоторые https-запросы к внешнему rest api. HTTP-запросы, выполняемые к внешнему api и http-серверу, используют одну и ту же базу событий.

Все работает нормально до тех пор, пока случайно обратный вызов, на который я получаю запросы, не прекратится. События таймера событий lib работают, потому что у меня тоже работает таймер, и выполняется обратный вызов таймера, только обратный вызов http-сервера перестает выполняться случайным образом.

После того, как я перезапущу программу, все снова начнет работать нормально.

API работает в ubuntu server 18.04, а версия libevent-2.1.6.

Кое — что из моего кода:

 rest_api_t *rest_api_new(
        int port,
        rest_api_request_t *reqs,
        unsigned reqs_len,
        rest_api_authorization_cb *auth_cb,
        void *ctx )
{
    //evthread_use_pthreads( );

    rest_api_t *api = calloc( 1, sizeof (*api) );
    api->ctx     = ctx;
    api->base    = event_base_new( );
    api->http    = evhttp_new( api->base );
    api->auth_cb = auth_cb;
    api->port    = port;

    // Add signal to rest api exit
    api->exit = evsignal_new( api->base, SIGINT, _rest_api_exit_cb, api->base );
    event_add( api->exit, NULL );

    // Set requests
    api->reqs = calloc( reqs_len, sizeof (*api->reqs) );
    size_t reqs_size = (sizeof (rest_api_request_t) * reqs_len);
    memcpy( api->reqs, reqs, reqs_size );
    api->reqs_len = reqs_len;

    // Set allowed methods
    evhttp_set_allowed_methods( api->http,
                                EVHTTP_REQ_GET |
                                EVHTTP_REQ_POST |
                                EVHTTP_REQ_PATCH |
                                EVHTTP_REQ_DELETE |
                                EVHTTP_REQ_OPTIONS );
    // Set buffer event callback
    evhttp_set_bevcb( api->http, bufferevent_cb, NULL );
    // Set requests callback
    evhttp_set_gencb( api->http, _rest_api_request_cb, api );
    // Set default unauthorized message
    rest_api_unauthorized_msg_set( api, HTTP_UNAUTHORIZED_MSG );

    return api;
}
 
 static
void _rest_api_request_cb( struct evhttp_request *request, void *arg )
{
    const enum evhttp_cmd_type http_cmd = evhttp_request_get_command( request );
    const char *cmd = _http_cmd_str( http_cmd );
    const char *uri = evhttp_request_get_uri( request );
    log_info( "%s %s", cmd ,uri );

    if ( http_cmd == EVHTTP_REQ_OPTIONS )
    {
        _rest_api_preflight_options_handle( request );
    }
    else
    {
        rest_api_t *api = arg;
        _rest_api_request_dispatch( request, api );
    }
}
 
 bool rest_api_run( rest_api_t *api )
{
    int rc = -1;

    struct evhttp_bound_socket *handle = NULL;
    handle = evhttp_bind_socket_with_handle( api->http, "0.0.0.0", api->port );
    if ( handle != NULL )
        rc = event_base_dispatch( api->base );

    return ( rc >= 0 );
}
 
 void rest_api_free( rest_api_t *api )
{
    if ( api != NULL )
    {
        event_free( api->exit );
        SSL_CTX_free( api->ssl );
        evhttp_free( api->http );
        event_base_free( api->base );
        free( api->reqs );
        free( api );
    }
}
 

Кто-нибудь знает об этой проблеме или о том, как ее решить?