skynet_context是一个服务的上下文,其保存着一个服务功能所需的操作,以snlua为例,ctx中的skynet_module保存着创建服务时需要的 snlua_create 方法等;其中的message_queue即为该ctx的消息队列,用来获取消息后创建服务;handle用来通过handle找到ctx的句柄,例如通过handle标识消息是发送给哪个ctx的。
// skynet_server.c
struct skynet_context {
void * instance; // 服务的实例
struct skynet_module * mod; // 保存服务模块的create, init, release, signal 的操作以及相关信息,用于服务的相关操作
void * cb_ud;
skynet_cb cb;
struct message_queue *queue; // 保存服务的消息队列,queue->handle能找到服务的skynet_handle
FILE * logfile;
char result[32];
uint32_t handle; // 保存skynet_context与skynet_handle的映射,可通过服务的 name 找到handle进而找到skynet_context
int session_id;
int ref;
bool init;
bool endless;
CHECKCALLING_DECL
};
skynet_module保存着服务所拥有的create,init,release,signal等方法,文件中有一个全局静态变量,用来保存所有的服务的信息。
// skynet_module.c
struct skynet_module {
const char * name; // 服务名
void * module; // 模块dll句柄
skynet_dl_create create;
skynet_dl_init init;
skynet_dl_release release;
skynet_dl_signal signal;
};
struct modules {
int count;
struct spinlock lock;
const char * path; // 记录着需要从哪里能找到服务的dll文件
struct skynet_module m[MAX_MODULE_TYPE];
};
static struct modules * M = NULL; // 保存所有的服务信息
message_queue保存服务的消息队列的信息,其中的handle保存的是skynet_context中的handle,方便通过handle找到相应的context;文件中有一个全局静态变量Q,保存所有的消息队列信息。
// skynet_mq.c
struct message_queue {
struct spinlock lock;
uint32_t handle; // 保存的值是ctx的skynet_handle
int cap;
int head;
int tail;
int release;
int in_global;
int overload;
int overload_threshold;
struct skynet_message *queue;
struct message_queue *next;
};
struct global_queue {
struct message_queue *head;
struct message_queue *tail;
struct spinlock lock;
};
static struct global_queue *Q = NULL; // 保存所有的服务的队列
skynet_handle 即为skynet_context中的handle句柄值,该值通过skynet_handle_register生成,通过文件中的全局静态变量H来保存服务名name与handle的映射,以及name,handle与skynet_context的映射关系。
// skynet_handle.c
struct handle_name { // 保存name与handle的映射
char * name;
uint32_t handle;
};
struct handle_storage { // 保存handle_name与skynet_context的映射
struct rwlock lock;
uint32_t harbor;
uint32_t handle_index;
int slot_size;
struct skynet_context ** slot;
int name_cap;
int name_count;
struct handle_name *name;
};
static struct handle_storage *H = NULL; // 保存所有的服务的handle与context的映射的链表