[BACK]Return to uipc_socket2.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / kern

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/kern/uipc_socket2.c between version 1.91 and 1.91.2.5

version 1.91, 2008/04/24 11:38:36 version 1.91.2.5, 2010/03/11 15:04:20
Line 12 
Line 12 
  * 2. Redistributions in binary form must reproduce the above copyright   * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the   *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.   *    documentation and/or other materials provided with the distribution.
  * 3. All advertising materials mentioning features or use of this software  
  *    must display the following acknowledgement:  
  *      This product includes software developed by the NetBSD  
  *      Foundation, Inc. and its contributors.  
  * 4. Neither the name of The NetBSD Foundation nor the names of its  
  *    contributors may be used to endorse or promote products derived  
  *    from this software without specific prior written permission.  
  *   *
  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS   * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
Line 85  __KERNEL_RCSID(0, "$NetBSD$");
Line 78  __KERNEL_RCSID(0, "$NetBSD$");
 #include <sys/signalvar.h>  #include <sys/signalvar.h>
 #include <sys/kauth.h>  #include <sys/kauth.h>
 #include <sys/pool.h>  #include <sys/pool.h>
   #include <sys/uidinfo.h>
   
 /*  /*
  * Primitive routines for operating on sockets and socket buffers.   * Primitive routines for operating on sockets and socket buffers.
Line 127  __KERNEL_RCSID(0, "$NetBSD$");
Line 121  __KERNEL_RCSID(0, "$NetBSD$");
  *   domains.   *   domains.
  */   */
   
 static POOL_INIT(socket_pool, sizeof(struct socket), 0, 0, 0, "sockpl", NULL,  static pool_cache_t socket_cache;
     IPL_SOFTNET);  
   
 u_long  sb_max = SB_MAX;        /* maximum socket buffer size */  u_long  sb_max = SB_MAX;        /* maximum socket buffer size */
 static u_long sb_max_adj;       /* adjusted sb_max */  static u_long sb_max_adj;       /* adjusted sb_max */
