test
1、./configure --prefix=/usr/curl-7.55 --disable-static --enable-threaded-resolver --enable-smtp --enable-pop3
2、make
3、make 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