skynet--5--看看

#ifndef SKYNET_IMP_H
#define SKYNET_IMP_H
struct skynet_config {
    int thread;
    int harbor;
    const char * logger;
    const char * module_path;
    const char * master;
    const char * local;
    const char * start;
    const char * standalone;
};
void skynet_start(struct skynet_config * config);
#endif


不同的config,開啓不同的功能。。。


#ifndef SKYNET_H
#define SKYNET_H
#include <stddef.h>
#include <stdint.h>
#define PTYPE_TEXT 0
#define PTYPE_RESPONSE 1
#define PTYPE_MULTICAST 2
#define PTYPE_CLIENT 3
#define PTYPE_SYSTEM 4
#define PTYPE_HARBOR 5
#define PTYPE_SOCKET 6
// read lualib/skynet.lua lualib/simplemonitor.lua
#define PTYPE_RESERVED_ERROR 7 
// read lualib/skynet.lua lualib/mqueue.lua
#define PTYPE_RESERVED_QUEUE 8
#define PTYPE_RESERVED_DEBUG 9
#define PTYPE_RESERVED_LUA 10
#define PTYPE_TAG_DONTCOPY 0x10000
#define PTYPE_TAG_ALLOCSESSION 0x20000
struct skynet_context;
void skynet_error(struct skynet_context * context, const char *msg, ...);
const char * skynet_command(struct skynet_context * context, const char * cmd , const char * parm);
uint32_t skynet_queryname(struct skynet_context * context, const char * name);
int skynet_send(struct skynet_context * context, uint32_t source, uint32_t destination , int type, int session, void * msg, size_t sz);
int skynet_sendname(struct skynet_context * context, const char * destination , int type, int session, void * msg, size_t sz);
void skynet_forward(struct skynet_context *, uint32_t destination);
int skynet_isremote(struct skynet_context *, uint32_t handle, int * harbor);
typedef int (*skynet_cb)(struct skynet_context * context, void *ud, int type, int session, uint32_t source , const void * msg, size_t sz);
void skynet_callback(struct skynet_context * context, void *ud, skynet_cb cb);
#endif



這些個函數在哪裏實現的呢?

#include "skynet.h"
#include "skynet_handle.h"
#include "skynet_mq.h"
#include "skynet_server.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define LOG_MESSAGE_SIZE 256
void
skynet_error(struct skynet_context * context, const char *msg, ...) {
    static int logger = -1;
    if (logger < 0) {
        logger = skynet_handle_findname("logger");
    }
    if (logger < 0) {
        return;
    }
    char tmp[LOG_MESSAGE_SIZE];
    char *data = NULL;
    va_list ap;
    va_start(ap,msg);
    int len = vsnprintf(tmp, LOG_MESSAGE_SIZE, msg, ap);
    va_end(ap);
    if (len < LOG_MESSAGE_SIZE) {
        data = strdup(tmp);
    } else {
        int max_size = LOG_MESSAGE_SIZE;
        for (;;) {
            max_size *= 2;
            data = malloc(max_size);
            va_start(ap,msg);
            len = vsnprintf(data, max_size, msg, ap);
            va_end(ap);
            if (len < max_size) {
                break;
            }
            free(data);
        }
    }
    struct skynet_message smsg;
    if (context == NULL) {
        smsg.source = 0;
    } else {
        smsg.source = skynet_context_handle(context);
    }
    smsg.session = 0;
    smsg.data = data;
    smsg.sz = len | (PTYPE_TEXT << HANDLE_REMOTE_SHIFT);
    skynet_context_push(logger, &smsg);
}


#include "skynet.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
struct logger {
    FILE * handle;
    int close;
};
struct logger *
logger_create(void) {
    struct logger * inst = malloc(sizeof(*inst));
    inst->handle = NULL;
    inst->close = 0;
    return inst;
}
void
logger_release(struct logger * inst) {
    if (inst->close) {
        fclose(inst->handle);
    }
    free(inst);
}
static int
_logger(struct skynet_context * context, void *ud, int type, int session, uint32_t source, const void * msg, size_t sz) {
    struct logger * inst = ud;
    fprintf(inst->handle, "[:%x] ",source);
    fwrite(msg, sz , 1, inst->handle);
    fprintf(inst->handle, "\n");
    fflush(inst->handle);
    return 0;
}
int
logger_init(struct logger * inst, struct skynet_context *ctx, const char * parm) {
    if (parm) {
        inst->handle = fopen(parm,"w");
        if (inst->handle == NULL) {
            return 1;
        }
        inst->close = 1;
    } else {
        inst->handle = stdout;
    }
    if (inst->handle) {
        skynet_callback(ctx, inst, _logger);
        skynet_command(ctx, "REG", ".logger");
        return 0;
    }
    return 1;
}



