Browse Source

Increase the robustness of hloop_free and hio_free

ithewei 1 year ago
parent
commit
a4e51af3ca
4 changed files with 20 additions and 11 deletions
  1. 2 1
      event/hevent.c
  2. 14 7
      event/hloop.c
  3. 2 1
      event/hloop.h
  4. 2 2
      event/nio.c

+ 2 - 1
event/hevent.c

@@ -191,7 +191,8 @@ void hio_done(hio_t* io) {
 }
 }
 
 
 void hio_free(hio_t* io) {
 void hio_free(hio_t* io) {
-    if (io == NULL) return;
+    if (io == NULL || io->destroy) return;
+    io->destroy = 1;
     hio_close(io);
     hio_close(io);
     hrecursive_mutex_destroy(&io->write_mutex);
     hrecursive_mutex_destroy(&io->write_mutex);
     HV_FREE(io->localaddr);
     HV_FREE(io->localaddr);

+ 14 - 7
event/hloop.c

@@ -417,15 +417,19 @@ hloop_t* hloop_new(int flags) {
     HV_ALLOC_SIZEOF(loop);
     HV_ALLOC_SIZEOF(loop);
     hloop_init(loop);
     hloop_init(loop);
     loop->flags |= flags;
     loop->flags |= flags;
+    hlogd("hloop_new tid=%ld", loop->tid);
     return loop;
     return loop;
 }
 }
 
 
 void hloop_free(hloop_t** pp) {
 void hloop_free(hloop_t** pp) {
-    if (pp && *pp) {
-        hloop_cleanup(*pp);
-        HV_FREE(*pp);
-        *pp = NULL;
-    }
+    if (pp == NULL || *pp == NULL) return;
+    hloop_t* loop = *pp;
+    if (loop->status == HLOOP_STATUS_DESTROY) return;
+    loop->status = HLOOP_STATUS_DESTROY;
+    hlogd("hloop_free tid=%ld", hv_gettid());
+    hloop_cleanup(loop);
+    HV_FREE(loop);
+    *pp = NULL;
 }
 }
 
 
 // while (loop->status) { hloop_process_events(loop); }
 // while (loop->status) { hloop_process_events(loop); }
@@ -436,6 +440,7 @@ int hloop_run(hloop_t* loop) {
     loop->status = HLOOP_STATUS_RUNNING;
     loop->status = HLOOP_STATUS_RUNNING;
     loop->pid = hv_getpid();
     loop->pid = hv_getpid();
     loop->tid = hv_gettid();
     loop->tid = hv_gettid();
+    hlogd("hloop_run tid=%ld", loop->tid);
 
 
     if (loop->intern_nevents == 0) {
     if (loop->intern_nevents == 0) {
         hmutex_lock(&loop->custom_events_mutex);
         hmutex_lock(&loop->custom_events_mutex);
@@ -471,8 +476,7 @@ int hloop_run(hloop_t* loop) {
     loop->end_hrtime = gethrtime_us();
     loop->end_hrtime = gethrtime_us();
 
 
     if (loop->flags & HLOOP_FLAG_AUTO_FREE) {
     if (loop->flags & HLOOP_FLAG_AUTO_FREE) {
-        hloop_cleanup(loop);
-        HV_FREE(loop);
+        hloop_free(&loop);
     }
     }
     return 0;
     return 0;
 }
 }
@@ -485,6 +489,9 @@ int hloop_wakeup(hloop_t* loop) {
 }
 }
 
 
 int hloop_stop(hloop_t* loop) {
 int hloop_stop(hloop_t* loop) {
+    if (loop == NULL) return -1;
+    if (loop->status == HLOOP_STATUS_STOP) return -2;
+    hlogd("hloop_stop tid=%ld", hv_gettid());
     if (hv_gettid() != loop->tid) {
     if (hv_gettid() != loop->tid) {
         hloop_wakeup(loop);
         hloop_wakeup(loop);
     }
     }

+ 2 - 1
event/hloop.h

@@ -31,7 +31,8 @@ typedef void (*hclose_cb)   (hio_t* io);
 typedef enum {
 typedef enum {
     HLOOP_STATUS_STOP,
     HLOOP_STATUS_STOP,
     HLOOP_STATUS_RUNNING,
     HLOOP_STATUS_RUNNING,
-    HLOOP_STATUS_PAUSE
+    HLOOP_STATUS_PAUSE,
+    HLOOP_STATUS_DESTROY
 } hloop_status_e;
 } hloop_status_e;
 
 
 typedef enum {
 typedef enum {

+ 2 - 2
event/nio.c

@@ -566,7 +566,7 @@ disconnect:
 
 
 int hio_close (hio_t* io) {
 int hio_close (hio_t* io) {
     if (io->closed) return 0;
     if (io->closed) return 0;
-    if (hv_gettid() != io->loop->tid) {
+    if (io->destroy == 0 && hv_gettid() != io->loop->tid) {
         return hio_close_async(io);
         return hio_close_async(io);
     }
     }
 
 
@@ -575,7 +575,7 @@ int hio_close (hio_t* io) {
         hrecursive_mutex_unlock(&io->write_mutex);
         hrecursive_mutex_unlock(&io->write_mutex);
         return 0;
         return 0;
     }
     }
-    if (!write_queue_empty(&io->write_queue) && io->error == 0 && io->close == 0) {
+    if (!write_queue_empty(&io->write_queue) && io->error == 0 && io->close == 0 && io->destroy == 0) {
         io->close = 1;
         io->close = 1;
         hrecursive_mutex_unlock(&io->write_mutex);
         hrecursive_mutex_unlock(&io->write_mutex);
         hlogw("write_queue not empty, close later.");
         hlogw("write_queue not empty, close later.");