mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-24 20:23:06 +00:00
enable write in socket thread
This commit is contained in:
@@ -4,6 +4,7 @@
|
|||||||
#include "socket_poll.h"
|
#include "socket_poll.h"
|
||||||
#include "atomic.h"
|
#include "atomic.h"
|
||||||
#include "spinlock.h"
|
#include "spinlock.h"
|
||||||
|
#include "skynet.h"
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
@@ -373,17 +374,17 @@ socket_server_create(uint64_t time) {
|
|||||||
int fd[2];
|
int fd[2];
|
||||||
poll_fd efd = sp_create();
|
poll_fd efd = sp_create();
|
||||||
if (sp_invalid(efd)) {
|
if (sp_invalid(efd)) {
|
||||||
fprintf(stderr, "socket-server: create event pool failed.\n");
|
skynet_error(NULL, "socket-server: create event pool failed.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (pipe(fd)) {
|
if (pipe(fd)) {
|
||||||
sp_release(efd);
|
sp_release(efd);
|
||||||
fprintf(stderr, "socket-server: create socket pair failed.\n");
|
skynet_error(NULL, "socket-server: create socket pair failed.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (sp_add(efd, fd[0], NULL)) {
|
if (sp_add(efd, fd[0], NULL)) {
|
||||||
// add recvctrl_fd to event poll
|
// add recvctrl_fd to event poll
|
||||||
fprintf(stderr, "socket-server: can't add server fd to event pool.\n");
|
skynet_error(NULL, "socket-server: can't add server fd to event pool.");
|
||||||
close(fd[0]);
|
close(fd[0]);
|
||||||
close(fd[1]);
|
close(fd[1]);
|
||||||
sp_release(efd);
|
sp_release(efd);
|
||||||
@@ -739,7 +740,7 @@ send_list_udp(struct socket_server *ss, struct socket *s, struct wb_list *list,
|
|||||||
union sockaddr_all sa;
|
union sockaddr_all sa;
|
||||||
socklen_t sasz = udp_socket_address(s, tmp->udp_address, &sa);
|
socklen_t sasz = udp_socket_address(s, tmp->udp_address, &sa);
|
||||||
if (sasz == 0) {
|
if (sasz == 0) {
|
||||||
fprintf(stderr, "socket-server : udp (%d) type mismatch.\n", s->id);
|
skynet_error(NULL, "socket-server : udp (%d) type mismatch.", s->id);
|
||||||
drop_udp(ss, s, list, tmp);
|
drop_udp(ss, s, list, tmp);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -750,7 +751,7 @@ send_list_udp(struct socket_server *ss, struct socket *s, struct wb_list *list,
|
|||||||
case AGAIN_WOULDBLOCK:
|
case AGAIN_WOULDBLOCK:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
fprintf(stderr, "socket-server : udp (%d) sendto error %s.\n",s->id, strerror(errno));
|
skynet_error(NULL, "socket-server : udp (%d) sendto error %s.",s->id, strerror(errno));
|
||||||
drop_udp(ss, s, list, tmp);
|
drop_udp(ss, s, list, tmp);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -931,6 +932,21 @@ append_sendbuffer_low(struct socket_server *ss,struct socket *s, struct request_
|
|||||||
s->wb_size += buf->sz;
|
s->wb_size += buf->sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
trigger_write(struct socket_server *ss, struct request_send * request, struct socket_message *result) {
|
||||||
|
int id = request->id;
|
||||||
|
struct socket * s = &ss->slot[HASH_ID(id)];
|
||||||
|
if (s->type == SOCKET_TYPE_INVALID || s->id != id)
|
||||||
|
return -1;
|
||||||
|
if (enable_write(ss, s, true)) {
|
||||||
|
result->opaque = s->opaque;
|
||||||
|
result->id = s->id;
|
||||||
|
result->ud = 0;
|
||||||
|
result->data = "enable write failed";
|
||||||
|
return SOCKET_ERR;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
When send a package , we can assign the priority : PRIORITY_HIGH or PRIORITY_LOW
|
When send a package , we can assign the priority : PRIORITY_HIGH or PRIORITY_LOW
|
||||||
@@ -952,7 +968,7 @@ send_socket(struct socket_server *ss, struct request_send * request, struct sock
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (s->type == SOCKET_TYPE_PLISTEN || s->type == SOCKET_TYPE_LISTEN) {
|
if (s->type == SOCKET_TYPE_PLISTEN || s->type == SOCKET_TYPE_LISTEN) {
|
||||||
fprintf(stderr, "socket-server: write to listen fd %d.\n", id);
|
skynet_error(NULL, "socket-server: write to listen fd %d.", id);
|
||||||
so.free_func((void *)request->buffer);
|
so.free_func((void *)request->buffer);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -968,7 +984,7 @@ send_socket(struct socket_server *ss, struct request_send * request, struct sock
|
|||||||
socklen_t sasz = udp_socket_address(s, udp_address, &sa);
|
socklen_t sasz = udp_socket_address(s, udp_address, &sa);
|
||||||
if (sasz == 0) {
|
if (sasz == 0) {
|
||||||
// udp type mismatch, just drop it.
|
// udp type mismatch, just drop it.
|
||||||
fprintf(stderr, "socket-server: udp socket (%d) type mistach.\n", id);
|
skynet_error(NULL, "socket-server: udp socket (%d) type mistach.", id);
|
||||||
so.free_func((void *)request->buffer);
|
so.free_func((void *)request->buffer);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -1154,7 +1170,7 @@ block_readpipe(int pipefd, void *buffer, int sz) {
|
|||||||
if (n<0) {
|
if (n<0) {
|
||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
continue;
|
continue;
|
||||||
fprintf(stderr, "socket-server : read pipe error %s.\n",strerror(errno));
|
skynet_error(NULL, "socket-server : read pipe error %s.",strerror(errno));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// must atomic read from a pipe
|
// must atomic read from a pipe
|
||||||
@@ -1285,6 +1301,8 @@ ctrl_cmd(struct socket_server *ss, struct socket_message *result) {
|
|||||||
result->ud = 0;
|
result->ud = 0;
|
||||||
result->data = NULL;
|
result->data = NULL;
|
||||||
return SOCKET_EXIT;
|
return SOCKET_EXIT;
|
||||||
|
case 'W':
|
||||||
|
return trigger_write(ss, (struct request_send *)buffer, result);
|
||||||
case 'D':
|
case 'D':
|
||||||
case 'P': {
|
case 'P': {
|
||||||
int priority = (type == 'D') ? PRIORITY_HIGH : PRIORITY_LOW;
|
int priority = (type == 'D') ? PRIORITY_HIGH : PRIORITY_LOW;
|
||||||
@@ -1306,7 +1324,7 @@ ctrl_cmd(struct socket_server *ss, struct socket_message *result) {
|
|||||||
add_udp_socket(ss, (struct request_udp *)buffer);
|
add_udp_socket(ss, (struct request_udp *)buffer);
|
||||||
return -1;
|
return -1;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "socket-server: Unknown ctrl %c.\n",type);
|
skynet_error(NULL, "socket-server: Unknown ctrl %c.",type);
|
||||||
return -1;
|
return -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1325,7 +1343,7 @@ forward_message_tcp(struct socket_server *ss, struct socket *s, struct socket_lo
|
|||||||
case EINTR:
|
case EINTR:
|
||||||
break;
|
break;
|
||||||
case AGAIN_WOULDBLOCK:
|
case AGAIN_WOULDBLOCK:
|
||||||
fprintf(stderr, "socket-server: EAGAIN capture.\n");
|
skynet_error(NULL, "socket-server: EAGAIN capture.");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// close when error
|
// close when error
|
||||||
@@ -1590,7 +1608,7 @@ socket_server_poll(struct socket_server *ss, struct socket_message * result, int
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SOCKET_TYPE_INVALID:
|
case SOCKET_TYPE_INVALID:
|
||||||
fprintf(stderr, "socket-server: invalid socket\n");
|
skynet_error(NULL, "socket-server: invalid socket");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (e->read) {
|
if (e->read) {
|
||||||
@@ -1654,7 +1672,7 @@ send_request(struct socket_server *ss, struct request_package *request, char typ
|
|||||||
ssize_t n = write(ss->sendctrl_fd, &request->header[6], len+2);
|
ssize_t n = write(ss->sendctrl_fd, &request->header[6], len+2);
|
||||||
if (n<0) {
|
if (n<0) {
|
||||||
if (errno != EINTR) {
|
if (errno != EINTR) {
|
||||||
fprintf(stderr, "socket-server : send ctrl command error %s.\n", strerror(errno));
|
skynet_error(NULL, "socket-server : send ctrl command error %s.", strerror(errno));
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1667,7 +1685,7 @@ static int
|
|||||||
open_request(struct socket_server *ss, struct request_package *req, uintptr_t opaque, const char *addr, int port) {
|
open_request(struct socket_server *ss, struct request_package *req, uintptr_t opaque, const char *addr, int port) {
|
||||||
int len = strlen(addr);
|
int len = strlen(addr);
|
||||||
if (len + sizeof(req->u.open) >= 256) {
|
if (len + sizeof(req->u.open) >= 256) {
|
||||||
fprintf(stderr, "socket-server : Invalid addr %s.\n",addr);
|
skynet_error(NULL, "socket-server : Invalid addr %s.",addr);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int id = reserve_id(ss);
|
int id = reserve_id(ss);
|
||||||
@@ -1723,7 +1741,7 @@ socket_server_send(struct socket_server *ss, struct socket_sendbuffer *buf) {
|
|||||||
union sockaddr_all sa;
|
union sockaddr_all sa;
|
||||||
socklen_t sasz = udp_socket_address(s, s->p.udp_address, &sa);
|
socklen_t sasz = udp_socket_address(s, s->p.udp_address, &sa);
|
||||||
if (sasz == 0) {
|
if (sasz == 0) {
|
||||||
fprintf(stderr, "socket-server : set udp (%d) address first.\n", id);
|
skynet_error(NULL, "socket-server : set udp (%d) address first.", id);
|
||||||
socket_unlock(&l);
|
socket_unlock(&l);
|
||||||
so.free_func((void *)buf->buffer);
|
so.free_func((void *)buf->buffer);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1745,14 +1763,18 @@ socket_server_send(struct socket_server *ss, struct socket_sendbuffer *buf) {
|
|||||||
s->dw_buffer = clone_buffer(buf, &s->dw_size);
|
s->dw_buffer = clone_buffer(buf, &s->dw_size);
|
||||||
s->dw_offset = n;
|
s->dw_offset = n;
|
||||||
|
|
||||||
int err = enable_write(ss, s, true);
|
|
||||||
|
|
||||||
socket_unlock(&l);
|
socket_unlock(&l);
|
||||||
|
|
||||||
if (err) {
|
inc_sending_ref(s, id);
|
||||||
fprintf(stderr, "socket-server : enable write (%d) failed.\n", id);
|
|
||||||
return -1;
|
struct request_package request;
|
||||||
}
|
request.u.send.id = id;
|
||||||
|
request.u.send.sz = 0;
|
||||||
|
request.u.send.buffer = NULL;
|
||||||
|
|
||||||
|
// let socket thread enable write event
|
||||||
|
send_request(ss, &request, 'W', sizeof(request.u.send));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
socket_unlock(&l);
|
socket_unlock(&l);
|
||||||
|
|||||||
Reference in New Issue
Block a user