ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/fdlist.c
(Generate patch)

Comparing ircd-hybrid/trunk/src/fdlist.c (file contents):
Revision 1618 by michael, Tue Oct 30 21:04:38 2012 UTC vs.
Revision 8520 by michael, Mon Apr 16 19:32:31 2018 UTC

# Line 1 | Line 1
1   /*
2 < *  ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 < *  fdlist.c: Maintains a list of file descriptors.
2 > *  ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3   *
4 < *  Copyright (C) 2002 by the past and present ircd coders, and others.
4 > *  Copyright (c) 1997-2018 ircd-hybrid development team
5   *
6   *  This program is free software; you can redistribute it and/or modify
7   *  it under the terms of the GNU General Public License as published by
# Line 16 | Line 15
15   *
16   *  You should have received a copy of the GNU General Public License
17   *  along with this program; if not, write to the Free Software
18 < *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
18 > *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19   *  USA
20 < *
21 < *  $Id$
20 > */
21 >
22 > /*! \file fdlist.c
23 > * \brief Maintains a list of file descriptors.
24 > * \version $Id$
25   */
26  
27   #include "stdinc.h"
28   #include "fdlist.h"
27 #include "client.h"  /* struct Client */
28 #include "event.h"
29 #include "ircd.h"    /* GlobalSetOptions */
29   #include "irc_string.h"
30   #include "s_bsd.h"   /* comm_setselect */
32 #include "conf.h"  /* ServerInfo */
33 #include "send.h"
31   #include "memory.h"
32 < #include "numeric.h"
33 < #include "s_misc.h"
37 < #include "irc_res.h"
32 > #include "misc.h"
33 > #include "res.h"
34  
35 < fde_t *fd_hash[FD_HASH_SIZE];
36 < fde_t *fd_next_in_loop = NULL;
35 >
36 > fde_t *fd_table;
37   int number_fd = LEAKED_FDS;
38   int hard_fdlimit = 0;
39 < struct Callback *fdlimit_cb = NULL;
44 <
45 < static void *
46 < changing_fdlimit(va_list args)
47 < {
48 <  int old_fdlimit = hard_fdlimit;
49 <
50 <  hard_fdlimit = va_arg(args, int);
51 <
52 <  if (ServerInfo.max_clients > (unsigned int)MAXCLIENTS_MAX)
53 <  {
54 <    if (old_fdlimit != 0)
55 <      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
56 <        "HARD_FDLIMIT changed to %d, adjusting MAXCLIENTS to %d",
57 <        hard_fdlimit, MAXCLIENTS_MAX);
58 <
59 <    ServerInfo.max_clients = MAXCLIENTS_MAX;
60 <  }
39 > int highest_fd = -1;
40  
62  return NULL;
63 }
41  
42   void
43   fdlist_init(void)
44   {
68  memset(&fd_hash, 0, sizeof(fd_hash));
69
70  fdlimit_cb = register_callback("changing_fdlimit", changing_fdlimit);
71  eventAddIsh("recalc_fdlimit", recalc_fdlimit, NULL, 58);
72  recalc_fdlimit(NULL);
73 }
74
75 void
76 recalc_fdlimit(void *unused)
77 {
78  int fdmax;
45    struct rlimit limit;
46  
47    if (!getrlimit(RLIMIT_NOFILE, &limit))
# Line 84 | Line 50 | recalc_fdlimit(void *unused)
50      setrlimit(RLIMIT_NOFILE, &limit);
51    }
52  
87  fdmax = getdtablesize();
88
53    /* allow MAXCLIENTS_MIN clients even at the cost of MAX_BUFFER and
54     * some not really LEAKED_FDS */
55 <  fdmax = IRCD_MAX(fdmax, LEAKED_FDS + MAX_BUFFER + MAXCLIENTS_MIN);
56 <
93 <  /* under no condition shall this raise over 65536
94 <   * for example user ip heap is sized 2*hard_fdlimit */
95 <  fdmax = IRCD_MIN(fdmax, 65536);
96 <
97 <  if (fdmax != hard_fdlimit)
98 <    execute_callback(fdlimit_cb, fdmax);
55 >  hard_fdlimit = IRCD_MAX(getdtablesize(), LEAKED_FDS + MAX_BUFFER + MAXCLIENTS_MIN);
56 >  fd_table = xcalloc(sizeof(fde_t) * hard_fdlimit);
57   }
58  
59 < static inline unsigned int
60 < hash_fd(int fd)
59 > static void
60 > fdlist_update_highest_fd(int fd, int opening)
61   {
62 <  return (((unsigned) fd) % FD_HASH_SIZE);
63 < }
62 >  if (fd < highest_fd)
63 >    return;
64  
65 < fde_t *
108 < lookup_fd(int fd)
109 < {
110 <  fde_t *F = fd_hash[hash_fd(fd)];
65 >  assert(fd < hard_fdlimit);
66  
67 <  while (F)
67 >  if (fd > highest_fd)
68    {
69 <    if (F->fd == fd)
70 <      return (F);
71 <    F = F->hnext;
72 <  }
69 >    /*
70 >     * assert() that we are not closing a FD bigger than our known highest FD.
71 >     */
72 >    assert(opening);
73 >    highest_fd = fd;
74 >    return;
75 >  }
76 >
77 >  /* If we are here, then fd == highest_fd */
78 >  /*
79 >   * assert() that we are closing the highest FD; we can't be re-opening it.
80 >   */
81 >  assert(!opening);
82  
83 <  return (NULL);
83 >  while (highest_fd >= 0 && fd_table[highest_fd].flags.open == 0)
84 >    --highest_fd;
85   }
86  
87   /* Called to open a given filedescriptor */
88 < void
89 < fd_open(fde_t *F, int fd, int is_socket, const char *desc)
88 > fde_t *
89 > fd_open(int fd, int is_socket, const char *desc)
90   {
91 <  unsigned int hashv = hash_fd(fd);
91 >  fde_t *F = &fd_table[fd];
92 >
93    assert(fd >= 0);
94 +  assert(F->fd == 0);
95 +  assert(F->flags.open == 0);
96  
97 +  /*
98 +   * Note: normally we'd have to clear the other flags, but currently F
99 +   * is always cleared before calling us.
100 +   */
101    F->fd = fd;
102    F->comm_index = -1;
131  if (desc)
132    strlcpy(F->desc, desc, sizeof(F->desc));
133  /* Note: normally we'd have to clear the other flags,
134   * but currently F is always cleared before calling us.. */
103    F->flags.open = 1;
104    F->flags.is_socket = is_socket;
137  F->hnext = fd_hash[hashv];
138  fd_hash[hashv] = F;
105  
106 <  number_fd++;
106 >  if (desc)
107 >    strlcpy(F->desc, desc, sizeof(F->desc));
108 >
109 >  ++number_fd;
110 >  fdlist_update_highest_fd(fd, 1);
111 >
112 >  return F;
113   }
114  
115   /* Called to close a given filedescriptor */
116   void
117   fd_close(fde_t *F)
118   {
119 <  unsigned int hashv = hash_fd(F->fd);
119 >  const int fd = F->fd;
120  
121 <  if (F == fd_next_in_loop)
122 <    fd_next_in_loop = F->hnext;
121 >  assert(F->fd >= 0);
122 >  assert(F->flags.open);
123  
124    if (F->flags.is_socket)
125      comm_setselect(F, COMM_SELECT_WRITE | COMM_SELECT_READ, NULL, NULL, 0);
126  
127    delete_resolver_queries(F);
128  
129 < #ifdef HAVE_LIBCRYPTO
130 <  if (F->ssl)
159 <    SSL_free(F->ssl);
160 < #endif
161 <
162 <  if (fd_hash[hashv] == F)
163 <    fd_hash[hashv] = F->hnext;
164 <  else {
165 <    fde_t *prev;
166 <
167 <    /* let it core if not found */
168 <    for (prev = fd_hash[hashv]; prev->hnext != F; prev = prev->hnext)
169 <      ;
170 <    prev->hnext = F->hnext;
171 <  }
129 >  if (tls_isusing(&F->ssl))
130 >    tls_free(&F->ssl);
131  
132    /* Unlike squid, we're actually closing the FD here! -- adrian */
133    close(F->fd);
134 <  number_fd--;
134 >  memset(F, 0, sizeof(*F));  /* Must set F->flags.open == 0 before fdlist_update_highest_fd() */
135  
136 <  memset(F, 0, sizeof(fde_t));
137 < }
179 <
180 < /*
181 < * fd_dump() - dump the list of active filedescriptors
182 < */
183 < void
184 < fd_dump(struct Client *source_p)
185 < {
186 <  int i;
187 <  fde_t *F;
188 <
189 <  for (i = 0; i < FD_HASH_SIZE; i++)
190 <    for (F = fd_hash[i]; F != NULL; F = F->hnext)
191 <      sendto_one(source_p, ":%s %d %s :fd %-5d desc '%s'",
192 <                 me.name, RPL_STATSDEBUG, source_p->name,
193 <                 F->fd, F->desc);
136 >  --number_fd;
137 >  fdlist_update_highest_fd(fd, 0);
138   }
139  
140   /*
# Line 204 | Line 148 | fd_note(fde_t *F, const char *format, ..
148   {
149    va_list args;
150  
151 <  if (format != NULL)
151 >  if (format)
152    {
153      va_start(args, format);
154      vsnprintf(F->desc, sizeof(F->desc), format, args);
# Line 220 | Line 164 | fd_note(fde_t *F, const char *format, ..
164   void
165   close_standard_fds(void)
166   {
167 <  int i;
224 <
225 <  for (i = 0; i < LOWEST_SAFE_FD; i++)
167 >  for (int i = 0; i < LOWEST_SAFE_FD; ++i)
168    {
169      close(i);
170 +
171      if (open("/dev/null", O_RDWR) < 0)
172 <      exit(-1); /* we're hosed if we can't even open /dev/null */
172 >      exit(EXIT_FAILURE); /* we're hosed if we can't even open /dev/null */
173    }
174   }
175  
176   void
177 < close_fds(fde_t *one)
177 > close_fds(void)
178   {
179 <  int i;
180 <  fde_t *F;
238 <
239 <  for (i = 0; i < FD_HASH_SIZE; i++)
240 <    for (F = fd_hash[i]; F != NULL; F = F->hnext)
241 <      if (F != one)
242 <        close(F->fd);
179 >  for (int fd = 0; fd <= highest_fd; ++fd)
180 >    close(fd);
181   }

Comparing ircd-hybrid/trunk/src/fdlist.c (property svn:keywords):
Revision 1618 by michael, Tue Oct 30 21:04:38 2012 UTC vs.
Revision 8520 by michael, Mon Apr 16 19:32:31 2018 UTC

# Line 1 | Line 1
1 < Id Revision
1 > Id

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)