Line 185  soisconnected(struct socket *so)
Line 178  soisconnected(struct socket *so)
   
         so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING|SS_ISCONFIRMING);          so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING|SS_ISCONFIRMING);
         so->so_state |= SS_ISCONNECTED;          so->so_state |= SS_ISCONNECTED;
         if (head && soqremque(so, 0)) {          if (head && so->so_onq == &head->so_q0) {
                 soqinsque(head, so, 1);                  if ((so->so_options & SO_ACCEPTFILTER) == 0) {
                 sorwakeup(head);                          soqremque(so, 0);
                 cv_broadcast(&head->so_cv);                          soqinsque(head, so, 1);
                           sorwakeup(head);
                           cv_broadcast(&head->so_cv);
                   } else {
                           so->so_upcall =
                               head->so_accf->so_accept_filter->accf_callback;
                           so->so_upcallarg = head->so_accf->so_accept_filter_arg;
                           so->so_rcv.sb_flags |= SB_UPCALL;
                           so->so_options &= ~SO_ACCEPTFILTER;
                           (*so->so_upcall)(so, so->so_upcallarg,
                                            POLLIN|POLLRDNORM, M_DONTWAIT);
                   }
         } else {          } else {
                 cv_broadcast(&so->so_cv);                  cv_broadcast(&so->so_cv);
                 sorwakeup(so);                  sorwakeup(so);
Line 222  soisdisconnected(struct socket *so)
Line 226  soisdisconnected(struct socket *so)
         sorwakeup(so);          sorwakeup(so);
 }  }
   
   void
   soinit2(void)
   {
   
           socket_cache = pool_cache_init(sizeof(struct socket), 0, 0, 0,
               "socket", NULL, IPL_SOFTNET, NULL, NULL, NULL);
   }
   
 /*  /*
  * When an attempt at a new connection is noted on a socket   * When an attempt at a new connection is noted on a socket
  * which accepts connections, sonewconn is called.  If the   * which accepts connections, sonewconn is called.  If the
Line 236  sonewconn(struct socket *head, int conns
Line 248  sonewconn(struct socket *head, int conns
         struct socket   *so;          struct socket   *so;
         int             soqueue, error;          int             soqueue, error;
   
           KASSERT(connstatus == 0 || connstatus == SS_ISCONFIRMING ||
               connstatus == SS_ISCONNECTED);
         KASSERT(solocked(head));          KASSERT(solocked(head));
   
           if ((head->so_options & SO_ACCEPTFILTER) != 0)
                   connstatus = 0;
         soqueue = connstatus ? 1 : 0;          soqueue = connstatus ? 1 : 0;
         if (head->so_qlen + head->so_q0len > 3 * head->so_qlimit / 2)          if (head->so_qlen + head->so_q0len > 3 * head->so_qlimit / 2)
                 return ((struct socket *)0);                  return NULL;
         so = soget(false);          so = soget(false);
         if (so == NULL)          if (so == NULL)
                 return (NULL);                  return NULL;
         mutex_obj_hold(head->so_lock);          mutex_obj_hold(head->so_lock);
         so->so_lock = head->so_lock;          so->so_lock = head->so_lock;
         so->so_type = head->so_type;          so->so_type = head->so_type;
Line 257  sonewconn(struct socket *head, int conns
Line 273  sonewconn(struct socket *head, int conns
         so->so_send = head->so_send;          so->so_send = head->so_send;
         so->so_receive = head->so_receive;          so->so_receive = head->so_receive;
         so->so_uidinfo = head->so_uidinfo;          so->so_uidinfo = head->so_uidinfo;
           so->so_cpid = head->so_cpid;
 #ifdef MBUFTRACE  #ifdef MBUFTRACE
         so->so_mowner = head->so_mowner;          so->so_mowner = head->so_mowner;
         so->so_rcv.sb_mowner = head->so_rcv.sb_mowner;          so->so_rcv.sb_mowner = head->so_rcv.sb_mowner;
         so->so_snd.sb_mowner = head->so_snd.sb_mowner;          so->so_snd.sb_mowner = head->so_snd.sb_mowner;
 #endif  #endif
         (void) soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat);          if (soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat) != 0)
                   goto out;
         so->so_snd.sb_lowat = head->so_snd.sb_lowat;          so->so_snd.sb_lowat = head->so_snd.sb_lowat;
         so->so_rcv.sb_lowat = head->so_rcv.sb_lowat;          so->so_rcv.sb_lowat = head->so_rcv.sb_lowat;
         so->so_rcv.sb_timeo = head->so_rcv.sb_timeo;          so->so_rcv.sb_timeo = head->so_rcv.sb_timeo;
Line 275  sonewconn(struct socket *head, int conns
Line 293  sonewconn(struct socket *head, int conns
         KASSERT(solocked(so));          KASSERT(solocked(so));
         if (error != 0) {          if (error != 0) {
                 (void) soqremque(so, soqueue);                  (void) soqremque(so, soqueue);
   out:
                   /*
                    * Remove acccept filter if one is present.
                    * XXX Is this really needed?
                    */
                   if (so->so_accf != NULL)
                           (void)accept_filt_clear(so);
                 soput(so);                  soput(so);
                 return (NULL);                  return NULL;
         }          }
         if (connstatus) {          if (connstatus) {
                 sorwakeup(head);                  sorwakeup(head);
                 cv_broadcast(&head->so_cv);                  cv_broadcast(&head->so_cv);
                 so->so_state |= connstatus;                  so->so_state |= connstatus;
         }          }
         return (so);          return so;
 }  }
   
 struct socket *  struct socket *
Line 291  soget(bool waitok)
Line 316  soget(bool waitok)
 {  {
         struct socket *so;          struct socket *so;
   
         so = pool_get(&socket_pool, (waitok ? PR_WAITOK : PR_NOWAIT));          so = pool_cache_get(socket_cache, (waitok ? PR_WAITOK : PR_NOWAIT));
         if (__predict_false(so == NULL))          if (__predict_false(so == NULL))
                 return (NULL);                  return (NULL);
         memset(so, 0, sizeof(*so));          memset(so, 0, sizeof(*so));
Line 320  soput(struct socket *so)
Line 345  soput(struct socket *so)
         cv_destroy(&so->so_cv);          cv_destroy(&so->so_cv);
         cv_destroy(&so->so_rcv.sb_cv);          cv_destroy(&so->so_rcv.sb_cv);
         cv_destroy(&so->so_snd.sb_cv);          cv_destroy(&so->so_snd.sb_cv);
         pool_put(&socket_pool, so);          pool_cache_put(socket_cache, so);
 }  }
   
 void  void
