Skip to content

Commit 3c43a91

Browse files
author
ubuntu14
committed
fixed bugs in IO proccess of master_sig.c/master_status.c
1 parent 0dc19ab commit 3c43a91

File tree

3 files changed

+81
-43
lines changed

3 files changed

+81
-43
lines changed

lib_acl/src/master/framework/master_sig.c

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ int acl_master_sig_pipe[2];
5151
#define ACL_SIG_PIPE_READ_FD acl_master_sig_pipe[0]
5252
#endif
5353

54-
ACL_VSTREAM *ACL_SIG_PIPE_WRITE_STREAM = NULL;
5554
ACL_VSTREAM *ACL_SIG_PIPE_READ_STREAM = NULL;
5655

5756
int acl_var_master_gotsigchld = 0;
@@ -126,19 +125,29 @@ static void master_sigchld(int sig acl_unused)
126125
/* master_sig_event - called upon return from select() */
127126

128127
static void master_sig_event(int type acl_unused, ACL_EVENT *event acl_unused,
129-
ACL_VSTREAM *stream acl_unused, void *context acl_unused)
128+
ACL_VSTREAM *stream, void *context acl_unused)
130129
{
131130
char c[1];
132131

133-
#if 0
134-
while (read(ACL_SIG_PIPE_READ_FD, c, 1) > 0)
135-
/* void */ ;
136-
#else
137-
while (acl_vstream_read(stream, c, 1) > 0)
138-
{
139-
/* void */
132+
if (stream->rw_timeout > 0) {
133+
acl_msg_warn("%s:%d, pipe(%d)'s rw_timeout(%d) > 0",
134+
__FUNCTION__, __LINE__, ACL_VSTREAM_SOCK(stream),
135+
stream->rw_timeout);
136+
stream->rw_timeout = 0;
140137
}
141-
#endif
138+
139+
while (1) {
140+
if (acl_vstream_read(stream, c, 1) == ACL_VSTREAM_EOF) {
141+
if (acl_msg_verbose)
142+
acl_msg_info(">>>%s:%d: %s<<<", __FUNCTION__,
143+
__LINE__, acl_last_serror());
144+
break;
145+
} else if (acl_msg_verbose) {
146+
acl_msg_info(">>>%s:%d: %s, c: %d<<<", __FUNCTION__,
147+
__LINE__, acl_last_serror(), c[0]);
148+
}
149+
}
150+
142151
acl_var_master_gotsigchld = 1;
143152
}
144153

@@ -231,14 +240,18 @@ void acl_master_sigsetup(void)
231240
#ifdef USE_SIG_PIPE
232241
if (pipe(acl_master_sig_pipe))
233242
acl_msg_fatal("pipe: %s", strerror(errno));
243+
234244
acl_non_blocking(ACL_SIG_PIPE_WRITE_FD, ACL_NON_BLOCKING);
235245
acl_non_blocking(ACL_SIG_PIPE_READ_FD, ACL_NON_BLOCKING);
236246
acl_close_on_exec(ACL_SIG_PIPE_WRITE_FD, ACL_CLOSE_ON_EXEC);
237247
acl_close_on_exec(ACL_SIG_PIPE_READ_FD, ACL_CLOSE_ON_EXEC);
238248

249+
/* Must set io rw_timeout to 0 to avoiding blocking read which
250+
* will blocking the main event loop.
251+
*/
239252
ACL_SIG_PIPE_READ_STREAM = acl_vstream_fdopen(ACL_SIG_PIPE_READ_FD,
240-
O_RDONLY, acl_var_master_buf_size,
241-
acl_var_master_rw_timeout, ACL_VSTREAM_TYPE_SOCK);
253+
O_RDONLY, acl_var_master_buf_size, 0, ACL_VSTREAM_TYPE_SOCK);
254+
242255
if (ACL_SIG_PIPE_READ_STREAM == NULL)
243256
acl_msg_fatal("%s(%d)->%s: acl_vstream_fdopen error=%s",
244257
__FILE__, __LINE__, myname, strerror(errno));
@@ -247,6 +260,7 @@ void acl_master_sigsetup(void)
247260
acl_msg_info("%s(%d)->%s: call acl_event_enable_read, "
248261
"SIG_PIPE_READ_FD = %d", __FILE__, __LINE__, myname,
249262
ACL_SIG_PIPE_READ_FD);
263+
250264
acl_event_enable_read(acl_var_master_global_event,
251265
ACL_SIG_PIPE_READ_STREAM, 0, master_sig_event, (void *) 0);
252266
#endif

