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

}

 

原文地址:https://www.cnblogs.com/skiing886/p/7696455.html