skynet---3---看看

发布时间: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,模块。。。

关键字