青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Benjamin

靜以修身,儉以養(yǎng)德,非澹薄無以明志,非寧靜無以致遠。
隨筆 - 398, 文章 - 0, 評論 - 196, 引用 - 0
數(shù)據(jù)加載中……

bind源碼解析(一)

  Bind是一款開放源碼的DNS服務(wù)器軟件,Bind由美國加州大學(xué)Berkeley分校研發(fā)和維護的,全名為Berkeley Internet Name Domain他是目前世界上使用最為廣泛的DNS服務(wù)器軟件,支持各種unix平臺和windows平臺。官方網(wǎng)站:http://www.bind.com/

下面介紹一下Bind軟件的主要的socket處理模塊:
Bind
業(yè)務(wù)處理主要要關(guān)注一個run函數(shù)和isc_app_run函數(shù),前者是線程函數(shù),相當(dāng)于一個消息泵,這個for循環(huán)作用通過管道發(fā)送事件,這個事件在到task里的run中被處理,如此反復(fù)和windows編程中的消息循環(huán)類似;

Bind中的socket采用的是epoll模型,在main.c中的setup函數(shù)里的result = create_managers()->result = isc_socketmgr_create2(ns_g_mctx, &ns_g_socketmgr, maxsocks)-> setup_watcher;創(chuàng)建epoolif(isc_thread_create(watcher, manager, &manager->watcher) != ISC_R_SUCCESS) 啟動watcher這個線程函數(shù)process_fds來處理epoll,具體的處理函數(shù)是process_fd,根據(jù)不同的事件來執(zhí)行dispatch_accept(sock); dispatch_recv(sock); dispatch_connect(sock); dispatch_send(sock);這幾個函數(shù)最后執(zhí)行的都是isc_task_send(它的作用是將event加到task隊列中)

main函數(shù)中,setup創(chuàng)建進程必要的服務(wù),setup里比較重要的函數(shù)是create_managersns_server_createns_server_create主要是對一些結(jié)構(gòu)體中的函數(shù)指針賦值還有用到的數(shù)據(jù)結(jié)構(gòu)分配內(nèi)存,create_managers啟動各種線程;

isc_app_run則是見將on-run事件(通過管道)加入到任務(wù)隊列中,最終執(zhí)行的是isc__task_sendanddetach。在ns_server_create中的CHECKFATAL(isc_app_onrun(ns_g_mctx, server->task, run_server, server),"isc_app_onrun")里的ISC_LIST_APPEND(isc_g_appctx.on_run, event, ev_link)比較關(guān)鍵,將on-run事件到鏈表中,這個鏈表在isc_app_run里的for循環(huán)中被遍歷;

Socket的初始化:

