• test


    1./configure --prefix=/usr/curl-7.55  --disable-static   --enable-threaded-resolver  --enable-smtp --enable-pop3

    2make 

    3make install

    以上安装版本为:curl-7.55.1

     

    #include "skynet.h"

    #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
    #define MAX_SLOT_SIZE 0x40000000

    struct handle_name
    {
        char * name;    //
    服务的字符串名称
        uint32_t handle;//
    服务的数字标识
    };

    struct handle_storage
    {
        struct rwlock lock;

        uint32_t harbor;//
    当前skynet节点编号
        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;
                    return handle;
                }
            }
            assert((s->slot_size*2 - 1) <= HANDLE_MASK);
            struct skynet_context ** new_slot = skynet_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];
            }
            skynet_free(s->slot);
            s->slot = new_slot;
            s->slot_size *= 2;
        }

    }

     

    int

    skynet_handle_retire(uint32_t handle) {

        int ret = 0;

        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) {

            s->slot[hash] = NULL;

            ret = 1;

            int i;

            int j=0, n=s->name_count;

            for (i=0; i<n; ++i) {

                if (s->name[i].handle == handle) {

                    skynet_free(s->name[i].name);

                    continue;

                } else if (i!=j) {

                    s->name[j] = s->name[i];

                }

                ++j;

            }

            s->name_count = j;

        } else {

            ctx = NULL;

        }

     

        rwlock_wunlock(&s->lock);

     

        if (ctx) {

            // release ctx may call skynet_handle_* , so wunlock first.

            skynet_context_release(ctx);

        }

     

        return ret;

    }

     

    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];

                uint32_t handle = 0;

                if (ctx)

                    handle = skynet_context_handle(ctx);

                rwlock_runlock(&s->lock);

                if (handle != 0) {

                    if (skynet_handle_retire(handle)) {

                        ++n;

                    }

                }

            }

            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;

            assert(s->name_cap <= MAX_SLOT_SIZE);

            struct handle_name * n = skynet_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];

            }

            skynet_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 = skynet_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 = skynet_malloc(sizeof(*H));

        s->slot_size = DEFAULT_SLOT_SIZE;

        s->slot = skynet_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 = skynet_malloc(s->name_cap * sizeof(struct handle_name));

     

        H = s;

     

        // Don't need to free H

    }

     

    #include "skynet.h"

    #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
    #define MAX_SLOT_SIZE 0x40000000

    struct handle_name
    {
        char * name;    //服务的字符串名称
        uint32_t handle;//服务的数字标识
    };

    struct handle_storage
    {
        struct rwlock lock;

        uint32_t harbor;//当前skynet节点编号
        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;
                    return handle;
                }
            }
            assert((s->slot_size*2 - 1) <= HANDLE_MASK);
            struct skynet_context ** new_slot = skynet_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];

            }

            skynet_free(s->slot);

            s->slot = new_slot;

            s->slot_size *= 2;

        }

    }

     

    int

    skynet_handle_retire(uint32_t handle) {

        int ret = 0;

        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) {

            s->slot[hash] = NULL;

            ret = 1;

            int i;

            int j=0, n=s->name_count;

            for (i=0; i<n; ++i) {

                if (s->name[i].handle == handle) {

                    skynet_free(s->name[i].name);

                    continue;

                } else if (i!=j) {

                    s->name[j] = s->name[i];

                }

                ++j;

            }

            s->name_count = j;

        } else {

            ctx = NULL;

        }

     

        rwlock_wunlock(&s->lock);

     

        if (ctx) {

            // release ctx may call skynet_handle_* , so wunlock first.

            skynet_context_release(ctx);

        }

     

        return ret;

    }

     

    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];

                uint32_t handle = 0;

                if (ctx)

                    handle = skynet_context_handle(ctx);

                rwlock_runlock(&s->lock);

                if (handle != 0) {

                    if (skynet_handle_retire(handle)) {

                        ++n;

                    }

                }

            }

            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;

            assert(s->name_cap <= MAX_SLOT_SIZE);

            struct handle_name * n = skynet_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];

            }

            skynet_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 = skynet_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 = skynet_malloc(sizeof(*H));

        s->slot_size = DEFAULT_SLOT_SIZE;

        s->slot = skynet_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 = skynet_malloc(s->name_cap * sizeof(struct handle_name));

     

        H = s;

     

        // Don't need to free H

    }

     

  • 相关阅读:
    react中实现滚动到指定位置固定显示导航栏,反之浸入背景
    activeElement解决ios滚动到底部显示内容时,键盘挡住显示内容的问题
    公积金无租房备案提取如何办理?(以成都为例)
    公积金状态封存怎么解封?
    你应该知道的公积金基础知识科普
    react antd表单不用form.create方法怎么设置input 回显值
    简述个人账户向公司账户转账的方法
    js拖拽进入和离开重复触发的问题
    Electron截屏功能
    Electron在mac下快捷键失效的问题及解决
  • 原文地址:https://www.cnblogs.com/skiing886/p/7696455.html
Copyright © 2020-2023  润新知