代码语言:javascript复制
#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----港口。。。干嘛的。。。待解。。
代码语言:javascript复制#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都是用这个结构,来交互。。
代码语言:javascript复制#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
哎。。要是有个说明多好。。。刚开始不入门看着真空虚啊。
代码语言:javascript复制#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对应起来。。。好吧。我没耐心了。。
代码语言:javascript复制#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
这么抽象的东西。。。模块。。。可以自己实现。。。?
代码语言:javascript复制#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]!='