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 4479 by michael, Thu Aug 14 16:18:31 2014 UTC vs.
Revision 8752 by michael, Tue Jan 1 11:07:01 2019 UTC

# Line 1 | Line 1
1   /*
2   *  ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3   *
4 < *  Copyright (c) 1997-2014 ircd-hybrid development team
4 > *  Copyright (c) 1997-2019 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 15 | 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  
# Line 26 | Line 26
26  
27   #include "stdinc.h"
28   #include "fdlist.h"
29 #include "client.h"  /* struct Client */
30 #include "event.h"
31 #include "ircd.h"    /* GlobalSetOptions */
29   #include "irc_string.h"
30   #include "s_bsd.h"   /* comm_setselect */
34 #include "conf.h"  /* ConfigServerInfo */
35 #include "send.h"
31   #include "memory.h"
37 #include "numeric.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 + int highest_fd = -1;
40  
41  
42 < static int
43 < set_fdlimit(void)
42 > void
43 > fdlist_init(void)
44   {
50  int fdmax;
45    struct rlimit limit;
46  
47 <  if (!getrlimit(RLIMIT_NOFILE, &limit))
47 >  if (getrlimit(RLIMIT_NOFILE, &limit) == 0)
48    {
49      limit.rlim_cur = limit.rlim_max;
50      setrlimit(RLIMIT_NOFILE, &limit);
51    }
52  
53 <  fdmax = getdtablesize();
54 <
55 <  /* allow MAXCLIENTS_MIN clients even at the cost of MAX_BUFFER and
56 <   * some not really LEAKED_FDS */
57 <  fdmax = IRCD_MAX(fdmax, LEAKED_FDS + MAX_BUFFER + MAXCLIENTS_MIN);
58 <
65 <  /* under no condition shall this raise over 65536
66 <   * for example user ip heap is sized 2*hard_fdlimit */
67 <  hard_fdlimit = IRCD_MIN(fdmax, 65536);
68 <
69 <  return -1;
53 >  /*
54 >   * Allow MAXCLIENTS_MIN clients even at the cost of MAX_BUFFER and
55 >   * some not really LEAKED_FDS
56 >   */
57 >  hard_fdlimit = IRCD_MAX(getdtablesize(), LEAKED_FDS + MAX_BUFFER + MAXCLIENTS_MIN);
58 >  fd_table = xcalloc(sizeof(fde_t) * hard_fdlimit);
59   }
60  
61 < void
62 < fdlist_init(void)
61 > static void
62 > fdlist_update_highest_fd(int fd, bool opening)
63   {
64 <  set_fdlimit();
65 < }
64 >  if (fd < highest_fd)
65 >    return;
66  
67 < static inline unsigned int
79 < hash_fd(int fd)
80 < {
81 <  return ((unsigned int)fd) % FD_HASH_SIZE;
82 < }
83 <
84 < fde_t *
85 < lookup_fd(int fd)
86 < {
87 <  fde_t *F = fd_hash[hash_fd(fd)];
67 >  assert(fd < hard_fdlimit);
68  
69 <  while (F)
69 >  if (fd > highest_fd)
70    {
71 <    if (F->fd == fd)
72 <      return F;
73 <    F = F->hnext;
71 >    /*
72 >     * assert() that we are not closing a FD bigger than our known highest FD.
73 >     */
74 >    assert(opening == true);
75 >    highest_fd = fd;
76 >    return;
77    }
78  
79 <  return NULL;
79 >  /* If we are here, then fd == highest_fd */
80 >  /*
81 >   * assert() that we are closing the highest FD; we can't be re-opening it.
82 >   */
83 >  assert(opening == false);
84 >
85 >  while (highest_fd >= 0 && fd_table[highest_fd].flags.open == false)
86 >    --highest_fd;
87   }
88  
89   /* Called to open a given filedescriptor */
90 < void
91 < fd_open(fde_t *F, int fd, int is_socket, const char *desc)
90 > fde_t *
91 > fd_open(int fd, bool is_socket, const char *desc)
92   {
93 <  unsigned int hashv = hash_fd(fd);
93 >  fde_t *F = &fd_table[fd];
94 >
95    assert(fd >= 0);
96 +  assert(F->fd == 0);
97 +  assert(F->flags.open == false);
98  
99 +  /*
100 +   * Note: normally we'd have to clear the other flags, but currently F
101 +   * is always cleared before calling us.
102 +   */
103    F->fd = fd;
104    F->comm_index = -1;
105 +  F->flags.open = true;
106 +  F->flags.is_socket = is_socket;
107  
108    if (desc)
109      strlcpy(F->desc, desc, sizeof(F->desc));
110  
111 <  /* Note: normally we'd have to clear the other flags,
112 <   * but currently F is always cleared before calling us.. */
114 <  F->flags.open = 1;
115 <  F->flags.is_socket = is_socket;
116 <  F->hnext = fd_hash[hashv];
117 <  fd_hash[hashv] = F;
111 >  fdlist_update_highest_fd(F->fd, true);
112 >  ++number_fd;
113  
114 <  number_fd++;
114 >  return F;
115   }
116  
117   /* Called to close a given filedescriptor */
118 < void
118 > fde_t *
119   fd_close(fde_t *F)
120   {
121 <  unsigned int hashv = hash_fd(F->fd);
121 >  assert(F->fd >= 0);
122 >  assert(F->flags.open == true);
123  
124 <  if (F == fd_next_in_loop)
129 <    fd_next_in_loop = F->hnext;
130 <
131 <  if (F->flags.is_socket)
124 >  if (F->flags.is_socket == true)
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)
138 <    SSL_free(F->ssl);
139 < #endif
140 <
141 <  if (fd_hash[hashv] == F)
142 <    fd_hash[hashv] = F->hnext;
143 <  else
144 <  {
145 <    fde_t *prev;
146 <
147 <    /* let it core if not found */
148 <    for (prev = fd_hash[hashv]; prev->hnext != F; prev = prev->hnext)
149 <      ;
150 <    prev->hnext = F->hnext;
151 <  }
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 >  F->flags.open = false;  /* Must set F->flags.open == false before fdlist_update_highest_fd() */
135  
136 <  memset(F, 0, sizeof(fde_t));
137 < }
136 >  fdlist_update_highest_fd(F->fd, false);
137 >  --number_fd;
138  
139 < /*
140 < * fd_dump() - dump the list of active filedescriptors
141 < */
163 < void
164 < fd_dump(struct Client *source_p, int parc, char *parv[])
165 < {
166 <  for (unsigned int i = 0; i < FD_HASH_SIZE; ++i)
167 <    for (fde_t *F = fd_hash[i]; F; F = F->hnext)
168 <      sendto_one_numeric(source_p, &me, RPL_STATSDEBUG|SND_EXPLICIT,
169 <                         "F :fd %-5d desc '%s'", F->fd, F->desc);
139 >  memset(F, 0, sizeof(*F));
140 >
141 >  return F;
142   }
143  
144   /*
# Line 196 | Line 168 | fd_note(fde_t *F, const char *format, ..
168   void
169   close_standard_fds(void)
170   {
171 <  for (unsigned int i = 0; i < LOWEST_SAFE_FD; ++i)
171 >  for (int i = 0; i < LOWEST_SAFE_FD; ++i)
172    {
173      close(i);
174  
175      if (open("/dev/null", O_RDWR) < 0)
176 <      exit(-1); /* we're hosed if we can't even open /dev/null */
176 >      exit(EXIT_FAILURE); /* we're hosed if we can't even open /dev/null */
177    }
178   }
179  
180   void
181 < close_fds(fde_t *one)
181 > close_fds(void)
182   {
183 <  for (unsigned int i = 0; i < FD_HASH_SIZE; ++i)
184 <    for (fde_t *F = fd_hash[i]; F; F = F->hnext)
213 <      if (F != one)
214 <        close(F->fd);
183 >  for (int fd = 0; fd <= highest_fd; ++fd)
184 >    close(fd);
185   }

Comparing ircd-hybrid/trunk/src/fdlist.c (property svn:keywords):
Revision 4479 by michael, Thu Aug 14 16:18:31 2014 UTC vs.
Revision 8752 by michael, Tue Jan 1 11:07:01 2019 UTC

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

Diff Legend

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