]> jfr.im git - irc/rqf/shadowircd.git/blobdiff - libcharybdis/epoll.c
Remove silly a2client_p, entirely pointless since User.server removal.
[irc/rqf/shadowircd.git] / libcharybdis / epoll.c
index 5a30ef55bd4cc5c163cc86a6e355c779170370df..f06ced33b06fe8c60ae4a87b7d2bbd108bb00130 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  ircd-ratbox: A slightly useful ircd.
+ *  charybdis: A slightly useful ircd.
  *  epoll.c: Linux epoll compatible network routines.
  *
  *  Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
@@ -7,6 +7,7 @@
  *  Copyright (C) 2001 Adrian Chadd <adrian@creative.net.au>
  *  Copyright (C) 2002-2005 ircd-ratbox development team
  *  Copyright (C) 2002 Aaron Sethman <androsyn@ratbox.org>
+ *  Copyright (C) 2008 William Pitcock <nenolod@sacredspiral.co.uk>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -133,8 +134,6 @@ comm_setselect(int fd, fdlist_t list, unsigned int type, PF * handler,
                libcharybdis_log("comm_setselect(): epoll_ctl failed: %s", strerror(errno));
                abort();
        }
-
-
 }
 
 /*
@@ -178,12 +177,28 @@ comm_select(unsigned long delay)
                        }
                        else
                                libcharybdis_log("epoll.c: NULL read handler called");
-
                }
 
 
-               if(F->flags.open == 0)
+               if(F->flags.open == 0 && F->pflags == 0)
                        continue;
+               else if (F->flags.open == 0)
+               {
+                       F->pflags = ep_event.events = flags;
+                       ep_event.data.ptr = F;
+
+                       if(epoll_ctl(ep, EPOLL_CTL_DEL, F->fd, &ep_event) != 0) {
+                               /* XXX: we assume this is because close(2) has been called here. */
+                               if (errno == EBADF)
+                                       continue;
+
+                               libcharybdis_log("comm_select(): epoll_ctl failed while trying to delete an FD marked as closed: %s", strerror(errno));
+                               abort();
+                       }
+
+                       continue;
+               }
+
                if(pfd[i].events & (EPOLLOUT | EPOLLHUP | EPOLLERR))
                {
                        hdl = F->write_handler;
@@ -198,15 +213,36 @@ comm_select(unsigned long delay)
                                libcharybdis_log("epoll.c: NULL write handler called");
                }
                
-               if(F->flags.open == 0)
-                       continue;               
+               if(F->flags.open == 0 && F->pflags == 0)
+                       continue;
+               else if (F->flags.open == 0)
+               {
+                       F->pflags = ep_event.events = flags;
+                       ep_event.data.ptr = F;
+
+                       if(epoll_ctl(ep, EPOLL_CTL_DEL, F->fd, &ep_event) != 0) {
+                               /* XXX: we assume this is because close(2) has been called here. */
+                               if (errno == EBADF)
+                                       continue;
+
+                               libcharybdis_log("comm_select(): epoll_ctl failed while trying to delete an FD marked as closed: %s", strerror(errno));
+                               abort();
+                       }
+
+                       continue;
+               }
                
                flags = 0;
                
                if(F->read_handler != NULL)
                        flags |= EPOLLIN;
+               else
+                       flags &= ~EPOLLIN;
+
                if(F->write_handler != NULL)
                        flags |= EPOLLOUT;
+               else
+                       flags &= ~EPOLLOUT;
                
                if(old_flags != flags)
                {
@@ -214,15 +250,14 @@ comm_select(unsigned long delay)
                                op = EPOLL_CTL_DEL;                     
                        else
                                op = EPOLL_CTL_MOD;
+
                        F->pflags = ep_event.events = flags;
                        ep_event.data.ptr = F;
+
                        if(epoll_ctl(ep, op, F->fd, &ep_event) != 0)
-                       {
-                               libcharybdis_log("comm_setselect(): epoll_ctl failed: %s", strerror(errno));
-                       }
+                               libcharybdis_log("comm_select(): epoll_ctl failed: %s", strerror(errno));
                }
                                        
        }
        return COMM_OK;
 }
-