浏览代码

hloop_post_event

hewei 6 年之前
父节点
当前提交
7a7cb14529
共有 4 个文件被更改,包括 91 次插入7 次删除
  1. 5 0
      event/hevent.h
  2. 54 1
      event/hloop.c
  3. 17 4
      event/hloop.h
  4. 15 2
      examples/loop.c

+ 5 - 0
event/hevent.h

@@ -16,6 +16,7 @@ typedef enum {
 } hloop_status_e;
 
 ARRAY_DECL(hio_t*, io_array);
+QUEUE_DECL(hevent_t, event_queue);
 
 struct hloop_s {
     uint32_t    flags;
@@ -43,6 +44,10 @@ struct hloop_s {
     struct io_array             ios;
     uint32_t                    nios;
     void*                       iowatcher;
+    // custom_events
+    int                         sockpair[2];
+    char                        readbuf[4];
+    event_queue                 custom_events;
 };
 
 struct hidle_s {

+ 54 - 1
event/hloop.c

@@ -12,7 +12,8 @@
 #define PAUSE_TIME              10          // ms
 #define MAX_BLOCK_TIME          1000        // ms
 
-#define IO_ARRAY_INIT_SIZE      1024
+#define IO_ARRAY_INIT_SIZE              1024
+#define CUSTOM_EVENT_QUEUE_INIT_SIZE    16
 static void hio_init(hio_t* io);
 static void hio_ready(hio_t* io);
 static void hio_done(hio_t* io);
@@ -168,6 +169,9 @@ static void hloop_init(hloop_t* loop) {
     //io_array_init(&loop->ios, IO_ARRAY_INIT_SIZE);
     // iowatcher: init when iowatcher_add_event
     //iowatcher_init(loop);
+    // custom_events: init when hloop_post_event
+    //event_queue_init(&loop->custom_events, 4);
+    loop->sockpair[0] = loop->sockpair[1] = -1;
     // NOTE: init start_time here, because htimer_add use it.
     loop->start_ms = timestamp_ms();
     loop->start_hrtime = loop->cur_hrtime = gethrtime();
@@ -212,6 +216,13 @@ static void hloop_cleanup(hloop_t* loop) {
     io_array_cleanup(&loop->ios);
     // iowatcher
     iowatcher_cleanup(loop);
+    // custom_events
+    if (loop->sockpair[0] != -1 && loop->sockpair[1] != -1) {
+        closesocket(loop->sockpair[0]);
+        closesocket(loop->sockpair[1]);
+        loop->sockpair[0] = loop->sockpair[1] = -1;
+    }
+    event_queue_cleanup(&loop->custom_events);
 }
 
 hloop_t* hloop_new(int flags) {
@@ -703,3 +714,45 @@ hio_t* create_udp_client(hloop_t* loop, const char* host, int port) {
     return io;
 }
 
+static void sockpair_read_cb(hio_t* io, void* buf, int readbytes) {
+    hloop_t* loop = io->loop;
+    for (int i = 0; i < readbytes; ++i) {
+        if (event_queue_empty(&loop->custom_events)) {
+            return;
+        }
+        hevent_t* pev = event_queue_front(&loop->custom_events);
+        if (pev == NULL) {
+            return;
+        }
+        hevent_t ev = *pev;
+        event_queue_pop_front(&loop->custom_events);
+        if (ev.cb) {
+            ev.cb(&ev);
+        }
+    }
+}
+
+void hloop_post_event(hloop_t* loop, hevent_t* ev) {
+    if (loop->sockpair[0] <= 0 && loop->sockpair[1] <= 0) {
+        if (Socketpair(AF_INET, SOCK_STREAM, 0, loop->sockpair) != 0) {
+            hloge("socketpair error");
+            return;
+        }
+        hread(loop, loop->sockpair[1], loop->readbuf, sizeof(loop->readbuf), sockpair_read_cb);
+    }
+    if (loop->custom_events.maxsize == 0) {
+        event_queue_init(&loop->custom_events, CUSTOM_EVENT_QUEUE_INIT_SIZE);
+    }
+    if (ev->loop == NULL) {
+        ev->loop = loop;
+    }
+    if (ev->event_type == 0) {
+        ev->event_type = HEVENT_TYPE_CUSTOM;
+    }
+    if (ev->event_id == 0) {
+        ev->event_id = ++loop->event_counter;
+    }
+    event_queue_push_back(&loop->custom_events, ev);
+    char buf = '1';
+    hwrite(loop, loop->sockpair[0], &buf, 1, NULL);
+}

+ 17 - 4
event/hloop.h

@@ -27,11 +27,12 @@ typedef void (*hclose_cb)   (hio_t* io);
 
 typedef enum {
     HEVENT_TYPE_NONE    = 0,
-    HEVENT_TYPE_IDLE    = 0x00000010,
-    HEVENT_TYPE_TIMEOUT = 0x00000100,
-    HEVENT_TYPE_PERIOD  = 0x00000200,
+    HEVENT_TYPE_IO      = 0x00000001,
+    HEVENT_TYPE_TIMEOUT = 0x00000010,
+    HEVENT_TYPE_PERIOD  = 0x00000020,
     HEVENT_TYPE_TIMER   = HEVENT_TYPE_TIMEOUT|HEVENT_TYPE_PERIOD,
-    HEVENT_TYPE_IO      = 0x00001000,
+    HEVENT_TYPE_IDLE    = 0x00000100,
+    HEVENT_TYPE_CUSTOM  = 0x00000400, // 1024
 } hevent_type_e;
 
 #define HEVENT_LOWEST_PRIORITY    (-5)
@@ -103,9 +104,21 @@ uint64_t hloop_now(hloop_t* loop);          // s
 uint64_t hloop_now_ms(hloop_t* loop);       // ms
 uint64_t hloop_now_hrtime(hloop_t* loop);   // us
 
+// userdata
 void  hloop_set_userdata(hloop_t* loop, void* userdata);
 void* hloop_userdata(hloop_t* loop);
 
+// custom_event
+/*
+ * hevent_t ev;
+ * memset(&ev, 0, sizeof(hevent_t));
+ * ev.event_type = (hevent_type_e)(HEVENT_TYPE_CUSTOM + 1);
+ * ev.cb = custom_event_cb;
+ * ev.userdata = userdata;
+ * hloop_post_event(loop, &ev);
+ */
+void hloop_post_event(hloop_t* loop, hevent_t* ev);
+
 // idle
 hidle_t*    hidle_add(hloop_t* loop, hidle_cb cb, uint32_t repeat DEFAULT(INFINITE));
 void        hidle_del(hidle_t* idle);

+ 15 - 2
examples/loop.c

@@ -39,12 +39,16 @@ void timer_write_log(htimer_t* timer) {
 
 void on_stdin(hio_t* io, void* buf, int readbytes) {
     printf("on_stdin fd=%d readbytes=%d\n", hio_fd(io), readbytes);
-    printf("> %s\n", buf);
+    printf("> %s\n", (char*)buf);
     if (strncmp((char*)buf, "quit", 4) == 0) {
         hloop_stop(hevent_loop(io));
     }
 }
 
+void on_custom_events(hevent_t* ev) {
+    printf("on_custom_events event_type=%d userdata=%ld\n", (int)ev->event_type, (long)ev->userdata);
+}
+
 int main() {
     // memcheck atexit
     MEMCHECK;
@@ -60,7 +64,7 @@ int main() {
     // test timer timeout
     for (int i = 1; i <= 10; ++i) {
         htimer_t* timer = htimer_add(loop, on_timer, i*1000, 3);
-        hevent_set_userdata(timer, i);
+        hevent_set_userdata(timer, (void*)(long)i);
     }
 
     // test timer period
@@ -79,6 +83,15 @@ int main() {
     char buf[64];
     hread(loop, STDIN_FILENO, buf, sizeof(buf), on_stdin);
 
+    // test custom_events
+    for (int i = 0; i < 10; ++i) {
+        hevent_t ev;
+        ev.event_type = (hevent_type_e)(HEVENT_TYPE_CUSTOM + i);
+        ev.cb = on_custom_events;
+        ev.userdata = (void*)(long)i;
+        hloop_post_event(loop, &ev);
+    }
+
     hloop_run(loop);
     hloop_free(&loop);
     return 0;