前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >skynet---3---看看

skynet---3---看看

作者头像
py3study
发布2020-01-06 11:27:36
7230
发布2020-01-06 11:27:36
举报
文章被收录于专栏:python3python3
代码语言: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]!='\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,模块。。。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-09-21 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档