OSDN Git Service

shared: Add proper IO disconnect handling when using epoll
authorMarcel Holtmann <marcel@holtmann.org>
Sun, 23 Mar 2014 19:37:55 +0000 (12:37 -0700)
committerMarcel Holtmann <marcel@holtmann.org>
Sun, 23 Mar 2014 19:37:55 +0000 (12:37 -0700)
src/shared/io-mainloop.c

index 2ea5eed..3e33d88 100644 (file)
@@ -92,12 +92,27 @@ static void io_callback(int fd, uint32_t events, void *user_data)
 {
        struct io *io = user_data;
 
-       if (events & (EPOLLERR | EPOLLHUP)) {
+       if ((events & (EPOLLRDHUP | EPOLLHUP | EPOLLERR))) {
                io->read_callback = NULL;
                io->write_callback = NULL;
 
-               mainloop_remove_fd(io->fd);
-               return;
+               if (!io->disconnect_callback) {
+                       mainloop_remove_fd(io->fd);
+                       return;
+               }
+
+               if (!io->disconnect_callback(io, io->disconnect_data)) {
+                       if (io->disconnect_destroy)
+                               io->disconnect_destroy(io->disconnect_data);
+
+                       io->disconnect_callback = NULL;
+                       io->disconnect_destroy = NULL;
+                       io->disconnect_data = NULL;
+
+                       io->events &= ~EPOLLRDHUP;
+
+                       mainloop_modify_fd(io->fd, io->events);
+               }
        }
 
        if ((events & EPOLLIN) && io->read_callback) {
@@ -129,21 +144,6 @@ static void io_callback(int fd, uint32_t events, void *user_data)
                        mainloop_modify_fd(io->fd, io->events);
                }
        }
-
-       if ((events & EPOLLRDHUP) && io->disconnect_callback) {
-               if (!io->disconnect_callback(io, io->disconnect_data)) {
-                       if (io->disconnect_destroy)
-                               io->disconnect_destroy(io->disconnect_data);
-
-                       io->disconnect_callback = NULL;
-                       io->disconnect_destroy = NULL;
-                       io->disconnect_data = NULL;
-
-                       io->events &= ~EPOLLRDHUP;
-
-                       mainloop_modify_fd(io->fd, io->events);
-               }
-       }
 }
 
 struct io *io_new(int fd)
@@ -175,10 +175,9 @@ void io_destroy(struct io *io)
        if (!io)
                return;
 
-       mainloop_remove_fd(io->fd);
-
        io->read_callback = NULL;
        io->write_callback = NULL;
+       io->disconnect_callback = NULL;
 
        mainloop_remove_fd(io->fd);