发布时间:2019-09-21 10:47:35编辑:auto阅读(1375)
#ifndef SKYNET_HARBOR_H #define SKYNET_HARBOR_H #include <stdint.h> #include <stdlib.h> #define GLOBALNAME_LENGTH 16 #define REMOTE_MAX 256 // reserve high 8 bits for remote id #define HANDLE_MASK 0xffffff #define HANDLE_REMOTE_SHIFT 24 struct remote_name { char name[GLOBALNAME_LENGTH]; uint32_t handle; }; struct remote_message { struct remote_name destination; const void * message; size_t sz; }; void skynet_harbor_send(struct remote_message *rmsg, uint32_t source, int session); void skynet_harbor_register(struct remote_name *rname); int skynet_harbor_message_isremote(uint32_t handle); void skynet_harbor_init(int harbor); int skynet_harbor_start(const char * master, const char *local); #endif
harbor----港口。。。干嘛的。。。待解。。
#include "skynet.h" #include "skynet_harbor.h" #include "skynet_server.h" #include <string.h> #include <stdio.h> #include <assert.h> static struct skynet_context * REMOTE = 0; static unsigned int HARBOR = 0; void skynet_harbor_send(struct remote_message *rmsg, uint32_t source, int session) { int type = rmsg->sz >> HANDLE_REMOTE_SHIFT; rmsg->sz &= HANDLE_MASK; assert(type != PTYPE_SYSTEM && type != PTYPE_HARBOR); skynet_context_send(REMOTE, rmsg, sizeof(*rmsg) , source, type , session); } void skynet_harbor_register(struct remote_name *rname) { int i; int number = 1; for (i=0;i<GLOBALNAME_LENGTH;i++) { char c = rname->name[i]; if (!(c >= '0' && c <='9')) { number = 0; break; } } assert(number == 0); skynet_context_send(REMOTE, rname, sizeof(*rname), 0, PTYPE_SYSTEM , 0); } int skynet_harbor_message_isremote(uint32_t handle) { int h = (handle & ~HANDLE_MASK); return h != HARBOR && h !=0; } void skynet_harbor_init(int harbor) { HARBOR = (unsigned int)harbor << HANDLE_REMOTE_SHIFT; } int skynet_harbor_start(const char * master, const char *local) { size_t sz = strlen(master) + strlen(local) + 32; char args[sz]; sprintf(args, "%s %s %d",master,local,HARBOR >> HANDLE_REMOTE_SHIFT); struct skynet_context * inst = skynet_context_new("harbor",args); if (inst == NULL) { return 1; } REMOTE = inst; return 0; }
skynet_context都是用这个结构,来交互。。
#ifndef SKYNET_CONTEXT_HANDLE_H #define SKYNET_CONTEXT_HANDLE_H #include <stdint.h> #include "skynet_harbor.h" struct skynet_context; uint32_t skynet_handle_register(struct skynet_context *); void skynet_handle_retire(uint32_t handle); struct skynet_context * skynet_handle_grab(uint32_t handle); void skynet_handle_retireall(); uint32_t skynet_handle_findname(const char * name); const char * skynet_handle_namehandle(uint32_t handle, const char *name); void skynet_handle_init(int harbor); #endif
哎。。要是有个说明多好。。。刚开始不入门看着真空虚啊。
#include "skynet_handle.h" #include "skynet_server.h" #include "rwlock.h" #include <stdlib.h> #include <assert.h> #include <string.h> #define DEFAULT_SLOT_SIZE 4 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; int name_cap; int name_count; struct handle_name *name; }; static struct handle_storage *H = NULL; uint32_t skynet_handle_register(struct skynet_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; int hash = handle & (s->slot_size-1); if (s->slot[hash] == NULL) { s->slot[hash] = ctx; s->handle_index = handle + 1; rwlock_wunlock(&s->lock); handle |= s->harbor; skynet_context_init(ctx, handle); return handle; } } assert((s->slot_size*2 - 1) <= HANDLE_MASK); struct skynet_context ** new_slot = malloc(s->slot_size * 2 * sizeof(struct skynet_context *)); memset(new_slot, 0, s->slot_size * 2 * sizeof(struct skynet_context *)); for (i=0;i<s->slot_size;i++) { int hash = skynet_context_handle(s->slot[i]) & (s->slot_size * 2 - 1); assert(new_slot[hash] == NULL); new_slot[hash] = s->slot[i]; } free(s->slot); s->slot = new_slot; s->slot_size *= 2; } } void skynet_handle_retire(uint32_t handle) { struct handle_storage *s = H; rwlock_wlock(&s->lock); uint32_t hash = handle & (s->slot_size-1); struct skynet_context * ctx = s->slot[hash]; if (ctx != NULL && skynet_context_handle(ctx) == handle) { skynet_context_release(ctx); s->slot[hash] = NULL; int i; int j=0, n=s->name_count; for (i=0; i<n; ++i) { if (s->name[i].handle == handle) { free(s->name[i].name); continue; } else if (i!=j) { s->name[j] = s->name[i]; } ++j; } s->name_count = j; } rwlock_wunlock(&s->lock); } void skynet_handle_retireall() { struct handle_storage *s = H; for (;;) { int n=0; int i; for (i=0;i<s->slot_size;i++) { rwlock_rlock(&s->lock); struct skynet_context * ctx = s->slot[i]; rwlock_runlock(&s->lock); if (ctx != NULL) { ++n; skynet_handle_retire(skynet_context_handle(ctx)); } } if (n==0) return; } } struct skynet_context * skynet_handle_grab(uint32_t handle) { struct handle_storage *s = H; struct skynet_context * result = NULL; rwlock_rlock(&s->lock); uint32_t hash = handle & (s->slot_size-1); struct skynet_context * ctx = s->slot[hash]; if (ctx && skynet_context_handle(ctx) == handle) { result = ctx; skynet_context_grab(result); } rwlock_runlock(&s->lock); return result; } uint32_t skynet_handle_findname(const char * name) { struct handle_storage *s = H; rwlock_rlock(&s->lock); uint32_t handle = 0; int begin = 0; int end = s->name_count - 1; while (begin<=end) { int mid = (begin+end)/2; struct handle_name *n = &s->name[mid]; int c = strcmp(n->name, name); if (c==0) { handle = n->handle; break; } if (c<0) { begin = mid + 1; } else { end = mid - 1; } } rwlock_runlock(&s->lock); return handle; } 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; struct handle_name * n = 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]; } 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 ++; } static const char * _insert_name(struct handle_storage *s, const char * name, uint32_t handle) { int begin = 0; int end = s->name_count - 1; while (begin<=end) { int mid = (begin+end)/2; struct handle_name *n = &s->name[mid]; int c = strcmp(n->name, name); if (c==0) { return NULL; } if (c<0) { begin = mid + 1; } else { end = mid - 1; } } char * result = strdup(name); _insert_name_before(s, result, handle, begin); return result; } const char * skynet_handle_namehandle(uint32_t handle, const char *name) { rwlock_wlock(&H->lock); const char * ret = _insert_name(H, name, handle); rwlock_wunlock(&H->lock); return ret; } void skynet_handle_init(int harbor) { assert(H==NULL); struct handle_storage * s = malloc(sizeof(*H)); s->slot_size = DEFAULT_SLOT_SIZE; s->slot = malloc(s->slot_size * sizeof(struct skynet_context *)); memset(s->slot, 0, s->slot_size * sizeof(struct skynet_context *)); rwlock_init(&s->lock); // reserve 0 for system s->harbor = (uint32_t) (harbor & 0xff) << HANDLE_REMOTE_SHIFT; s->handle_index = 1; s->name_cap = 2; s->name_count = 0; s->name = malloc(s->name_cap * sizeof(struct handle_name)); H = s; // Don't need to free H }
貌似是把handle,name和context对应起来。。。好吧。我没耐心了。。
#ifndef SKYNET_MODULE_H #define SKYNET_MODULE_H struct skynet_context; typedef void * (*skynet_dl_create)(void); typedef int (*skynet_dl_init)(void * inst, struct skynet_context *, const char * parm); typedef void (*skynet_dl_release)(void * inst); struct skynet_module { const char * name; void * module; skynet_dl_create create; skynet_dl_init init; skynet_dl_release release; }; void skynet_module_insert(struct skynet_module *mod); struct skynet_module * skynet_module_query(const char * name); void * skynet_module_instance_create(struct skynet_module *); int skynet_module_instance_init(struct skynet_module *, void * inst, struct skynet_context *ctx, const char * parm); void skynet_module_instance_release(struct skynet_module *, void *inst); void skynet_module_init(const char *path); #endif
这么抽象的东西。。。模块。。。可以自己实现。。。?
#include "skynet_module.h" #include <assert.h> #include <string.h> #include <dlfcn.h>//这个好陌生。。。dll相关函数:dlopen-打开动态链接库 #include <stdlib.h> #include <stdint.h> #include <stdio.h> #define MAX_MODULE_TYPE 32 struct modules { int count; int lock; const char * path; struct skynet_module m[MAX_MODULE_TYPE]; }; static struct modules * M = NULL; static void * _try_open(struct modules *m, const char * name) { const char * path = m->path; size_t path_size = strlen(path); size_t name_size = strlen(name); int sz = path_size + name_size; char tmp[sz]; int i; for (i=0;path[i]!='?' && path[i]!='\0';i++) { tmp[i] = path[i]; } memcpy(tmp+i,name,name_size); if (path[i] == '?') { strcpy(tmp+i+name_size,path+i+1); } else { fprintf(stderr,"Invalid C service path\n"); exit(1); } void * dl = dlopen(tmp, RTLD_NOW | RTLD_GLOBAL); if (dl == NULL) { fprintf(stderr, "try open %s failed : %s\n",tmp,dlerror()); } return dl; } static struct skynet_module * _query(const char * name) { int i; for (i=0;i<M->count;i++) { if (strcmp(M->m[i].name,name)==0) { return &M->m[i]; } } return NULL; } static int _open_sym(struct skynet_module *mod) { size_t name_size = strlen(mod->name); char tmp[name_size + 9]; // create/init/release , longest name is release (7) memcpy(tmp, mod->name, name_size); strcpy(tmp+name_size, "_create"); mod->create = dlsym(mod->module, tmp); strcpy(tmp+name_size, "_init"); mod->init = dlsym(mod->module, tmp); strcpy(tmp+name_size, "_release"); mod->release = dlsym(mod->module, tmp); return mod->init == NULL; } struct skynet_module * skynet_module_query(const char * name) { struct skynet_module * result = _query(name); if (result) return result; while(__sync_lock_test_and_set(&M->lock,1)) {} result = _query(name); // double check if (result == NULL && M->count < MAX_MODULE_TYPE) { int index = M->count; void * dl = _try_open(M,name); if (dl) { M->m[index].name = name; M->m[index].module = dl; if (_open_sym(&M->m[index]) == 0) { M->m[index].name = strdup(name); M->count ++; result = &M->m[index]; } } } __sync_lock_release(&M->lock); return result; } void skynet_module_insert(struct skynet_module *mod) { while(__sync_lock_test_and_set(&M->lock,1)) {} struct skynet_module * m = _query(mod->name); assert(m == NULL && M->count < MAX_MODULE_TYPE); int index = M->count; M->m[index] = *mod; ++M->count; __sync_lock_release(&M->lock); } void * skynet_module_instance_create(struct skynet_module *m) { if (m->create) { return m->create(); } else { return (void *)(intptr_t)(~0); } } int skynet_module_instance_init(struct skynet_module *m, void * inst, struct skynet_context *ctx, const char * parm) { return m->init(inst, ctx, parm); } void skynet_module_instance_release(struct skynet_module *m, void *inst) { if (m->release) { m->release(inst); } } void skynet_module_init(const char *path) { struct modules *m = malloc(sizeof(*m)); m->count = 0; m->path = strdup(path); m->lock = 0; M = m; }
打开dll,模块。。。
上一篇: CentOS6.5 安装GNS3
下一篇: 使用virtualenv搭建独立的Pyt
47839
46383
37274
34725
29311
25968
24899
19946
19538
18019
5788°
6410°
5925°
5959°
7062°
5908°
5941°
6435°
6402°
7774°