Line 447  sowakeup(struct socket *so, struct sockb
Line 472  sowakeup(struct socket *so, struct sockb
         if (sb->sb_flags & SB_ASYNC)          if (sb->sb_flags & SB_ASYNC)
                 fownsignal(so->so_pgid, SIGIO, code, band, so);                  fownsignal(so->so_pgid, SIGIO, code, band, so);
         if (sb->sb_flags & SB_UPCALL)          if (sb->sb_flags & SB_UPCALL)
                 (*so->so_upcall)(so, so->so_upcallarg, M_DONTWAIT);                  (*so->so_upcall)(so, so->so_upcallarg, band, M_DONTWAIT);
   }
   
   /*
    * Reset a socket's lock pointer.  Wake all threads waiting on the
    * socket's condition variables so that they can restart their waits
    * using the new lock.  The existing lock must be held.
    */
   void
   solockreset(struct socket *so, kmutex_t *lock)
   {
   
           KASSERT(solocked(so));
   
           so->so_lock = lock;
           cv_broadcast(&so->so_snd.sb_cv);
           cv_broadcast(&so->so_rcv.sb_cv);
           cv_broadcast(&so->so_cv);
 }  }
   
 /*  /*
Line 553  sbreserve(struct sockbuf *sb, u_long cc,
Line 595  sbreserve(struct sockbuf *sb, u_long cc,
   
         if (cc == 0 || cc > sb_max_adj)          if (cc == 0 || cc > sb_max_adj)
                 return (0);                  return (0);
         if (so) {  
                 if (kauth_cred_geteuid(l->l_cred) == so->so_uidinfo->ui_uid)          maxcc = l->l_proc->p_rlimit[RLIMIT_SBSIZE].rlim_cur;
                         maxcc = l->l_proc->p_rlimit[RLIMIT_SBSIZE].rlim_cur;  
                 else          uidinfo = so->so_uidinfo;
                         maxcc = RLIM_INFINITY;  
                 uidinfo = so->so_uidinfo;  
         } else {  
                 uidinfo = uid_find(0);  /* XXX: nothing better */  
                 maxcc = RLIM_INFINITY;  
         }  
         if (!chgsbsize(uidinfo, &sb->sb_hiwat, cc, maxcc))          if (!chgsbsize(uidinfo, &sb->sb_hiwat, cc, maxcc))
                 return 0;                  return 0;
         sb->sb_mbmax = min(cc * 2, sb_max);          sb->sb_mbmax = min(cc * 2, sb_max);
Line 1394  sbunlock(struct sockbuf *sb)
Line 1430  sbunlock(struct sockbuf *sb)
 }  }
   
 int  int
 sowait(struct socket *so, int timo)  sowait(struct socket *so, bool catch, int timo)
 {  {
         kmutex_t *lock;          kmutex_t *lock;
         int error;          int error;
   
         KASSERT(solocked(so));          KASSERT(solocked(so));
           KASSERT(catch || timo != 0);
   
         lock = so->so_lock;          lock = so->so_lock;
         error = cv_timedwait_sig(&so->so_cv, lock, timo);          if (catch)
                   error = cv_timedwait_sig(&so->so_cv, lock, timo);
           else
                   error = cv_timedwait(&so->so_cv, lock, timo);
         if (__predict_false(lock != so->so_lock))          if (__predict_false(lock != so->so_lock))
                 solockretry(so, lock);                  solockretry(so, lock);
         return error;          return error;

Legend:
Removed from v.1.91  
changed lines
  Added in v.1.91.2.5

CVSweb <webmaster@jp.NetBSD.org>