// mainloop thread static void forward_message(int type, bool padding, struct socket_message * result) { struct server_socket_message *sm; int sz = sizeof(*sm); if (padding) { if (result->data) { sz += strlen(result->data); } else { result->data = ""; } } sm = (struct server_socket_message *)server_malloc(sz); sm->type = type; sm->id = result->id; sm->ud = result->ud; if (padding) { sm->buffer = NULL; strcpy((char*)(sm+1), result->data); } else { sm->buffer = result->data; } struct server_message message; message.source = 0; message.session = 0; message.data = sm; message.sz = sz | PTYPE_SOCKET << HANDLE_REMOTE_SHIFT;//高8位作为消息类型 if (server_context_push((uint32_t)result->opaque, &message)) { // todo: report somewhere to close socket // don't call server_socket_close here (It will block mainloop) server_free(sm->buffer); server_free(sm); } }
struct snlua * snlua_create(void) { struct snlua * l = server_malloc(sizeof(*l)); memset(l,0,sizeof(*l)); l->L = lua_newstate(server_lalloc, NULL);//创建一个新的lua状态机 return l; }
static void _insert_name_before(struct handle_storage *s, char *name, uint32_t handle, int before) { if (s->name_count >= s->name_cap) { s->name_cap *= 2; assert(s->name_cap <= MAX_SLOT_SIZE); struct handle_name * n = server_malloc(s->name_cap * sizeof(struct handle_name)); int i; for (i=0;i<before;i++) { n[i] = s->name[i]; } for (i=before;i<s->name_count;i++) { n[i+1] = s->name[i]; } server_free(s->name); s->name = n; } else { int i; for (i=s->name_count;i>before;i--) { s->name[i] = s->name[i-1]; } } s->name[before].name = name; s->name[before].handle = handle; s->name_count ++; }
//拷贝字符串 char * server_strdup(const char *str) { size_t sz = strlen(str); char * ret = server_malloc(sz+1); memcpy(ret, str, sz+1); return ret; }
//初始化handle管理 void server_handle_init(int harbor) { assert(H==NULL); struct handle_storage * s = server_malloc(sizeof(*H)); s->slot_size = DEFAULT_SLOT_SIZE; s->slot = server_malloc(s->slot_size * sizeof(struct server_context *)); memset(s->slot, 0, s->slot_size * sizeof(struct server_context *)); rwlock_init(&s->lock); s->harbor = (uint32_t) (harbor & 0xff) << HANDLE_REMOTE_SHIFT; s->handle_index = 1; s->name_cap = 2; s->name_count = 0; s->name = server_malloc(s->name_cap * sizeof(struct handle_name)); H = s; }
int snlua_init(struct snlua *l, struct server_context *ctx, const char * args) { int sz = strlen(args); char * tmp = server_malloc(sz); memcpy(tmp, args, sz); server_callback(ctx, l , _launch);//设置回调函数 const char * self = server_cmd_command(ctx, "REG", NULL); uint32_t handle_id = strtoul(self+1, NULL, 16); server_send(ctx, 0, handle_id, PTYPE_TAG_DONTCOPY, 0, tmp, sz);//初始化完毕发送一条消息给自身,然后通过callback 回调到 _launch return 0; }
//注册ctx,将ctx存到handle_storage哈希表中,并得到一个handle uint32_t server_handle_register(struct server_context *ctx) { struct handle_storage *s = H; rwlock_wlock(&s->lock); for (;;) { int i; for (i=0;i<s->slot_size;i++) { uint32_t handle = (i+s->handle_index) & HANDLE_MASK;//高8位清0,保留低24位 int hash = handle & (s->slot_size-1);//保证handle不能大于slot_size,使得hash取值在[0, slot_size-1] if (s->slot[hash] == NULL) {//找到未使用的slot,将这个 ctx 放入这个 slot 中 s->slot[hash] = ctx; s->handle_index = handle + 1;//移动handle_index,方便下次使用 rwlock_wunlock(&s->lock); handle |= s->harbor;//高8位用于存放分布式id return handle; } } assert((s->slot_size*2 - 1) <= HANDLE_MASK);//确保 扩大2倍空间后 总共handle即 slot的数量不超过 24位的限制 //哈希表扩大2倍 struct server_context ** new_slot = server_malloc(s->slot_size * 2 * sizeof(struct server_context *)); memset(new_slot, 0, s->slot_size * 2 * sizeof(struct server_context *)); //将原来的数据拷贝到新的空间 for (i=0;i<s->slot_size;i++) { int hash = server_context_handle(s->slot[i]) & (s->slot_size * 2 - 1);//映射新的 hash 值 assert(new_slot[hash] == NULL); new_slot[hash] = s->slot[i]; } server_free(s->slot); s->slot = new_slot; s->slot_size *= 2; } }
inline static struct block * blk_alloc(void) { struct block *b = server_malloc(sizeof(struct block)); b->next = NULL; return b; }