好吧。我純屬貼代碼的。。。。第一遍純屬走馬觀花。。

#ifndef SKYNET_TIMER_H
#define SKYNET_TIMER_H
#include <stdint.h>
int skynet_timeout(uint32_t handle, int time, int session);
void skynet_updatetime(void);
uint32_t skynet_gettime(void);
uint32_t skynet_gettime_fixsec(void);
void skynet_timer_init(void);
#endif


#include "skynet_timer.h"
#include "skynet_mq.h"
#include "skynet_server.h"
#include "skynet_handle.h"
#include "skynet.h"
#include <time.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#if defined(__APPLE__)
#include <sys/time.h>
#endif
typedef void (*timer_execute_func)(void *ud,void *arg);
#define TIME_NEAR_SHIFT 8
#define TIME_NEAR (1 << TIME_NEAR_SHIFT)
#define TIME_LEVEL_SHIFT 6
#define TIME_LEVEL (1 << TIME_LEVEL_SHIFT)
#define TIME_NEAR_MASK (TIME_NEAR-1)
#define TIME_LEVEL_MASK (TIME_LEVEL-1)
struct timer_event {
    uint32_t handle;
    int session;
};
struct timer_node {
    struct timer_node *next;
    int expire;
};
struct link_list {
    struct timer_node head;
    struct timer_node *tail;
};
struct timer {
    struct link_list near[TIME_NEAR];
    struct link_list t[4][TIME_LEVEL-1];
    int lock;
    int time;
    uint32_t current;
    uint32_t starttime;
};
static struct timer * TI = NULL;
static inline struct timer_node *
link_clear(struct link_list *list)
{
    struct timer_node * ret = list->head.next;
    list->head.next = 0;
    list->tail = &(list->head);
    return ret;
}
static inline void
link(struct link_list *list,struct timer_node *node)
{
    list->tail->next = node;
    list->tail = node;
    node->next=0;
}
static void
add_node(struct timer *T,struct timer_node *node)
{
    int time=node->expire;
    int current_time=T->time;
                                       
    if ((time|TIME_NEAR_MASK)==(current_time|TIME_NEAR_MASK)) {
        link(&T->near[time&TIME_NEAR_MASK],node);
    }
    else {
        int i;
        int mask=TIME_NEAR << TIME_LEVEL_SHIFT;
        for (i=0;i<3;i++) {
            if ((time|(mask-1))==(current_time|(mask-1))) {
                break;
            }
            mask <<= TIME_LEVEL_SHIFT;
        }
        link(&T->t[i][((time>>(TIME_NEAR_SHIFT + i*TIME_LEVEL_SHIFT)) & TIME_LEVEL_MASK)-1],node);
    }
}
static void
timer_add(struct timer *T,void *arg,size_t sz,int time)
{
    struct timer_node *node = (struct timer_node *)malloc(sizeof(*node)+sz);
    memcpy(node+1,arg,sz);
    while (__sync_lock_test_and_set(&T->lock,1)) {};
        node->expire=time+T->time;
        add_node(T,node);
    __sync_lock_release(&T->lock);
}
static void
timer_execute(struct timer *T)
{
    while (__sync_lock_test_and_set(&T->lock,1)) {};
    int idx=T->time & TIME_NEAR_MASK;
    struct timer_node *current;
    int mask,i,time;
                                       
    while (T->near[idx].head.next) {
        current=link_clear(&T->near[idx]);
                                           
        do {
            struct timer_event * event = (struct timer_event *)(current+1);
            struct skynet_message message;
            message.source = 0;
            message.session = event->session;
            message.data = NULL;
            message.sz = PTYPE_RESPONSE << HANDLE_REMOTE_SHIFT;
            skynet_context_push(event->handle, &message);
                                               
            struct timer_node * temp = current;
            current=current->next;
            free(temp);
        } while (current);
    }
                                       
    ++T->time;
                                       
    mask = TIME_NEAR;
    time = T->time >> TIME_NEAR_SHIFT;
    i=0;
                                       
    while ((T->time & (mask-1))==0) {
        idx=time & TIME_LEVEL_MASK;
        if (idx!=0) {
            --idx;
            current=link_clear(&T->t[i][idx]);
            while (current) {
                struct timer_node *temp=current->next;
                add_node(T,current);
                current=temp;
            }
            break;             
        }
        mask <<= TIME_LEVEL_SHIFT;
        time >>= TIME_LEVEL_SHIFT;
        ++i;
    }  
    __sync_lock_release(&T->lock);
}
static struct timer *
timer_create_timer()
{
    struct timer *r=(struct timer *)malloc(sizeof(struct timer));
    memset(r,0,sizeof(*r));
    int i,j;
    for (i=0;i<TIME_NEAR;i++) {
        link_clear(&r->near[i]);
    }
    for (i=0;i<4;i++) {
        for (j=0;j<TIME_LEVEL-1;j++) {
            link_clear(&r->t[i][j]);
        }
    }
    r->lock = 0;
    r->current = 0;
    return r;
}
int
skynet_timeout(uint32_t handle, int time, int session) {
    if (time == 0) {
        struct skynet_message message;
        message.source = 0;
        message.session = session;
        message.data = NULL;
        message.sz = PTYPE_RESPONSE << HANDLE_REMOTE_SHIFT;
        if (skynet_context_push(handle, &message)) {
            return -1;
        }
    } else {
        struct timer_event event;
        event.handle = handle;
        event.session = session;
        timer_add(TI, &event, sizeof(event), time);
    }
    return session;
}
static uint32_t
_gettime(void) {
    uint32_t t;
#if !defined(__APPLE__)
    struct timespec ti;
    clock_gettime(CLOCK_MONOTONIC, &ti);
    t = (uint32_t)(ti.tv_sec & 0xffffff) * 100;
    t += ti.tv_nsec / 10000000;
#else
    struct timeval tv;
    gettimeofday(&tv, NULL);
    t = (uint32_t)(tv.tv_sec & 0xffffff) * 100;
    t += tv.tv_usec / 10000;
#endif
    return t;
}
void
skynet_updatetime(void) {
    uint32_t ct = _gettime();
    if (ct > TI->current) {
        int diff = ct-TI->current;
        TI->current = ct;
        int i;
        for (i=0;i<diff;i++) {
            timer_execute(TI);
        }
    }
}
uint32_t
skynet_gettime_fixsec(void) {
    return TI->starttime;
}
uint32_t
skynet_gettime(void) {
    return TI->current;
}
void
skynet_timer_init(void) {
    TI = timer_create_timer();
    TI->current = _gettime();
#if !defined(__APPLE__)
    struct timespec ti;
    clock_gettime(CLOCK_REALTIME, &ti);
    uint32_t sec = (uint32_t)ti.tv_sec;
#else
    struct timeval tv;
    gettimeofday(&tv, NULL);
    uint32_t sec = (uint32_t)tv.tv_sec;
#endif
    uint32_t mono = _gettime() / 100;
    TI->starttime = sec - mono;
}


