2016-06-19 75 views
2

我有用C编写的单线程服务器,它接受基于EPOLL的TCP/UDP连接并支持我们需要支持的大量协议层的插件。这一点很好。MariaDB与EPOLL非阻塞

由于单线程的性质,我想实现,可以利用相同的架构EPOLL而不是单独遍历所有打开的连接的数据库层。

我们使用MariaDB和在其API中支持非阻塞函数的MariaDB连接器。

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服务器的握手:阅读inital通信包“,系统错误:11’,” –

+0

更新:我甩样本来自MariaDB网站的代码,它工作正常,所以假设我在应用程序代码中的_start和_cont之间发生了错误。 –

回答

1

对于任何其他在此登陆的人来说,我确定它或者说不会破坏它。

注意 - 从例子 - 从_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.