setup(void)-> create_managers->isc__socketmgr_create2函數(shù)中:
manager->common.methods = &socketmgrmethods;將函數(shù)指針賦值。ns_server_create(ns_g_mctx, &ns_g_server)
CHECKFATAL(isc_app_onrun(ns_g_mctx, server->task, run_server, server),"isc_app_onrun");實際執(zhí)行的是run_server函數(shù)
load_configuration->scan_interfaces(server, ISC_TRUE)->ns_interfacemgr_scan(server->interfacemgr, verbose)->ns_interfacemgr_scan0(mgr, NULL, verbose)-> do_scan->ns_interface_setup->if (accept_tcp == ISC_TRUE) {result = ns_interface_accepttcp(ifp);->isc_socket_create->manager->methods->socketcreate(manager, pf, type, socketp)這句代碼會調(diào)用上面賦給的函數(shù)地址(socketmgrmethods),將調(diào)用socketmgrmethodsisc__socket_create函數(shù)。前面闡述的是有關(guān)tcp的初始化,下面是udp的初始化:

do_scan->ns_interface_setup->ns_interface_listenudp->ns_clientmgr_createclients->client_create->
clclient->sendevent = (isc_socketevent_t *)
       isc_event_allocate(client->mctx, client,
            ISC_SOCKEVENT_SENDDONE,
            client_senddone, client,
            sizeof(isc_socketevent_t));
client->recvevent = (isc_socketevent_t *)
       isc_event_allocate(client->mctx, client,
            ISC_SOCKEVENT_RECVDONE,
            client_request, client,
            sizeof(isc_socketevent_t));

主要功能就是賦值ISC_EVENT_INIT(event, size, 0, NULL, type, action, deconst_arg,sender, destroy, mctx);active函數(shù)指針賦值為client_request,即在這里給UDP的處理函數(shù)賦值(接收);發(fā)送同樣如此:這樣每進來一次udp就查詢一次,,會在task的run函數(shù)里執(zhí)行active指針函數(shù),進而調(diào)用這個client_request

switch (client->message->opcode) {
 case dns_opcode_query:
              CTRACE("query");
              ns_query_start(client);
              break;
       case dns_opcode_update:
              CTRACE("update");
              ns_client_settimeout(client, 60);
              ns_update_start(client, sigresult);
              break;
       case dns_opcode_notify:
              CTRACE("notify");
              ns_client_settimeout(client, 60);
              ns_notify_start(client);
              break;

       case dns_opcode_iquery:
              CTRACE("iquery");
              ns_client_error(client, DNS_R_NOTIMP);
              break;
       default:
 
              CTRACE("unknown opcode");
             ns_client_error(client, DNS_R_NOTIMP);
       }

 

Sockettask的關(guān)聯(lián)(和一些關(guān)鍵性代碼的說明):

1isc__task_create(isc_taskmgr_t *manager0, unsigned int quantum,isc_task_t **taskp)—創(chuàng)建ns_g_taskmgr,實參:ns_g_mctx, ns_g_cpus, 0, &ns_g_taskmgr
 
/*分配內(nèi)存*/manager = isc_mem_get(mctx, sizeof(*manager));返回的是ret = ctx->freelists[new_size];(ctx->memalloc)(ctx->arg, size);前者是鏈表的最后,后在則是分配的內(nèi)存的起始位置。
manag的數(shù)據(jù)類型是isc__taskmgr_tctxisc__mem類型,ctx->freelistelement **           freelistselement則是typedef struct element element;
struct element { 
     
element *            next;
};

//初始化條件變量(linux系統(tǒng)的函數(shù)) 一旦其它的某個線程改變了條件變量,它將通知相應(yīng)的條件變量喚醒一個或多個正被此條件變量阻塞的線程。這些線程將重新鎖定互斥鎖 并重新測試條件是否滿足。一般說來,條件變量被用來進行線程間的同步。

if (isc_condition_init(&manager->work_available) != ISC_R_SUCCESS) {
              UNEXPECTED_ERROR(__FILE__, __LINE__,
                             "isc_condition_init() %s",
                             isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
                                          ISC_MSG_FAILED, "failed"));
              result = ISC_R_UNEXPECTED;
              goto cleanup_threads;
       }

       /*初始化條件變量*/
       if (isc_condition_init(&manager->exclusive_granted) != ISC_R_SUCCESS) {
              UNEXPECTED_ERROR(__FILE__, __LINE__,
                             "isc_condition_init() %s",
                             isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
                                          ISC_MSG_FAILED, "failed"));
              result = ISC_R_UNEXPECTED;
              goto cleanup_workavailable;
       }

 

/*啟線程*/
       for (i = 0; i < workers; i++) {
              if (isc_thread_create(run, manager,
                               &manager->threads[manager->workers]) ==
                  ISC_R_SUCCESS) {
                     manager->workers++;
                     started++;
              }
       }

/*設(shè)置并發(fā)線程*/
isc_thread_setconcurrency(workers);
/*附加到特定的內(nèi)存塊上*/
isc_mem_attach(mctx, &manager->mctx);muct的值賦給&manager->mctx
最后啟動線程。重點說明一下這個run線程函數(shù),這個線程函數(shù)使用來處理task的。run(void *uap) {

…………………………………………………………………….
       isc__taskmgr_t *manager = uap;
       dispatch(manager);windowsDispatchMessage類似分發(fā)消息

……………………………………………………………………..
       return ((isc_threadresult_t)0);

}

