曾經研究memcached的時候發現它的狀態機裏有一個很隱蔽的邏輯bug很難觸發就隨手在issue裏提了個bug,如今已經被合併到memcached主幹上了git
on line 3857 if update_event() return false and the connection's bind event is still EV_READ c->state will be conn_closing and stop will be true if no more bytes comes, the socket will never be cleanup?
就是說在memcache.c的3857行若是update_event()返回false而且 鏈接的bind event依舊是EV_READgithub
c->state將會是conn_closing 並且 stop的值將會是truebash
這時若是沒有更多的數據從socket上傳入socket將永遠不會被清理形成泄漏less
Status: Fixed:運維
https://code.google.com/p/memcached/issues/detail?id=261&can=1&q=auxtenwpc%40gmail.comsocket
https://github.com/memcached/memcached/commit/b2734f8321230bd52e36df7f82a6b1d71532e496ide
過了兩年纔有人鳥我而後被合併到主幹上了:-)memcached
Reported by auxten...@gmail.com, Mar 17, 2012google
3839 case conn_new_cmd: 3840 /* Only process nreqs at a time to avoid starving other 3841 connections */ 3842 3843 --nreqs; 3844 if (nreqs >= 0) { 3845 reset_cmd_handler(c); 3846 } else { 3847 pthread_mutex_lock(&c->thread->stats.mutex); 3848 c->thread->stats.conn_yields++; 3849 pthread_mutex_unlock(&c->thread->stats.mutex); 3850 if (c->rbytes > 0) { 3851 /* We have already read in data into the input buffer, 3852 so libevent will most likely not signal read events 3853 on the socket (unless more data is available. As a 3854 hack we should just put in a request to write data, 3855 because that should be possible ;-) 3856 */ 3857 if (!update_event(c, EV_WRITE | EV_PERSIST)) { 3858 if (settings.verbose > 0) 3859 fprintf(stderr, "Couldn't update event\n"); 3860 conn_set_state(c, conn_closing); 3861 } 3862 } 3863 stop = true; 3864 } 3865 break; on line 3857 if update_event() return false and the connection's bind event is still EV_READ c->state will be conn_closing and stop will be true if no more bytes comes, the socket will never be cleanup? so i think there need a patch --- a/memcached.c +++ b/memcached.c @@ -3858,6 +3858,7 @@ static void drive_machine(conn *c) { if (settings.verbose > 0) fprintf(stderr, "Couldn't update event\n"); conn_set_state(c, conn_closing); + break; } } stop = true;
Project Member #1 dorma...@rydia.netspa
Wow, two years old... and it looks correct to me. If that update_event fails the connection might zombie. It's very hard for that to fail and it's been that way forever. Pushed a commit for the next release.
歡迎加入運維開發技術分享QQ羣365534424