• <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>

            S.l.e!ep.¢%

            像打了激速一樣,以四倍的速度運(yùn)轉(zhuǎn),開心的工作
            簡(jiǎn)單、開放、平等的公司文化;尊重個(gè)性、自由與個(gè)人價(jià)值;
            posts - 1098, comments - 335, trackbacks - 0, articles - 1
              C++博客 :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

            skynet的啟動(dòng) 2014.11.05

            Posted on 2014-11-05 17:44 S.l.e!ep.¢% 閱讀(701) 評(píng)論(0)  編輯 收藏 引用 所屬分類: Skynet
            bootstrap(..); 之前的代碼沒看懂

            bootstrap()代碼如下
            static?void
            bootstrap(
            struct?skynet_context?*?logger,?const?char?*?cmdline)?{
            ????
            int?sz?=?strlen(cmdline);
            ????
            char?name[sz+1];
            ????
            char?args[sz+1];
            ????sscanf(cmdline,?
            "%s?%s",?name,?args);
            ????
            struct?skynet_context?*ctx?=?skynet_context_new(name,?args);
            ????
            if?(ctx?==?NULL)?{
            ????????skynet_error(NULL,?
            "Bootstrap?error?:?%s\n",?cmdline);
            ????????skynet_context_dispatchall(logger);
            ????????exit(
            1);
            ????}
            }

            一開始以為 skynet_context_new() 只是malloc()之類的調(diào)用而已
            后來再看看 skynet_context_new() 的源碼

            struct?skynet_context?*?
            skynet_context_new(
            const?char?*?name,?const?char?*param)?{
            ????
            struct?skynet_module?*?mod?=?skynet_module_query(name);

            ????
            if?(mod?==?NULL)
            ????????
            return?NULL;

            ????
            void?*inst?=?skynet_module_instance_create(mod);
            ????
            if?(inst?==?NULL)
            ????????
            return?NULL;
            ????
            struct?skynet_context?*?ctx?=?skynet_malloc(sizeof(*ctx));
            ????CHECKCALLING_INIT(ctx)

            ????ctx
            ->mod?=?mod;
            ????ctx
            ->instance?=?inst;
            ????ctx
            ->ref?=?2;
            ????ctx
            ->cb?=?NULL;
            ????ctx
            ->cb_ud?=?NULL;
            ????ctx
            ->session_id?=?0;
            ????ctx
            ->logfile?=?NULL;

            ????ctx
            ->init?=?false;
            ????ctx
            ->endless?=?false;
            ????
            //?Should?set?to?0?first?to?avoid?skynet_handle_retireall?get?an?uninitialized?handle
            ????ctx->handle?=?0;????
            ????ctx
            ->handle?=?skynet_handle_register(ctx);
            ????
            struct?message_queue?*?queue?=?ctx->queue?=?skynet_mq_create(ctx->handle);
            ????
            //?init?function?maybe?use?ctx->handle,?so?it?must?init?at?last
            ????context_inc();

            ????CHECKCALLING_BEGIN(ctx)
            ????
            int?r?=?skynet_module_instance_init(mod,?inst,?ctx,?param);
            ????CHECKCALLING_END(ctx)
            ????
            if?(r?==?0)?{
            ????????
            struct?skynet_context?*?ret?=?skynet_context_release(ctx);
            ????????
            if?(ret)?{
            ????????????ctx
            ->init?=?true;
            ????????}
            ????????skynet_globalmq_push(queue);
            ????????
            if?(ret)?{
            ????????????skynet_error(ret,?
            "LAUNCH?%s?%s",?name,?param???param?:?"");
            ????????}
            ????????
            return?ret;
            ????}?
            else?{
            ????????skynet_error(ctx,?
            "FAILED?launch?%s",?name);
            ????????uint32_t?handle?
            =?ctx->handle;
            ????????skynet_context_release(ctx);
            ????????skynet_handle_retire(handle);
            ????????
            struct?drop_t?d?=?{?handle?};
            ????????skynet_mq_release(queue,?drop_message,?
            &d);
            ????????
            return?NULL;
            ????}
            }

            大概是進(jìn)行了模塊的初始化,并為這個(gè)模塊創(chuàng)建消息隊(duì)列, 并放到全局的隊(duì)列里(注:模塊初始化時(shí)會(huì)將 param 傳進(jìn)去)

            之后開啟線程,進(jìn)行消息處理
            _start(config->thread);

            用GDB調(diào)試,看下堆棧
            #0??_init?(l=0x2b98570163a0,?ctx=0x2b98570540f0,?args=0x2b9857099070?"bootstrap",?sz=9)?at?service-src/service_snlua.c:71
            #
            1??0x00002b9857d02469?in?_launch?(context=0x2b98570540f0,?ud=0x2b98570163a0,?type=0,?session=0,?source=16777218,?msg=0x2b9857099070,?sz=9)?at?service-src/service_snlua.c:125
            #
            2??0x0000000000409546?in?dispatch_message?(ctx=0x2b98570540f0,?msg=0x420030e0)?at?skynet-src/skynet_server.c:254
            #
            3??0x00000000004096c4?in?skynet_context_message_dispatch?(sm=0x2b9857016440,?q=0x2b98570530c0,?weight=-1)?at?skynet-src/skynet_server.c:308
            #
            4??0x000000000040a98f?in?_worker?(p=0x7fff54a5f8d0)?at?skynet-src/skynet_start.c:128

            為何會(huì)調(diào)用到 _launch? 回到前面
            static?void
            bootstrap(
            struct?skynet_context?*?logger,?const?char?*?cmdline)?{
            ????
            int?sz?=?strlen(cmdline);
            ????
            char?name[sz+1];
            ????
            char?args[sz+1];
            ????sscanf(cmdline,?
            "%s?%s",?name,?args);
            ????
            struct?skynet_context?*ctx?=?skynet_context_new(name,?args);?// 這里傳的參數(shù)分別為 snlua?bootstrap
            ????if?(ctx?==?NULL)?{
            ????????skynet_error(NULL,?
            "Bootstrap?error?:?%s\n",?cmdline);
            ????????skynet_context_dispatchall(logger);
            ????????exit(
            1);
            ????}
            }

            調(diào)用的流程是這樣的
            #0? _open_sym (mod=0x2b9e0a032438) at skynet-src/skynet_module.c:76
            #1? 0x0000000000408463 in skynet_module_query (name=0x7fffa16ae600 "snlua") at skynet-src/skynet_module.c:107
            #2? 0x0000000000409099 in skynet_context_new (name=0x7fffa16ae600 "snlua", param=0x7fffa16ae5e0 "bootstrap") at skynet-src/skynet_server.c:117
            #3? 0x000000000040adda in bootstrap (logger=0x2b9e0a054080, cmdline=0x2b9e0a0aa298 "snlua bootstrap") at skynet-src/skynet_start.c:204
            #4? 0x000000000040aedb in skynet_start (config=0x7fffa16ae6d0) at skynet-src/skynet_start.c:232
            #5? 0x000000000040751e in main (argc=2, argv=0x7fffa16ae7f8) at skynet-src/skynet_main.c:139

            skynet_context_new 會(huì)先去 cservice目錄下 查找 snlua.so , 然后分別找
            snlua_create? --->? skynet_module->create
            snlua_init??? --->? skynet_module->init
            snlua_release --->? skynet_module->release
            這三個(gè)函數(shù)然后分別賦值給
            skynet_module 的 create / init / release

            snlua.so 的代碼在 service_snlua.c
            看 snlua_init() 函數(shù)代碼就知道它將 skynet_context 的 cb 賦值為
            _launch

            int
            snlua_init(
            struct?snlua?*l,?struct?skynet_context?*ctx,?const?char?*?args)?{
            ????
            int?sz?=?strlen(args);
            ????
            char?*?tmp?=?skynet_malloc(sz);
            ????memcpy(tmp,?args,?sz);
            ????skynet_callback(ctx,?l?,?_launch);? // 這句代碼將
            skynet_context 的 cb 賦值為 _launch
            ???
            const?char?*?self?=?skynet_command(ctx,?"REG",?NULL);
            ????uint32_t?handle_id?
            =?strtoul(self+1,?NULL,?16);
            ????
            //?it?must?be?first?message
            ????skynet_send(ctx,?0,?handle_id,?PTYPE_TAG_DONTCOPY,0,?tmp,?sz);
            ????
            return?0;
            }


            再看回下面的消息分派 dispatch_message() 里有以下代碼, 實(shí)際上就是調(diào)用了 _launch()
            ??? if (!ctx->cb(ctx, ctx->cb_ud, type, msg->session, msg->source, msg->data, sz)) {
            ??? ??? skynet_free(msg->data);
            ??? }

            #0??_init?(l=0x2b98570163a0,?ctx=0x2b98570540f0,?args=0x2b9857099070?"bootstrap",?sz=9)?at?service-src/service_snlua.c:71
            #
            1??0x00002b9857d02469?in?_launch?(context=0x2b98570540f0,?ud=0x2b98570163a0,?type=0,?session=0,?source=16777218,?msg=0x2b9857099070,?sz=9)?at?service-src/service_snlua.c:125
            #
            2??0x0000000000409546?in?dispatch_message?(ctx=0x2b98570540f0,?msg=0x420030e0)?at?skynet-src/skynet_server.c:254
            #
            3??0x00000000004096c4?in?skynet_context_message_dispatch?(sm=0x2b9857016440,?q=0x2b98570530c0,?weight=-1)?at?skynet-src/skynet_server.c:308
            #
            4??0x000000000040a98f?in?_worker?(p=0x7fff54a5f8d0)?at?skynet-src/skynet_start.c:128


            yy6080久久| 亚洲人成精品久久久久| 久久―日本道色综合久久| 一本大道久久香蕉成人网| 国产99久久久久久免费看| 狠狠色丁香久久婷婷综合五月 | 国产精品久久久久9999| 18禁黄久久久AAA片| 久久久一本精品99久久精品88| 久久午夜福利无码1000合集| 久久婷婷国产综合精品| 99精品久久久久久久婷婷| 久久99精品久久久久婷婷| 久久激情五月丁香伊人| 狠狠久久综合伊人不卡| 国产精品成人99久久久久 | 99久久综合国产精品免费| 69国产成人综合久久精品| 人妻少妇精品久久| 久久久久久亚洲精品不卡 | 久久r热这里有精品视频| 国产韩国精品一区二区三区久久| 国产精品丝袜久久久久久不卡| 亚洲精品乱码久久久久久久久久久久 | 久久精品国产亚洲精品| 久久综合亚洲鲁鲁五月天| 久久精品国产精品国产精品污 | 国产91久久综合| 天天爽天天狠久久久综合麻豆| 久久99久久无码毛片一区二区| 精品久久久久久久无码| 久久婷婷五月综合成人D啪| 国产成人精品综合久久久久| 激情五月综合综合久久69| 996久久国产精品线观看| 久久久久久久久久久精品尤物 | 久久久久久久久久久久中文字幕| 欧美性猛交xxxx免费看久久久| 久久精品一区二区国产| 久久久久久久久久久久中文字幕| 久久综合亚洲鲁鲁五月天|