Ticket #785: net-close-4-6-branch.diff

File net-close-4-6-branch.diff, 13.4 KB (added by Chris Johns, on Dec 3, 2006 at 1:31:13 PM)

net-close-4-6-branch.diff

  • rtems_bsdnet_internal.h

    RCS file: /usr1/CVS/rtems/cpukit/libnetworking/rtems/rtems_bsdnet_internal.h,v
    retrieving revision 1.18
    diff -p -u -r1.18 rtems_bsdnet_internal.h
    int ioctl (int, int, ...); 
    189189 * tries to use these events or if the `sleep'
    190190 * events are equal to any of the NETISR * events.
    191191 */
    192 #define SBWAIT_EVENT   RTEMS_EVENT_24
    193 #define SOSLEEP_EVENT  RTEMS_EVENT_25
    194 #define NETISR_IP_EVENT                (1 << NETISR_IP)
    195 #define NETISR_ARP_EVENT       (1 << NETISR_ARP)
    196 #define NETISR_EVENTS  (NETISR_IP_EVENT|NETISR_ARP_EVENT)
    197 #if (SBWAIT_EVENT & SOSLEEP_EVENT & NETISR_EVENTS)
     192#define SBWAIT_EVENT        RTEMS_EVENT_24
     193#define SOSLEEP_EVENT       RTEMS_EVENT_25
     194#define SOCONNABORTED_EVENT RTEMS_EVENT_26
     195#define NETISR_IP_EVENT     (1 << NETISR_IP)
     196#define NETISR_ARP_EVENT    (1 << NETISR_ARP)
     197#define NETISR_EVENTS       (NETISR_IP_EVENT|NETISR_ARP_EVENT)
     198#if (SBWAIT_EVENT & SOSLEEP_EVENT & SOCONNABORTED_EVENT & NETISR_EVENTS)
    198199# error "Network event conflict"
    199200#endif
    200201
  • rtems_glue.c

    RCS file: /usr1/CVS/rtems/cpukit/libnetworking/rtems/rtems_glue.c,v
    retrieving revision 1.29.2.2
    diff -p -u -r1.29.2.2 rtems_glue.c
    sbwait(sb) 
    375375         */
    376376        sb->sb_flags |= SB_WAIT;
    377377
    378         /*
    379          * Release the network semaphore.
    380          */
    381         rtems_bsdnet_semaphore_release ();
     378        sc = rtems_bsdnet_event_receive (SBWAIT_EVENT | SOCONNABORTED_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT,
     379                                        sb->sb_timeo, &events);
    382380
    383         /*
    384          * Wait for the wakeup event.
    385          */
    386         sc = rtems_event_receive (SBWAIT_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT, sb->sb_timeo, &events);
    387 
    388         /*
    389          * Reobtain the network semaphore.
    390          */
    391         rtems_bsdnet_semaphore_obtain ();
     381        if (events & SOCONNABORTED_EVENT)
     382                return ECONNABORTED;
    392383
    393384        /*
    394385         * Return the status of the wait.
    sowakeup(so, sb) 
    411402{
    412403        if (sb->sb_flags & SB_WAIT) {
    413404                sb->sb_flags &= ~SB_WAIT;
    414                 rtems_event_send (sb->sb_sel.si_pid, SBWAIT_EVENT);
     405                if (so->so_state & SS_ASYNC) {
     406                        rtems_event_send (sb->sb_sel.si_pid, SOCONNABORTED_EVENT);
     407                        sb->sb_sel.si_pid = 0;
     408                        soconnsleep (so);
     409                }
     410                else {
     411                        rtems_event_send (sb->sb_sel.si_pid, SBWAIT_EVENT);
     412                        sb->sb_sel.si_pid = 0;
     413                }
    415414        }
    416415        if (sb->sb_wakeup) {
    417416                (*sb->sb_wakeup) (so, sb->sb_wakeuparg);
    soconnsleep (struct socket *so) 
    456455         */
    457456        if (so->so_pgid)
    458457                rtems_panic ("Another task is already sleeping on that socket");
     458
    459459        rtems_task_ident (RTEMS_SELF, 0, &tid);
    460460        so->so_pgid = tid;
    461461
    462462        /*
    463463         * Wait for the wakeup event.
    464464         */
    465         sc = rtems_bsdnet_event_receive (SOSLEEP_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT, so->so_rcv.sb_timeo, &events);
     465        sc = rtems_bsdnet_event_receive (SOSLEEP_EVENT | SOCONNABORTED_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT,
     466                                        so->so_rcv.sb_timeo, &events);
    466467
    467         /*
    468          * Relinquish ownership of the socket.
    469          */
    470         so->so_pgid = 0;
     468        if (events & SOCONNABORTED_EVENT)
     469                return ECONNABORTED;
    471470
    472471        switch (sc) {
    473472        case RTEMS_SUCCESSFUL:  return 0;
    soconnsleep (struct socket *so) 
    482481void
    483482soconnwakeup (struct socket *so)
    484483{
    485         if (so->so_pgid)
    486                 rtems_event_send (so->so_pgid, SOSLEEP_EVENT);
     484        if (so->so_pgid) {
     485                if ((so->so_options & SO_ACCEPTCONN) && (so->so_state & SS_ASYNC)) {
     486                        rtems_event_send (so->so_pgid, SOCONNABORTED_EVENT);
     487                        so->so_pgid = 0;
     488                        soconnsleep (so);
     489                }
     490                else {
     491                        rtems_event_send (so->so_pgid, SOSLEEP_EVENT);
     492                        so->so_pgid = 0;
     493                }
     494        }
    487495}
    488496
    489497/*
  • rtems_syscall.c

    RCS file: /usr1/CVS/rtems/cpukit/libnetworking/rtems/rtems_syscall.c,v
    retrieving revision 1.17.2.1
    diff -p -u -r1.17.2.1 rtems_syscall.c
    int rtems_bsdnet_makeFdForSocket(void *s 
    3636struct socket *rtems_bsdnet_fdToSocket(int fd);
    3737
    3838/*
    39  * Package system call argument into mbuf.
     39 * Package system call argument into mbuf. This call must not block
     40 * or release the network semaphore.
    4041 */
     42/* chrisj@rtems.org: thread safe check: done */
    4143static int
    4244sockargstombuf (struct mbuf **mp, const void *buf, int buflen, int type)
    4345{
    sockargstombuf (struct mbuf **mp, const  
    4547
    4648        if ((u_int)buflen > MLEN)
    4749                return (EINVAL);
    48         m = m_get(M_WAIT, type);
     50        m = m_get(M_NOWAIT, type);
    4951        if (m == NULL)
    5052                return (ENOBUFS);
    5153        m->m_len = buflen;
    sockargstombuf (struct mbuf **mp, const  
    6466 *                       BSD-style entry points                      *
    6567 *********************************************************************
    6668 */
     69/* chrisj@rtems.org: thread safe check: done */
    6770int
    6871socket (int domain, int type, int protocol)
    6972{
    socket (int domain, int type, int protoc 
    8689        return fd;
    8790}
    8891
     92/* chrisj@rtems.org: thread safe check: done */
    8993int
    9094bind (int s, struct sockaddr *name, int namelen)
    9195{
    bind (int s, struct sockaddr *name, int  
    113117        return ret;
    114118}
    115119
     120/* chrisj@rtems.org: thread safe check: done */
    116121int
    117122connect (int s, struct sockaddr *name, int namelen)
    118123{
    connect (int s, struct sockaddr *name, i 
    138143                return -1;
    139144        }
    140145        error = soconnect (so, nam);
     146        if ((error == ECONNABORTED) && (so->so_pgid)) {
     147                rtems_event_send (so->so_pgid, SOSLEEP_EVENT);
     148                so->so_pgid = 0;
     149        }
    141150        if (error)
    142151                goto bad;
    143152        if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
    connect (int s, struct sockaddr *name, i 
    148157        }
    149158        while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
    150159                error = soconnsleep (so);
     160                if ((error == ECONNABORTED) && (so->so_pgid)) {
     161                        rtems_event_send (so->so_pgid, SOSLEEP_EVENT);
     162                        so->so_pgid = 0;
     163                        break;
     164                }
    151165                if (error)
    152166                        break;
    153167        }
    connect (int s, struct sockaddr *name, i 
    156170                so->so_error = 0;
    157171        }
    158172    bad:
     173/*
     174 * chrisj@rtems.org: removed the clearing of the SS_ISCONNECTING so
     175 *                   the error path does not touch the so struct.
    159176        so->so_state &= ~SS_ISCONNECTING;
     177*/
    160178        m_freem (nam);
    161179        if (error)
    162180                errno = error;
    connect (int s, struct sockaddr *name, i 
    166184        return ret;
    167185}
    168186
     187/* chrisj@rtems.org: thread safe check: done */
    169188int
    170189listen (int s, int backlog)
    171190{
    listen (int s, int backlog) 
    185204        return ret;
    186205}
    187206
     207/* chrisj@rtems.org: thread safe check: done */
    188208int
    189209accept (int s, struct sockaddr *name, int *namelen)
    190210{
    accept (int s, struct sockaddr *name, in 
    207227                rtems_bsdnet_semaphore_release ();
    208228                return -1;
    209229        }
    210         while (head->so_comp.tqh_first == NULL && head->so_error == 0) {
    211                 if (head->so_state & SS_CANTRCVMORE) {
    212                         head->so_error = ECONNABORTED;
    213                         break;
    214                 }
     230        while (head->so_comp.tqh_first == NULL && head->so_error == 0) {
     231                if (head->so_state & SS_CANTRCVMORE) {
     232                        head->so_error = ECONNABORTED;
     233                        break;
     234                }
    215235                head->so_error = soconnsleep (head);
    216         }
     236                if ((head->so_error == ECONNABORTED) && (head->so_pgid)) {
     237                        rtems_event_send (head->so_pgid, SOSLEEP_EVENT);
     238                        head->so_pgid = 0;
     239                        break;
     240                }
     241                head->so_pgid = 0;
     242        }
    217243        if (head->so_error) {
    218244                errno = head->so_error;
    219245                head->so_error = 0;
    accept (int s, struct sockaddr *name, in 
    254280 *  Shutdown routine
    255281 */
    256282
     283/* chrisj@rtems.org: thread safe check: done */
    257284int
    258285shutdown (int s, int how)
    259286{
    260       struct socket *so;
    261       int error;
     287        struct socket *so;
     288        int error;
    262289
    263       rtems_bsdnet_semaphore_obtain ();
    264       if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
    265               rtems_bsdnet_semaphore_release ();
    266               return -1;
    267       }
    268       error = soshutdown(so, how);
    269       rtems_bsdnet_semaphore_release ();
    270       if (error) {
    271               errno = error;
    272               return -1;
    273       }
    274       return 0;
     290        rtems_bsdnet_semaphore_obtain ();
     291        if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
     292                rtems_bsdnet_semaphore_release ();
     293                return -1;
     294        }
     295        error = soshutdown(so, how);
     296        if ((error == ECONNABORTED) && (so->so_pgid)) {
     297                rtems_event_send (so->so_pgid, SOSLEEP_EVENT);
     298                so->so_pgid = 0;
     299        }
     300        rtems_bsdnet_semaphore_release ();
     301        if (error) {
     302                errno = error;
     303                return -1;
     304        }
     305        return 0;
    275306}
    276307
    277308/*
    278309 * All `transmit' operations end up calling this routine.
    279310 */
     311/* chrisj@rtems.org: thread safe check: done */
    280312ssize_t
    281313sendmsg (int s, const struct msghdr *mp, int flags)
    282314{
    sendmsg (int s, const struct msghdr *mp, 
    351383/*
    352384 * Send a message to a host
    353385 */
     386/* chrisj@rtems.org: thread safe check: done */
    354387ssize_t
    355388sendto (int s, const void *buf, size_t buflen, int flags, const struct sockaddr *to, int tolen)
    356389{
    sendto (int s, const void *buf, size_t b 
    371404/*
    372405 * Send a message to a connected host
    373406 */
     407/* chrisj@rtems.org: thread safe check: done */
    374408ssize_t
    375409send (int s, const void *buf, size_t buflen, int flags)
    376410{
    send (int s, const void *buf, size_t buf 
    380414/*
    381415 * All `receive' operations end up calling this routine.
    382416 */
     417/* chrisj@rtems.org: thread safe check: done */
    383418ssize_t
    384419recvmsg (int s, struct msghdr *mp, int flags)
    385420{
    recvmsg (int s, struct msghdr *mp, int f 
    416451        error = soreceive (so, &from, &auio, (struct mbuf **)NULL,
    417452                        mp->msg_control ? &control : (struct mbuf **)NULL,
    418453                        &mp->msg_flags);
     454        if ((error == ECONNABORTED) && (so->so_pgid)) {
     455                rtems_event_send (so->so_pgid, SOSLEEP_EVENT);
     456                so->so_pgid = 0;
     457        }
    419458        if (error) {
    420459                if (auio.uio_resid != len && (error == EINTR || error == EWOULDBLOCK))
    421460                        error = 0;
    recvmsg (int s, struct msghdr *mp, int f 
    474513/*
    475514 * Receive a message from a host
    476515 */
     516/* chrisj@rtems.org: thread safe check: done */
    477517ssize_t
    478518recvfrom (int s, void *buf, size_t buflen, int flags, const struct sockaddr *from, int *fromlen)
    479519{
    recvfrom (int s, void *buf, size_t bufle 
    501541/*
    502542 * Receive a message from a connected host
    503543 */
     544/* chrisj@rtems.org: thread safe check: done */
    504545ssize_t
    505546recv (int s, void *buf, size_t buflen, int flags)
    506547{
    507548        return recvfrom (s, buf, buflen, flags, NULL, NULL);
    508549}
    509550
     551/* chrisj@rtems.org: thread safe check: not done */
    510552int
    511553setsockopt (int s, int level, int name, const void *val, int len)
    512554{
    setsockopt (int s, int level, int name,  
    542584        return 0;
    543585}
    544586
     587/* chrisj@rtems.org: thread safe check: not done */
    545588int
    546589getsockopt (int s, int level, int name, void *aval, int *avalsize)
    547590{
    getsockopt (int s, int level, int name,  
    585628        return 0;
    586629}
    587630
     631/* chrisj@rtems.org: thread safe check: not done */
    588632static int
    589633getpeersockname (int s, struct sockaddr *name, int *namelen, int pflag)
    590634{
    getpeersockname (int s, struct sockaddr  
    624668        return 0;
    625669}
    626670
     671/* chrisj@rtems.org: thread safe check: not done */
    627672int
    628673getpeername (int s, struct sockaddr *name, int *namelen)
    629674{
    630675        return getpeersockname (s, name, namelen, 1);
    631676}
     677/* chrisj@rtems.org: thread safe check: not done */
    632678int
    633679getsockname (int s, struct sockaddr *name, int *namelen)
    634680{
    635681        return getpeersockname (s, name, namelen, 0);
    636682}
    637683
     684/* chrisj@rtems.org: thread safe check: not done */
    638685int
    639686sysctl(int *name, u_int namelen, void *oldp,
    640687       size_t *oldlenp, void *newp, size_t newlen)
    sysctl(int *name, u_int namelen, void *o 
    662709 *                      RTEMS I/O HANDLER ROUTINES                      *
    663710 ************************************************************************
    664711 */
     712/* chrisj@rtems.org: thread safe check: done */
    665713static int
    666714rtems_bsdnet_close (rtems_libio_t *iop)
    667715{
    rtems_bsdnet_close (rtems_libio_t *iop) 
    674722                rtems_bsdnet_semaphore_release ();
    675723                return -1;
    676724        }
     725        /*
     726         * Clear the socket pointer incase a nested call to close occurs.
     727         */
     728        iop->data1 = NULL;
     729        /*
     730         * A special flag for RTEMS to signal the socket is being closed.
     731         * We use this to block the close if any thread is blocked
     732         * waiting.
     733         */
     734  so->so_state |= SS_ASYNC;
    677735        error = soclose (so);
    678736        rtems_bsdnet_semaphore_release ();
    679737        if (error) {
    rtems_bsdnet_close (rtems_libio_t *iop) 
    683741        return 0;
    684742}
    685743
     744/* chrisj@rtems.org: thread safe check: done */
    686745static ssize_t
    687746rtems_bsdnet_read (rtems_libio_t *iop, void *buffer, unsigned32 count)
    688747{
    689748        return recv (iop->data0, buffer, count, 0);
    690749}
    691750
     751/* chrisj@rtems.org: thread safe check: done */
    692752static ssize_t
    693753rtems_bsdnet_write (rtems_libio_t *iop, const void *buffer, unsigned32 count)
    694754{
    695755        return send (iop->data0, buffer, count, 0);
    696756}
    697757
     758/* chrisj@rtems.org: thread safe check: not done */
    698759static int
    699760so_ioctl (rtems_libio_t *iop, struct socket *so, unsigned32 command, void *buffer)
    700761{
    so_ioctl (rtems_libio_t *iop, struct soc 
    722783        return (*so->so_proto->pr_usrreqs->pru_control)(so, command, buffer, 0);
    723784}
    724785
     786/* chrisj@rtems.org: thread safe check: not done */
    725787static int
    726788rtems_bsdnet_ioctl (rtems_libio_t *iop, unsigned32 command, void *buffer)
    727789{
    rtems_bsdnet_ioctl (rtems_libio_t *iop,  
    743805        return 0;
    744806}
    745807
     808/* chrisj@rtems.org: thread safe check: done */
    746809static int
    747810rtems_bsdnet_fcntl (int cmd, rtems_libio_t *iop)
    748811{
    rtems_bsdnet_fcntl (int cmd, rtems_libio 
    763826        return 0;
    764827}
    765828
     829/* chrisj@rtems.org: thread safe check: done */
    766830static int
    767831rtems_bsdnet_fstat (rtems_filesystem_location_info_t *loc, struct stat *sp)
    768832{