static void dispatch(isc__taskmgr_t *manager)里面有三個while循環(huán)
//判斷(manager)->exiting && (manager)->tasks. .head == NULL
while (!FINISHED(manager))
while ((EMPTY(manager->ready_tasks) ||manager->exclusive_requested) &&!FINISHED(manager)) // 判斷(manager->ready_tasks).head ==NULL
{、
XTHREADTRACE(isc_msgcat_get(isc_msgcat,ISC_MSGSET_GENERAL,ISC_MSG_WAIT, "wait"));
WAIT(&manager->work_available, &manager->lock);
//實際執(zhí)行的是isc_condition_wait((&manager->work_available), (&manager->lock)) == ISC_R_SUCCESS);-----------------> (pthread_cond_wait((&manager->work_available), &((&manager->lock)->mutex)) == 0,這里用來發(fā)信號,對互斥量加以保護,線程釋放互斥量,等待其他線程發(fā)給該條件變量的信號(喚醒一個等待者)或廣播該條件變量(喚醒所有等待者)。當(dāng)?shù)却龡l件變量時,互斥量必須始終為釋放的,這樣其他線程才有機會鎖住互斥量,修改條件變量。當(dāng)線程從條件變量等待中醒來時,它重新繼續(xù)鎖住互斥量,對臨界資源進行處理。
XTHREADTRACE(isc_msgcat_get(isc_msgcat,ISC_MSGSET_TASK,ISC_MSG_AWAKE, "awake"));
}
task = HEAD(manager->ready_tasks);
if (task != NULL) {
task->state = task_state_running;
                   XTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
                                       ISC_MSG_RUNNING, "running"));
                   isc_stdtime_get(&task->now);
//遍歷鏈表
                   do {
                          if (!EMPTY(task->events)) {
                                 event = HEAD(task->events);
                                 DEQUEUE(task->events, event, ev_link);
 

                                 /**執(zhí)行事件消息處理  */
.........................................................

if (event->ev_action != NULL) {
UNLOCK(&task->lock);
 (event->ev_action)(   (isc_task_t *)task, event);
LOCK(&task->lock);   
                             
}
           
 
dispatch_count++;
 } if (task->references == 0 && EMPTY(task->events) &&!TASK_SHUTTINGDOWN(task)) { isc_boolean_t was_idle;

/*在這個任務(wù)里沒有引用沒有待定的事件,這意味者不會有實際的事件(動作)發(fā)生,初始化關(guān)機以防止成為一個廢止(狀態(tài))。替代"if EMPTY(task->events)"的原因:如果發(fā)送沒有關(guān)機事件,將派發(fā)一個結(jié)束任務(wù);如果沒有派發(fā)關(guān)機事件,(總是)希望任務(wù)的總量是實際中(任務(wù)的總量)*/
 was_idle = task_shutdown(task);                                
INSIST(!was_idle);
 } 

                          if (EMPTY(task->events)) {                       
                             XTRACE(isc_msgcat_get(isc_msgcat,
                                                     ISC_MSGSET_TASK,
                                                     ISC_MSG_EMPTY,
                                                     "empty"));
                                 if (task->references == 0 &&
                                     TASK_SHUTTINGDOWN(task)) {
                                       /*The task is done */
                                       XTRACE(isc_msgcat_get(
                                                      isc_msgcat,
                                                      ISC_MSGSET_TASK,
                                                      ISC_MSG_DONE,
                                                     "done"));
                                        finished = ISC_TRUE;
                                        task->state = task_state_done;
                                 } else
                                        task->state = task_state_idle;
                                 done = ISC_TRUE;
                          } else if (dispatch_count >= task->quantum) {

/*(任務(wù))總量用完,但是還有更多的work在做,將重新排列放到在準備隊列后。不必檢查總量直到至少派發(fā)一個事件,因此最小數(shù)是1*/                                 XTRACE(isc_msgcat_get(isc_msgcat,
                                                     ISC_MSGSET_TASK,
                                                     ISC_MSG_QUANTUM,
                                                     "quantum"));
                                 task->state = task_state_ready;
                                 requeue = ISC_TRUE;
                                 done = ISC_TRUE;
                          }
                   } while (!done); 初始化是ISC_FALSE
       ………

} 

注意:上面處理的是ns_g_taskmgr里的task

 

2isc__socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,unsigned int maxsocks)//創(chuàng)建ns_g_socketmgr
實參:ns_g_mctx, &ns_g_socketmgr, maxsocks
isc__socketmgr_t *manager;
*managerp = (isc_socketmgr_t *)socketmgr;//初始化 

manager = isc_mem_get(mctx, sizeof(*manager));//分配內(nèi)存manger的各個成員變量和方法賦值;

................................................
//
初始化manager->shutdown_ok—條件變量,和互斥對象配合使用在多線程編程中。
if (isc_condition_init(&manager->shutdown_ok) != ISC_R_SUCCESS) {
              UNEXPECTED_ERROR(__FILE__, __LINE__,
                             "isc_condition_init() %s",
                             isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
                                          ISC_MSG_FAILED, "failed"));
              result = ISC_R_UNEXPECTED;
              goto cleanup_lock;
       }

