Use _Atomic type for socket.sending and socket.udpconnecting. See #1317

This commit is contained in:
Cloud Wu
2021-01-11 16:57:25 +08:00
parent c0e3421462
commit 1ed4fdf94d
4 changed files with 13 additions and 11 deletions

View File

@@ -30,7 +30,7 @@ struct snlua {
size_t mem_report;
size_t mem_limit;
lua_State * activeL;
volatile ATOM_INT trap;
ATOM_INT trap;
};
// LUA_CACHELIB may defined in patched lua for shared proto

View File

@@ -1,12 +1,13 @@
#ifndef SKYNET_ATOMIC_H
#define SKYNET_ATOMIC_H
#ifdef NO_STDATOMIC
#ifdef __STDC_NO_ATOMICS__
#define ATOM_BYTE unsigned char
#define ATOM_INT int
#define ATOM_POINTER void *
#define ATOM_SIZET size_t
#define ATOM_ULONG unsigned long
#define ATOM_INIT(ptr, v) (*(ptr) = v)
#define ATOM_LOAD(ptr) (*(ptr))
#define ATOM_STORE(ptr, v) (*(ptr) = v)
@@ -26,6 +27,7 @@
#define ATOM_INT atomic_int
#define ATOM_POINTER atomic_uintptr_t
#define ATOM_SIZET atomic_size_t
#define ATOM_ULONG atomic_ulong
#define ATOM_INIT(ref, v) atomic_init(ref, v)
#define ATOM_LOAD(ptr) atomic_load(ptr)
#define ATOM_STORE(ptr, v) atomic_store(ptr, v)

View File

@@ -91,14 +91,14 @@ struct socket {
struct wb_list low;
int64_t wb_size;
struct socket_stat stat;
volatile uint32_t sending;
ATOM_ULONG sending;
int fd;
int id;
uint8_t protocol;
ATOM_BYTE type;
bool reading;
bool writing;
int udpconnecting;
ATOM_INT udpconnecting;
int64_t warn_size;
union {
int size;
@@ -356,7 +356,7 @@ reserve_id(struct socket_server *ss) {
s->protocol = PROTOCOL_UNKNOWN;
// socket_server_udp_connect may inc s->udpconncting directly (from other thread, before new_fd),
// so reset it to 0 here rather than in new_fd.
s->udpconnecting = 0;
ATOM_INIT(&s->udpconnecting, 0);
s->fd = -1;
return id;
} else {
@@ -564,7 +564,7 @@ new_fd(struct socket_server *ss, int id, int fd, int protocol, uintptr_t opaque,
s->fd = fd;
s->reading = true;
s->writing = false;
s->sending = ID_TAG16(id) << 16 | 0;
ATOM_INIT(&s->sending , ID_TAG16(id) << 16 | 0);
s->protocol = protocol;
s->p.size = MIN_READ_BUFFER;
s->opaque = opaque;
@@ -1060,7 +1060,7 @@ _failed:
static inline int
nomore_sending_data(struct socket *s) {
return send_buffer_empty(s) && s->dw_buffer == NULL && (s->sending & 0xffff) == 0;
return send_buffer_empty(s) && s->dw_buffer == NULL && (ATOM_LOAD(&s->sending) & 0xffff) == 0;
}
static int
@@ -1254,7 +1254,7 @@ inc_sending_ref(struct socket *s, int id) {
if (s->protocol != PROTOCOL_TCP)
return;
for (;;) {
uint32_t sending = s->sending;
unsigned long sending = ATOM_LOAD(&s->sending);
if ((sending >> 16) == ID_TAG16(id)) {
if ((sending & 0xffff) == 0xffff) {
// s->sending may overflow (rarely), so busy waiting here for socket thread dec it. see issue #794
@@ -1276,7 +1276,7 @@ dec_sending_ref(struct socket_server *ss, int id) {
struct socket * s = &ss->slot[HASH_ID(id)];
// Notice: udp may inc sending while type == SOCKET_TYPE_RESERVE
if (s->id == id && s->protocol == PROTOCOL_TCP) {
assert((s->sending & 0xffff) != 0);
assert((ATOM_LOAD(&s->sending) & 0xffff) != 0);
ATOM_FDEC(&s->sending);
}
}
@@ -1729,7 +1729,7 @@ socket_server_connect(struct socket_server *ss, uintptr_t opaque, const char * a
static inline int
can_direct_write(struct socket *s, int id) {
return s->id == id && nomore_sending_data(s) && ATOM_LOAD(&s->type) == SOCKET_TYPE_CONNECTED && s->udpconnecting == 0;
return s->id == id && nomore_sending_data(s) && ATOM_LOAD(&s->type) == SOCKET_TYPE_CONNECTED && ATOM_LOAD(&s->udpconnecting) == 0;
}
// return -1 when error, 0 when success

View File

@@ -8,7 +8,7 @@
#ifndef USE_PTHREAD_LOCK
#ifdef NO_STDATOMIC
#ifdef __STDC_NO_ATOMICS__
#define atomic_flag_ int
#define ATOMIC_FLAG_INIT_ 0