2016-06-19 7 views
2

У меня есть однопоточный сервер, написанный на C, который принимает TCP/UDP-соединения на основе EPOLL и поддерживает плагины для множества уровней протокола, которые нам необходимо поддерживать. Этот бит в порядке.MariaDB, не блокирующий с помощью EPOLL

Из-за однопоточной природы я хотел реализовать слой базы данных, который мог бы использовать одну и ту же архитектуру EPOLL, а затем отдельно перебирать все открытые соединения.

Мы используем соединители MariaDB и MariaDB, которые поддерживают неблокирующие функции в его API.

https://mariadb.com/kb/en/mariadb/using-the-non-blocking-library/

Но то, что я нахожу, что это не то, что я ожидал, и то, что я ожидал, что будет описано ниже.

Сначала я запускаю mysql_real_connect_start(), и если он возвращает ноль, мы немедленно отправляем запрос, поскольку это указывает на отсутствие блокировки, хотя этого никогда не происходит.

В противном случае я получаю дескриптор файла, который кажется незамедлительным, и зарегистрируйте его с помощью EPOLL и вернитесь в основную петлю EPOLL, ожидая событий.

s = mysql_get_socket(mysql); 

if(s > 0) 
{ 
    brt_socket_set_fds(endpoint, s); 
    struct epoll_event event; 
    event.data.fd = s; 
    event.events = EPOLLRDHUP | EPOLLIN | EPOLLET | EPOLLOUT; 
    s = epoll_ctl(efd, EPOLL_CTL_ADD, s, &event); 
    if (s == -1) { 
     syslog(LOG_ERR, "brd_db : epoll error."); 
     // handle error. 
    } 
... 

Итак, через некоторое время я получаю EPOLLOUT, указывающий, что розетка была открыта.

И я добросовестно вызываю mysql_real_connect_cont(), но на этом этапе он все равно возвращает ненулевое значение, указывая, что я должен ждать дольше?

Но вот это последнее событие EPOLL, которое я получаю, за исключением EPOLLRDHUP, когда, как я полагаю, MariaDB вешает трубку через 10 секунд.

Может ли кто-нибудь помочь мне понять, возможна ли эта идея?

Спасибо ... Спасибо ... столько спасибо.

+0

Обновление: на самом деле на mysql_real_connect_cont я получаю сообщение об ошибке «0x6643a7„Подключение к серверу MySQL на „рукопожатия: чтение щёток пакета связи“, системная ошибка: 11“» –

+0

An обновление: Я выбросил образец код с сайта MariaDB, и он отлично работает, поэтому предположим, что я ошибаюсь между _start и _cont в моем коде приложения. –

ответ

1

OK для тех, кто здесь приземляется, я исправил его или, скорее, не сломал.

Обратите внимание, что из примеров - возвращаемый статус от _start/_cont-вызовов передается как параметр в следующий _cont. Оказывается, это очень важно.

Статус содержит флаги MYSQL_WAIT_READ, MYSQL_WAIT_WRITE, MYSQL_WAIT_EXCEPT, MYSQL_WAIT_TIMEOUT, а если не передано на следующую _cont, я предполагаю, что вы возились с государственной машиной _cont.

Я не сохранял состояние статуса между разными местами, где вызывались _start и _cont.

struct MC 
{ 
    MYSQL *mysql; 
    int status; 
} MC; 
... 
// Initial call 
mc->status = mysql_real_connect_start(&ret, mc->mysql, host, user, password, NULL, 0, NULL, 0); 

// EPOLL raised calls. 
mc->status = mysql_real_connect_cont(&ret, mc->mysql, mc->status); 
if(mc->status) return... // keep waiting check for errors.