lib_acl/src/master/framework/master_status.c

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -46,22 +46,26 @@ static void master_status_event(int type, ACL_EVENT *event acl_unused,
4646
return;
4747

4848
/*
49-
* We always keep the child end of the status pipe open, so an EOF read
50-
* condition means that we're seriously confused. We use non-blocking
51-
* reads so that we don't get stuck when someone sends a partial message.
52-
* Messages are short, so a partial read means someone wrote less than a
53-
* whole status message. Hopefully the next read will be in sync again...
54-
* We use a global child process status table because when a child dies
55-
* only its pid is known - we do not know what service it came from.
49+
* We always keep the child end of the status pipe open, so an EOF
50+
* read condition means that we're seriously confused. We use
51+
* non-blocking reads so that we don't get stuck when someone sends
52+
* a partial message. Messages are short, so a partial read means
53+
* someone wrote less than a whole status message. Hopefully the next
54+
* read will be in sync again... We use a global child process status
55+
* table because when a child dies only its pid is known - we do not
56+
* know what service it came from.
5657
*/
5758

58-
#if 0
59-
n = read(ACL_VSTREAM_SOCK(serv->status_read_stream),
60-
(char *) &stat_buf, sizeof(stat_buf));
61-
#else
59+
if (serv->status_read_stream->rw_timeout > 0) {
60+
acl_msg_warn("%s:%d, pipe(%d)'s rw_timeout(%d) > 0",
61+
__FUNCTION__, __LINE__,
62+
ACL_VSTREAM_SOCK(serv->status_read_stream),
63+
serv->status_read_stream->rw_timeout);
64+
serv->status_read_stream->rw_timeout = 0;
65+
}
66+
6267
n = acl_vstream_read(serv->status_read_stream,
6368
(char *) &stat_buf, sizeof(stat_buf));
64-
#endif
6569

6670
switch (n) {
6771
case -1:
@@ -167,21 +171,24 @@ void acl_master_status_init(ACL_MASTER_SERV *serv)
167171
*/
168172
if (acl_duplex_pipe(serv->status_fd) < 0)
169173
acl_msg_fatal("pipe: %s", strerror(errno));
174+
170175
acl_non_blocking(serv->status_fd[0], ACL_BLOCKING);
171176
acl_close_on_exec(serv->status_fd[0], ACL_CLOSE_ON_EXEC);
172177
acl_close_on_exec(serv->status_fd[1], ACL_CLOSE_ON_EXEC);
178+
179+
/* Must set io rw_timeout to 0 to avoiding blocking read which
180+
* will blocking the main event loop.
181+
*/
173182
serv->status_read_stream = acl_vstream_fdopen(serv->status_fd[0],
174-
O_RDWR, acl_var_master_buf_size,
175-
acl_var_master_rw_timeout, ACL_VSTREAM_TYPE_SOCK);
183+
O_RDWR, acl_var_master_buf_size, 0, ACL_VSTREAM_TYPE_SOCK);
176184

177185
if (acl_msg_verbose)
178186
acl_msg_info("%s(%d)->%s: call acl_event_enable_read, "
179187
"status_fd = %d", __FILE__, __LINE__,
180188
myname, serv->status_fd[0]);
181189

182190
acl_event_enable_read(acl_var_master_global_event,
183-
serv->status_read_stream, 0, master_status_event,
184-
(void *) serv);
191+
serv->status_read_stream, 0, master_status_event, serv);
185192
}
186193

187194
/* acl_master_status_cleanup - stop status event processing for this service */

lib_acl/src/stdlib/iostuff/acl_read_wait.c

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ static void thread_epoll_init(void)
5757
int acl_read_wait(ACL_SOCKET fd, int timeout)
5858
{
5959
const char *myname = "acl_read_wait";
60-
int op = EPOLL_CTL_ADD, delay = timeout * 1000, *epoll_fd;
60+
int op = EPOLL_CTL_ADD, delay = timeout * 1000, *epoll_fd, ret;
6161
struct epoll_event ee, events[1];
6262

6363
acl_assert(acl_pthread_once(&epoll_once, thread_epoll_init) == 0);
@@ -78,16 +78,41 @@ int acl_read_wait(ACL_SOCKET fd, int timeout)
7878
ee.events = EPOLLIN | EPOLLHUP | EPOLLERR;
7979
ee.data.u64 = 0;
8080
ee.data.fd = fd;
81-
if (epoll_ctl(*epoll_fd, op, fd, &ee) == -1) {
81+
if (epoll_ctl(*epoll_fd, op, fd, &ee) == -1
82+
&& acl_last_error() != EEXIST)
83+
{
8284
acl_msg_error("%s(%d): epoll_ctl error: %s, fd: %d",
8385
myname, __LINE__, acl_last_serror(), fd);
8486
return -1;
8587
}
8688

87-
if (epoll_wait(*epoll_fd, events, 1, delay) == -1) {
88-
acl_msg_error("%s(%d): epoll_wait error: %s, fd: %d",
89-
myname, __LINE__, acl_last_serror(), fd);
90-
return -1;
89+
for (;;) {
90+
switch (epoll_wait(*epoll_fd, events, 1, delay)) {
91+
case -1:
92+
if (acl_last_error() == ACL_EINTR)
93+
{
94+
acl_msg_warn(">>>>catch EINTR, try again<<<");
95+
continue;
96+
}
97+
98+
acl_msg_error("%s(%d): epoll_wait error: %s, fd: %d",
99+
myname, __LINE__, acl_last_serror(), fd);
100+
ret = -1;
101+
break;
102+
case 0:
103+
acl_set_error(ACL_ETIMEDOUT);
104+
ret = -1;
105+
break;
106+
default:
107+
if ((events[0].events & (EPOLLERR | EPOLLHUP)) != 0)
108+
ret = -1;
109+
else if ((events[0].events & EPOLLIN) == 0) {
110+
acl_set_error(ACL_ETIMEDOUT);
111+
ret = -1;
112+
} else
113+
ret = 0;
114+
break;
115+
}
91116
}
92117

93118
ee.events = 0;
@@ -99,15 +124,7 @@ int acl_read_wait(ACL_SOCKET fd, int timeout)
99124
return -1;
100125
}
101126

102-
if ((events[0].events & (EPOLLERR | EPOLLHUP)) != 0)
103-
return -1;
104-
105-
if ((events[0].events & EPOLLIN) == 0) {
106-
acl_set_error(ACL_ETIMEDOUT);
107-
return -1;
108-
}
109-
110-
return 0;
127+
return ret;
111128
}
112129

113130
#elif defined(ACL_UNIX)

0 commit comments

Comments
 (0)