//創(chuàng)建管道-----epoll模型中使用
if (pipe(manager->pipe_fds) != 0) {
              isc__strerror(errno, strbuf, sizeof(strbuf));
              UNEXPECTED_ERROR(__FILE__, __LINE__,
                             "pipe() %s: %s",
                             isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,\
                                          ISC_MSG_FAILED, "failed"),
                             strbuf);
              result = ISC_R_UNEXPECTED;
              goto cleanup_condition;
       }

//設(shè)置EPOLL中的事件和文件描述的關(guān)聯(lián)
result = setup_watcher(mctx, manager);這個函數(shù)實際上執(zhí)行的是epoll_ctl(manager->epoll_fd, EPOLL_CTL_ADD, fd, &event)
if (isc_thread_create(watcher, manager, &manager->watcher) !=ISC_R_SUCCESS)//啟動線程,實際執(zhí)行的是cc = epoll_wait(manager->epoll_fd, manager->events,
manager->nevents, -1);開始監(jiān)聽管道里的事件,如果需要處理就處理。

posted on 2010-12-20 21:44 Benjamin 閱讀(4065) 評論(3)  編輯 收藏 引用 所屬分類: linux

評論

# re: bind源碼解析(一)  回復(fù)  更多評論   

When you are in a not good position and have no money to move out from that, you would require to take the <a href="http://bestfinance-blog.com/topics/home-loans">home loans</a>. Just because that will help you unquestionably. I get short term loan every time I need and feel good because of that.
2011-09-08 14:39 | CAMERONMeredith19

# re: bind源碼解析(一)  回復(fù)  更多評論   

Do you see that you do great investigation just about this good post. Continue performing that! Students buy essay just about this opting for the term paper writing services.
2011-10-07 06:25 | buy essays

# re: bind源碼解析(一)  回復(fù)  更多評論   