貌似已經貼完代碼了。。。

這個文件夾全是基礎的內容。。


server-src纔是實際的server了。。

#ifndef skynet_databuffer_h
#define skynet_databuffer_h
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define MESSAGEPOOL 1023
struct message {
    char * buffer;
    int size;
    struct message * next;
};
struct databuffer {
    int header;
    int offset;
    int size;
    struct message * head;
    struct message * tail;
};
struct messagepool_list {
    struct messagepool_list *next;
    struct message pool[MESSAGEPOOL];
};
struct messagepool {
    struct messagepool_list * pool;
    struct message * freelist;
};
// use memset init struct
static void
messagepool_free(struct messagepool *pool) {
    struct messagepool_list *p = pool->pool;
    while(p) {
        struct messagepool_list *tmp = p;
        p=p->next;
        free(tmp);
    }
    pool->pool = NULL;
    pool->freelist = NULL;
}
static inline void
_return_message(struct databuffer *db, struct messagepool *mp) {
    struct message *m = db->head;
    if (m->next == NULL) {
        assert(db->tail == m);
        db->head = db->tail = NULL;
    } else {
        db->head = m->next;
    }
    free(m->buffer);
    m->buffer = NULL;
    m->size = 0;
    m->next = mp->freelist;
    mp->freelist = m;
}
static void
databuffer_read(struct databuffer *db, struct messagepool *mp, void * buffer, int sz) {
    assert(db->size >= sz);
    db->size -= sz;
    for (;;) {
        struct message *current = db->head;
        int bsz = current->size - db->offset;
        if (bsz > sz) {
            memcpy(buffer, current->buffer + db->offset, sz);
            db->offset += sz;
            return;
        }
        if (bsz == sz) {
            memcpy(buffer, current->buffer + db->offset, sz);
            db->offset = 0;
            _return_message(db, mp);
            return;
        } else {
            memcpy(buffer, current->buffer + db->offset, bsz);
            _return_message(db, mp);
            db->offset = 0;
            buffer+=bsz;
            sz-=bsz;
        }
    }
}
static void
databuffer_push(struct databuffer *db, struct messagepool *mp, void *data, int sz) {
    struct message * m;
    if (mp->freelist) {
        m = mp->freelist;
        mp->freelist = m->next;
    } else {
        struct messagepool_list * mpl = malloc(sizeof(*mpl));
        struct message * temp = mpl->pool;
        int i;
        for (i=1;i<MESSAGEPOOL;i++) {
            temp[i].buffer = NULL;
            temp[i].size = 0;
            temp[i].next = &temp[i+1];
        }
        temp[MESSAGEPOOL-1].next = NULL;
        mpl->next = mp->pool;
        mp->pool = mpl;
        m = &temp[0];
        mp->freelist = &temp[1];
    }
    m->buffer = data;
    m->size = sz;
    m->next = NULL;
    db->size += sz;
    if (db->head == NULL) {
        assert(db->tail == NULL);
        db->head = db->tail = m;
    } else {
        db->tail->next = m;
        db->tail = m;
    }
}
static int
databuffer_readheader(struct databuffer *db, struct messagepool *mp, int header_size) {
    if (db->header == 0) {
        // parser header (2 or 4)
        if (db->size < header_size) {
            return -1;
        }
        uint8_t plen[4];
        databuffer_read(db,mp,(char *)plen,header_size);
        // big-endian
        if (header_size == 2) {
            db->header = plen[0] << 8 | plen[1];
        } else {
            db->header = plen[0] << 24 | plen[1] << 16 | plen[2] << 8 | plen[3];
        }
    }
    if (db->size < db->header)
        return -1;
    return db->header;
}
static inline void
databuffer_reset(struct databuffer *db) {
    db->header = 0;
}
static void
databuffer_clear(struct databuffer *db, struct messagepool *mp) {
    while (db->head) {
        _return_message(db,mp);
    }
    memset(db, 0, sizeof(*db));
}
#endif



