Skip to content

Commit a69cd46

Browse files
author
ithewei
committed
fix: call hio_write in write_cb, iter maybe invalid
1 parent de856c8 commit a69cd46

File tree

2 files changed

+22
-12
lines changed

2 files changed

+22
-12
lines changed

event/hevent.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -184,10 +184,11 @@ struct hio_s {
184184
* hio lifeline:
185185
*
186186
* fd =>
187-
* hio_get => HV_ALLOC_SIZEOF(io) => hio_init =>
187+
* hio_get => HV_ALLOC_SIZEOF(io) => hio_init => hio_ready
188188
*
189-
* hio_ready => hio_add => hio_read_cb/hio_write_cb =>
190-
* hio_close => hio_done => hio_close_cb =>
189+
* hio_read => hio_add(HV_READ) => hio_read_cb
190+
* hio_write => hio_add(HV_WRITE) => hio_write_cb
191+
* hio_close => hio_done => hio_del(HV_RDWR) => hio_close_cb
191192
*
192193
* hloop_stop => hloop_free => hio_free => HV_FREE(io)
193194
*/

event/nio.c

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -313,14 +313,14 @@ static void nio_write(hio_t* io) {
313313
return;
314314
}
315315
offset_buf_t* pbuf = write_queue_front(&io->write_queue);
316-
char* buf = pbuf->base + pbuf->offset;
316+
char* base = pbuf->base;
317+
char* buf = base + pbuf->offset;
317318
int len = pbuf->len - pbuf->offset;
318319
nwrite = __nio_write(io, buf, len);
319320
// printd("write retval=%d\n", nwrite);
320321
if (nwrite < 0) {
321322
err = socket_errno();
322323
if (err == EAGAIN) {
323-
//goto write_done;
324324
hrecursive_mutex_unlock(&io->write_mutex);
325325
return;
326326
} else {
@@ -336,10 +336,14 @@ static void nio_write(hio_t* io) {
336336
io->write_bufsize -= nwrite;
337337
__write_cb(io, buf, nwrite);
338338
if (nwrite == len) {
339-
HV_FREE(pbuf->base);
339+
// NOTE: after write_cb, pbuf maybe invalid.
340+
// HV_FREE(pbuf->base);
341+
HV_FREE(base);
340342
write_queue_pop_front(&io->write_queue);
341-
// write next
342-
goto write;
343+
if (!io->closed) {
344+
// write continue
345+
goto write;
346+
}
343347
}
344348
hrecursive_mutex_unlock(&io->write_mutex);
345349
return;
@@ -488,10 +492,10 @@ int hio_write (hio_t* io, const void* buf, size_t len) {
488492
}
489493
}
490494
write_done:
495+
hrecursive_mutex_unlock(&io->write_mutex);
491496
if (nwrite > 0) {
492497
__write_cb(io, buf, nwrite);
493498
}
494-
hrecursive_mutex_unlock(&io->write_mutex);
495499
return nwrite;
496500
write_error:
497501
disconnect:
@@ -510,18 +514,24 @@ int hio_close (hio_t* io) {
510514
if (hv_gettid() != io->loop->tid) {
511515
return hio_close_async(io);
512516
}
517+
513518
hrecursive_mutex_lock(&io->write_mutex);
514-
if (!write_queue_empty(&io->write_queue) && io->error == 0 && io->close == 0) {
519+
if (io->closed) {
515520
hrecursive_mutex_unlock(&io->write_mutex);
521+
return 0;
522+
}
523+
if (!write_queue_empty(&io->write_queue) && io->error == 0 && io->close == 0) {
516524
io->close = 1;
525+
hrecursive_mutex_unlock(&io->write_mutex);
517526
hlogw("write_queue not empty, close later.");
518527
int timeout_ms = io->close_timeout ? io->close_timeout : HIO_DEFAULT_CLOSE_TIMEOUT;
519528
io->close_timer = htimer_add(io->loop, __close_timeout_cb, timeout_ms, 1);
520529
io->close_timer->privdata = io;
521530
return 0;
522531
}
523-
524532
io->closed = 1;
533+
hrecursive_mutex_unlock(&io->write_mutex);
534+
525535
hio_done(io);
526536
__close_cb(io);
527537
if (io->ssl) {
@@ -531,7 +541,6 @@ int hio_close (hio_t* io) {
531541
if (io->io_type & HIO_TYPE_SOCKET) {
532542
closesocket(io->fd);
533543
}
534-
hrecursive_mutex_unlock(&io->write_mutex);
535544
return 0;
536545
}
537546
#endif

0 commit comments

Comments
 (0)