mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-24 12:20:41 +00:00
support user defined send object
This commit is contained in:
@@ -40,8 +40,9 @@
|
|||||||
struct write_buffer {
|
struct write_buffer {
|
||||||
struct write_buffer * next;
|
struct write_buffer * next;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
int sz;
|
|
||||||
void *buffer;
|
void *buffer;
|
||||||
|
int sz;
|
||||||
|
bool userobject;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wb_list {
|
struct wb_list {
|
||||||
@@ -68,6 +69,7 @@ struct socket_server {
|
|||||||
int alloc_id;
|
int alloc_id;
|
||||||
int event_n;
|
int event_n;
|
||||||
int event_index;
|
int event_index;
|
||||||
|
struct socket_object_interface soi;
|
||||||
struct event ev[MAX_EVENT];
|
struct event ev[MAX_EVENT];
|
||||||
struct socket slot[MAX_SOCKET];
|
struct socket slot[MAX_SOCKET];
|
||||||
char buffer[MAX_INFO];
|
char buffer[MAX_INFO];
|
||||||
@@ -137,9 +139,40 @@ union sockaddr_all {
|
|||||||
struct sockaddr_in6 v6;
|
struct sockaddr_in6 v6;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct send_object {
|
||||||
|
void * buffer;
|
||||||
|
int sz;
|
||||||
|
void (*free_func)(void *);
|
||||||
|
};
|
||||||
|
|
||||||
#define MALLOC skynet_malloc
|
#define MALLOC skynet_malloc
|
||||||
#define FREE skynet_free
|
#define FREE skynet_free
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
send_object_init(struct socket_server *ss, struct send_object *so, void *object, int sz) {
|
||||||
|
if (sz < 0) {
|
||||||
|
so->buffer = ss->soi.buffer(object);
|
||||||
|
so->sz = ss->soi.size(object);
|
||||||
|
so->free_func = ss->soi.free;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
so->buffer = object;
|
||||||
|
so->sz = sz;
|
||||||
|
so->free_func = FREE;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
write_buffer_free(struct socket_server *ss, struct write_buffer *wb) {
|
||||||
|
if (wb->userobject) {
|
||||||
|
ss->soi.free(wb->buffer);
|
||||||
|
} else {
|
||||||
|
FREE(wb->buffer);
|
||||||
|
}
|
||||||
|
FREE(wb);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
socket_keepalive(int fd) {
|
socket_keepalive(int fd) {
|
||||||
int keepalive = 1;
|
int keepalive = 1;
|
||||||
@@ -213,6 +246,7 @@ socket_server_create() {
|
|||||||
ss->alloc_id = 0;
|
ss->alloc_id = 0;
|
||||||
ss->event_n = 0;
|
ss->event_n = 0;
|
||||||
ss->event_index = 0;
|
ss->event_index = 0;
|
||||||
|
memset(&ss->soi, 0, sizeof(ss->soi));
|
||||||
FD_ZERO(&ss->rfds);
|
FD_ZERO(&ss->rfds);
|
||||||
assert(ss->recvctrl_fd < FD_SETSIZE);
|
assert(ss->recvctrl_fd < FD_SETSIZE);
|
||||||
|
|
||||||
@@ -220,13 +254,12 @@ socket_server_create() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_wb_list(struct wb_list *list) {
|
free_wb_list(struct socket_server *ss, struct wb_list *list) {
|
||||||
struct write_buffer *wb = list->head;
|
struct write_buffer *wb = list->head;
|
||||||
while (wb) {
|
while (wb) {
|
||||||
struct write_buffer *tmp = wb;
|
struct write_buffer *tmp = wb;
|
||||||
wb = wb->next;
|
wb = wb->next;
|
||||||
FREE(tmp->buffer);
|
write_buffer_free(ss, tmp);
|
||||||
FREE(tmp);
|
|
||||||
}
|
}
|
||||||
list->head = NULL;
|
list->head = NULL;
|
||||||
list->tail = NULL;
|
list->tail = NULL;
|
||||||
@@ -242,8 +275,8 @@ force_close(struct socket_server *ss, struct socket *s, struct socket_message *r
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
assert(s->type != SOCKET_TYPE_RESERVE);
|
assert(s->type != SOCKET_TYPE_RESERVE);
|
||||||
free_wb_list(&s->high);
|
free_wb_list(ss,&s->high);
|
||||||
free_wb_list(&s->low);
|
free_wb_list(ss,&s->low);
|
||||||
if (s->type != SOCKET_TYPE_PACCEPT && s->type != SOCKET_TYPE_PLISTEN) {
|
if (s->type != SOCKET_TYPE_PACCEPT && s->type != SOCKET_TYPE_PLISTEN) {
|
||||||
sp_del(ss->event_fd, s->fd);
|
sp_del(ss->event_fd, s->fd);
|
||||||
}
|
}
|
||||||
@@ -395,8 +428,7 @@ send_list(struct socket_server *ss, struct socket *s, struct wb_list *list, stru
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
list->head = tmp->next;
|
list->head = tmp->next;
|
||||||
FREE(tmp->buffer);
|
write_buffer_free(ss,tmp);
|
||||||
FREE(tmp);
|
|
||||||
}
|
}
|
||||||
list->tail = NULL;
|
list->tail = NULL;
|
||||||
|
|
||||||
@@ -469,10 +501,12 @@ send_buffer(struct socket_server *ss, struct socket *s, struct socket_message *r
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
append_sendbuffer_(struct wb_list *s, struct request_send * request, int n) {
|
append_sendbuffer_(struct socket_server *ss, struct wb_list *s, struct request_send * request, int n) {
|
||||||
struct write_buffer * buf = MALLOC(sizeof(*buf));
|
struct write_buffer * buf = MALLOC(sizeof(*buf));
|
||||||
buf->ptr = request->buffer+n;
|
struct send_object so;
|
||||||
buf->sz = request->sz - n;
|
buf->userobject = send_object_init(ss, &so, request->buffer, request->sz);
|
||||||
|
buf->ptr = so.buffer+n;
|
||||||
|
buf->sz = so.sz - n;
|
||||||
buf->buffer = request->buffer;
|
buf->buffer = request->buffer;
|
||||||
buf->next = NULL;
|
buf->next = NULL;
|
||||||
if (s->head == NULL) {
|
if (s->head == NULL) {
|
||||||
@@ -487,13 +521,13 @@ append_sendbuffer_(struct wb_list *s, struct request_send * request, int n) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
append_sendbuffer(struct socket *s, struct request_send * request, int n) {
|
append_sendbuffer(struct socket_server *ss, struct socket *s, struct request_send * request, int n) {
|
||||||
s->wb_size += append_sendbuffer_(&s->high, request, n);
|
s->wb_size += append_sendbuffer_(ss, &s->high, request, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
append_sendbuffer_low(struct socket *s, struct request_send * request) {
|
append_sendbuffer_low(struct socket_server *ss,struct socket *s, struct request_send * request) {
|
||||||
s->wb_size += append_sendbuffer_(&s->low, request, 0);
|
s->wb_size += append_sendbuffer_(ss, &s->low, request, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
@@ -512,15 +546,17 @@ static int
|
|||||||
send_socket(struct socket_server *ss, struct request_send * request, struct socket_message *result, int priority) {
|
send_socket(struct socket_server *ss, struct request_send * request, struct socket_message *result, int priority) {
|
||||||
int id = request->id;
|
int id = request->id;
|
||||||
struct socket * s = &ss->slot[HASH_ID(id)];
|
struct socket * s = &ss->slot[HASH_ID(id)];
|
||||||
|
struct send_object so;
|
||||||
|
send_object_init(ss, &so, request->buffer, request->sz);
|
||||||
if (s->type == SOCKET_TYPE_INVALID || s->id != id
|
if (s->type == SOCKET_TYPE_INVALID || s->id != id
|
||||||
|| s->type == SOCKET_TYPE_HALFCLOSE
|
|| s->type == SOCKET_TYPE_HALFCLOSE
|
||||||
|| s->type == SOCKET_TYPE_PACCEPT) {
|
|| s->type == SOCKET_TYPE_PACCEPT) {
|
||||||
FREE(request->buffer);
|
so.free_func(request->buffer);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
assert(s->type != SOCKET_TYPE_PLISTEN && s->type != SOCKET_TYPE_LISTEN);
|
assert(s->type != SOCKET_TYPE_PLISTEN && s->type != SOCKET_TYPE_LISTEN);
|
||||||
if (send_buffer_empty(s) && s->type == SOCKET_TYPE_CONNECTED) {
|
if (send_buffer_empty(s) && s->type == SOCKET_TYPE_CONNECTED) {
|
||||||
int n = write(s->fd, request->buffer, request->sz);
|
int n = write(s->fd, so.buffer, so.sz);
|
||||||
if (n<0) {
|
if (n<0) {
|
||||||
switch(errno) {
|
switch(errno) {
|
||||||
case EINTR:
|
case EINTR:
|
||||||
@@ -533,17 +569,17 @@ send_socket(struct socket_server *ss, struct request_send * request, struct sock
|
|||||||
return SOCKET_CLOSE;
|
return SOCKET_CLOSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (n == request->sz) {
|
if (n == so.sz) {
|
||||||
FREE(request->buffer);
|
so.free_func(request->buffer);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
append_sendbuffer(s, request, n); // add to high priority list, even priority == PRIORITY_LOW
|
append_sendbuffer(ss, s, request, n); // add to high priority list, even priority == PRIORITY_LOW
|
||||||
sp_write(ss->event_fd, s->fd, s, true);
|
sp_write(ss->event_fd, s->fd, s, true);
|
||||||
} else {
|
} else {
|
||||||
if (priority == PRIORITY_LOW) {
|
if (priority == PRIORITY_LOW) {
|
||||||
append_sendbuffer_low(s, request);
|
append_sendbuffer_low(ss, s, request);
|
||||||
} else {
|
} else {
|
||||||
append_sendbuffer(s, request, 0);
|
append_sendbuffer(ss, s, request, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1092,3 +1128,9 @@ socket_server_nodelay(struct socket_server *ss, int id) {
|
|||||||
request.u.setopt.value = 1;
|
request.u.setopt.value = 1;
|
||||||
send_request(ss, &request, 'T', sizeof(request.u.setopt));
|
send_request(ss, &request, 'T', sizeof(request.u.setopt));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
socket_server_userobject(struct socket_server *ss, struct socket_object_interface *soi) {
|
||||||
|
ss->soi = *soi;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,4 +38,13 @@ int socket_server_bind(struct socket_server *, uintptr_t opaque, int fd);
|
|||||||
|
|
||||||
void socket_server_nodelay(struct socket_server *, int id);
|
void socket_server_nodelay(struct socket_server *, int id);
|
||||||
|
|
||||||
|
struct socket_object_interface {
|
||||||
|
void * (*buffer)(void *);
|
||||||
|
int (*size)(void *);
|
||||||
|
void (*free)(void *);
|
||||||
|
};
|
||||||
|
|
||||||
|
// if you send package sz == -1, use soi.
|
||||||
|
void socket_server_userobject(struct socket_server *, struct socket_object_interface *soi);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user