#ifndef skynet_hashid_h
#define skynet_hashid_h
#include <assert.h>
#include <stdlib.h>
#include <string.h>
struct hashid_node {
    int id;
    struct hashid_node *next;
};
struct hashid {
    int hashmod;
    int cap;
    int count;
    struct hashid_node *id;
    struct hashid_node **hash;
};
static void
hashid_init(struct hashid *hi, int max, int hashcap) {
    int i;
    assert((hashcap & (hashcap-1))==0);
    hi->cap = max;
    assert(hi->cap <= hashcap);
    hi->hashmod = hashcap - 1;
    hi->count = 0;
    hi->id = malloc(max * sizeof(struct hashid_node));
    for (i=0;i<max;i++) {
        hi->id[i].id = -1;
        hi->id[i].next = NULL;
    }
    hi->hash = malloc(hashcap * sizeof(struct hashid_node *));
    memset(hi->hash, 0, hashcap * sizeof(struct hashid_node *));
}
static void
hashid_clear(struct hashid *hi) {
    free(hi->id);
    free(hi->hash);
    hi->id = NULL;
    hi->hash = NULL;
    hi->hashmod = 1;
    hi->cap = 0;
    hi->count = 0;
}
static int
hashid_lookup(struct hashid *hi, int id) {
    int h = id & hi->hashmod;
    struct hashid_node * c = hi->hash[h];
    while(c) {
        if (c->id == id)
            return c - hi->id;
        c = c->next;
    }
    return -1;
}
static int
hashid_remove(struct hashid *hi, int id) {
    int h = id & hi->hashmod;
    struct hashid_node * c = hi->hash[h];
    if (c == NULL)
        return -1;
    if (c->id == id) {
        hi->hash[h] = c->next;
        goto _clear;
    }
    while(c->next) {
        if (c->next->id == id) {
            struct hashid_node * temp = c->next;
            c->next = temp->next;
            c = temp;
            goto _clear;
        }
        c = c->next;
    }
    return -1;
_clear:
    c->id = -1;
    c->next = NULL;
    --hi->count;
    return c - hi->id;
}
static int
hashid_insert(struct hashid * hi, int id) {
    struct hashid_node *c = NULL;
    int i;
    for (i=0;i<hi->cap;i++) {
        int index = (i+hi->count) % hi->cap;
        if (hi->id[index].id == -1) {
            c = &hi->id[index];
            break;
        }
    }
    assert(c);
    ++hi->count;
    c->id = id;
    assert(c->next == NULL);
    int h = id & hi->hashmod;
    if (hi->hash[h]) {
        c->next = hi->hash[h];
    }
    hi->hash[h] = c;
             
    return c - hi->id;
}
static inline int
hashid_full(struct hashid *hi) {
    return hi->count == hi->cap;
}
#endif



#ifndef SKYNET_LOCAL_CAST_H
#define SKYNET_LOCAL_CAST_H
#include <stdint.h>
struct localcast {
    int n;
    const uint32_t * group;
    void *msg;
    size_t sz;
};
#endif



好吧。代碼貼的差不多了。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章