Tha’s really payless to receive hot enough fact referring to this good topic. But sometimes students switch on the personal computer and buy research paper and everybody could have the assistance of the high quality custom essays writing corporations to buy an essay fast.
2011-10-09 02:18 | buy research papers
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            日韩视频一区二区三区在线播放 | 久久精品五月| 亚洲理论电影网| 欧美mv日韩mv国产网站| 欧美成人免费大片| 亚洲国产成人精品女人久久久| 亚洲欧美国产77777| 亚洲在线不卡| 久久久人成影片一区二区三区| 久久久一区二区| 国产婷婷色综合av蜜臀av | 日韩视频专区| 亚洲一区欧美| 久久成人精品一区二区三区| 久久久久五月天| 欧美精品久久久久久久| 欧美涩涩视频| 韩日精品视频一区| 日韩视频不卡| 久久成人18免费网站| 性欧美xxxx大乳国产app| 欧美伊人久久大香线蕉综合69| 久久免费视频网| 久久亚洲高清| 国产精品久久久久毛片软件| 影音先锋久久| 亚洲综合成人在线| 欧美高清在线| 亚洲欧美日韩天堂| 久久综合网hezyo| 国产精品国产亚洲精品看不卡15| 在线观看日韩一区| 亚洲欧美日本伦理| 亚洲电影成人| 欧美专区第一页| 国产精品美女视频网站| 欧美1区视频| 欧美 日韩 国产一区二区在线视频 | 亚洲精品一二三区| 亚洲午夜国产成人av电影男同| 亚洲天堂成人| 美女网站久久| 亚洲一区二区三区视频| 欧美91精品| 韩国三级电影一区二区| 亚洲一区二区三区四区五区黄| 欧美成人免费一级人片100| 亚洲网站视频| 欧美日韩一区国产| 亚洲精选一区| 欧美高清视频一区二区| 久久国内精品自在自线400部| 国产精品高潮视频| 99riav久久精品riav| 欧美国产亚洲精品久久久8v| 亚洲已满18点击进入久久| 日韩亚洲欧美中文三级| 久久免费精品视频| 久久久.com| 欧美视频免费在线| 一色屋精品视频在线观看网站| 亚洲国产欧美精品| 久久综合999| 久久不射电影网| 国产日韩欧美综合在线| 亚洲小说春色综合另类电影| 欧美午夜片在线观看| 免费看亚洲片| 午夜精品一区二区三区在线视| 欧美激情精品久久久久久黑人| 亚洲春色另类小说| 欧美成人一区二区三区片免费| 欧美在线视屏| 在线精品亚洲| 亚洲激情电影在线| 久久亚洲综合色| 亚洲国产婷婷| 亚洲免费观看高清在线观看 | 欧美日韩日本国产亚洲在线| 亚洲日本成人| 久久亚洲影音av资源网| 亚洲国产欧美在线人成| 久久久久一区二区三区四区| 1000部国产精品成人观看| 美女日韩欧美| 欧美不卡高清| 亚洲欧美成人在线| 久久成人免费视频| 91久久亚洲| 亚洲午夜激情网页| 在线观看一区二区视频| 亚洲人成在线观看网站高清| 国产精品二区影院| 免费不卡在线视频| 欧美视频网址| 免费成人在线视频网站| 欧美另类视频在线| 久久久亚洲精品一区二区三区 | 99精品视频免费在线观看| 99xxxx成人网| 国产精品嫩草99av在线| 久久久精品一区| 欧美国产视频在线| 性久久久久久久久久久久| 久久琪琪电影院| 亚洲欧美日韩电影| 麻豆国产va免费精品高清在线| 国产精品99久久久久久白浆小说 | 日韩亚洲欧美综合| 国产视频一区欧美| 夜夜嗨一区二区| 亚洲电影免费| 亚洲欧美视频在线| 在线中文字幕一区| 鲁鲁狠狠狠7777一区二区| 欧美一区2区三区4区公司二百| 亚洲欧洲精品成人久久奇米网 | 亚洲欧美激情视频在线观看一区二区三区| 精品1区2区| 亚洲欧美春色| 中文精品在线| 欧美激情一区二区三区高清视频| 久久久www成人免费毛片麻豆| 欧美色图麻豆| 亚洲精品一区二区三区蜜桃久| 樱桃国产成人精品视频| 欧美一区日韩一区| 欧美亚洲免费高清在线观看| 欧美日韩一本到| 99国内精品久久| 亚洲午夜黄色| 欧美视频免费在线| 宅男噜噜噜66一区二区| 亚洲无毛电影| 国产精品久久999| 亚洲一区二区三区成人在线视频精品 | 久久综合九色99| 欧美伊人久久大香线蕉综合69| 欧美天堂亚洲电影院在线播放| 日韩视频永久免费观看| 99精品视频免费| 亚洲伦理自拍| 亚洲专区在线| 欧美黄免费看| 亚洲国产精品电影| 亚洲人成高清| 欧美黄色精品| 亚洲免费电影在线| 亚洲免费网站| 国产亚洲美州欧州综合国| 亚洲欧美日韩国产一区二区三区| 午夜国产精品视频免费体验区| 国产精品久久999| 午夜精品www| 欧美.www| 免费观看一区| 亚洲精品乱码久久久久久蜜桃麻豆| 亚洲精品在线视频| 欧美特黄a级高清免费大片a级| 亚洲一区二区三区四区五区黄| 性久久久久久| 亚洲电影在线播放| 欧美日产在线观看| 亚洲欧洲日本mm| 亚洲精品国产精品国自产在线 | 亚洲欧美日韩一区二区在线| 久久精品免费播放| 亚洲福利精品| 欧美小视频在线观看| 欧美在线中文字幕| 91久久国产综合久久蜜月精品 | 欧美视频中文字幕| 午夜精品久久久久99热蜜桃导演| 久久综合九色综合欧美就去吻| 亚洲每日在线| 国产一区二区三区四区三区四| 欧美成人午夜77777| 中文欧美在线视频| 亚洲日本电影| 欧美日韩午夜视频在线观看| 亚洲午夜精品视频| 久久亚洲精品伦理| 亚洲色图在线视频| 精品盗摄一区二区三区| 欧美日韩国产123| 久久精品国亚洲| 一区二区国产日产| 亚洲福利免费| 久久精品一区二区国产| 亚洲无限av看| 亚洲精品一区二区在线| 国产一区二区精品久久99| 欧美日韩伦理在线| 免费久久精品视频| 欧美一区二视频在线免费观看| 中日韩午夜理伦电影免费| 亚洲国产影院| 麻豆成人在线观看| 国产精品久久一区主播| 欧美一区二区免费|