skynet_context

// skynet_server.c
struct skynet_context {
    void * instance;                    // 对应的模块的实体(例如snlua 的实体)
    struct skynet_module * mod;         // 模块的create,init,release,signal对应的处理函数
    void * cb_ud;                       // 对应模块用来绑定的结构体对象(例如:service_logger.c下的logger 结构体对象,service_snlua.c下的snlua结构体对象)
    skynet_cb cb;                       // context对应callback函数
    struct message_queue *queue;        // 消息队列列表
    FILE * logfile;
    char result[32];
    uint32_t handle;                    // 对应的handle,唯一标识,可通过handle查找到对应的消息队列,在skynet_handle.c中也可以通过handle找到对应的context
    int session_id;                     // 当前处理的消息id,用来判断是否卡死在同一个消息处理中
    int ref;
    bool init;
    bool endless;

    CHECKCALLING_DECL                  // 锁信息
};

context结构体包含了skynet_module, skynet_handle产生的handle,消息队列列表,对应模块的实体,callback信息。虽然命名是context,但是并不像操作系统中的线程上下文记录很多线程相关信息,只是记录了一个协程所用到的模块及处理,消息队列,handle。

// skynet_handle.c
struct handle_name {
    char * name;
    uint32_t handle;
};

struct handle_storage {
    struct rwlock lock;

    uint32_t harbor;
    uint32_t handle_index;
    int slot_size;
    struct skynet_context ** slot;      // 记录着所有的skynet_context
    
    int name_cap;
    int name_count;
    struct handle_name *name;
};

static struct handle_storage *H = NULL;

所有的context在new出来的时候都会注册到skynet_handle.c中的静态 handle_storage* H 结构体的slot中,在消息处理中可以通过handle或者name查找到对应skynet_context,从而找到想要的消息队列handle。

在消息派发的处理中,通过handle获取到context,从而派发到相应的次级队列的过程如下:

// skynet_server.c
struct message_queue * 
skynet_context_message_dispatch(struct skynet_monitor *sm, struct message_queue *q, int weight) {
    ...
    uint32_t handle = skynet_mq_handle(q);      // 获取消息处理对应的handle

    struct skynet_context * ctx = skynet_handle_grab(handle);      // 通过handle获得context
    ...
    int i,n=1;
    struct skynet_message msg;

    for (i=0;i<n;i++) {
        ...
        skynet_monitor_trigger(sm, msg.source , handle);

        if (ctx->cb == NULL) {
            skynet_free(msg.data);
        } else {
            dispatch_message(ctx, &msg);       // 派发到次级队列
        }

        skynet_monitor_trigger(sm, 0,0);
    }

    ...
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容