Module: xenomai-jki
Branch: for-upstream
Commit: e03cb5081bfd995f34a3ac2d9544190fdd30a50c
URL:    
http://git.xenomai.org/?p=xenomai-jki.git;a=commit;h=e03cb5081bfd995f34a3ac2d9544190fdd30a50c

Author: Jan Kiszka <jan.kis...@siemens.com>
Date:   Mon Mar  1 14:45:26 2010 +0100

POSIX: Fix select to return deleted xnsynch objects as pending

We already return an fd as pending if the corresponding xnsynch object
is delete while waiting on it. Extend select to do the same if the
object is already mark deleted on binding.

This fixes select on half-closed RTnet TCP sockets.

Signed-off-by: Jan Kiszka <jan.kis...@siemens.com>

---

 ksrc/skins/posix/syscall.c |   39 +++++++++++++++++++++++++++++----------
 1 files changed, 29 insertions(+), 10 deletions(-)

diff --git a/ksrc/skins/posix/syscall.c b/ksrc/skins/posix/syscall.c
index 959b61c..f7616f6 100644
--- a/ksrc/skins/posix/syscall.c
+++ b/ksrc/skins/posix/syscall.c
@@ -2298,24 +2298,30 @@ static int select_bind_one(struct xnselector *selector, 
unsigned type, int fd)
 }
 
 static int select_bind_all(struct xnselector *selector,
-                          fd_set *fds[XNSELECT_MAX_TYPES], int nfds)
+                          fd_set *in_fds[XNSELECT_MAX_TYPES],
+                          fd_set *out_fds[XNSELECT_MAX_TYPES], int nfds)
 {
        unsigned fd, type;
+       int pending = 0;
        int err;
 
        for (type = 0; type < XNSELECT_MAX_TYPES; type++) {
-               fd_set *set = fds[type];
+               fd_set *set = in_fds[type];
                if (set)
                        for (fd = find_first_bit(set->fds_bits, nfds);
                             fd < nfds;
                             fd = find_next_bit(set->fds_bits, nfds, fd + 1)) {
                                err = select_bind_one(selector, type, fd);
-                               if (err)
-                                       return err;
+                               if (err) {
+                                       if (err != -EIDRM)
+                                               return err;
+                                       __FD_SET(fd, out_fds[type]);
+                                       pending++;
+                               }
                        }
        }
 
-       return 0;
+       return pending;
 }
 
 /* int select(int, fd_set *, fd_set *, fd_set *, struct timeval *) */
@@ -2328,8 +2334,10 @@ static int __select(struct pt_regs *regs)
        };
        fd_set *in_fds[XNSELECT_MAX_TYPES] = {NULL, NULL, NULL};
        fd_set *out_fds[XNSELECT_MAX_TYPES] = {NULL, NULL, NULL};
-       fd_set in_fds_storage[XNSELECT_MAX_TYPES],
-               out_fds_storage[XNSELECT_MAX_TYPES];
+       fd_set *tmp_fds[XNSELECT_MAX_TYPES];
+       fd_set in_fds_storage[XNSELECT_MAX_TYPES];
+       fd_set out_fds_storage[XNSELECT_MAX_TYPES];
+       fd_set tmp_fds_storage[XNSELECT_MAX_TYPES];
        xnticks_t timeout = XN_INFINITE;
        xntmode_t mode = XN_RELATIVE;
        struct xnselector *selector;
@@ -2387,7 +2395,9 @@ static int __select(struct pt_regs *regs)
 
                /* Bind directly the file descriptors, we do not need to go
                   through xnselect returning -ECHRNG */
-               if ((err = select_bind_all(selector, in_fds, nfds)))
+               for (i = 0; i < XNSELECT_MAX_TYPES; i++)
+                       __FD_ZERO(out_fds[i]);
+               if ((err = select_bind_all(selector, in_fds, out_fds, nfds)))
                        return err;
        }
 
@@ -2395,9 +2405,18 @@ static int __select(struct pt_regs *regs)
                err = xnselect(selector, out_fds, in_fds, nfds, timeout, mode);
 
                if (err == -ECHRNG) {
-                       int err = select_bind_all(selector, out_fds, nfds);
-                       if (err)
+                       int err2;
+
+                       for (i = 0; i < XNSELECT_MAX_TYPES; i++) {
+                               __FD_ZERO(&tmp_fds_storage[i]);
+                               tmp_fds[i] = &tmp_fds_storage[i];
+                       }
+                       err2 = select_bind_all(selector, out_fds, tmp_fds,
+                                              nfds);
+                       if (err2) {
+                               memcpy(out_fds, &tmp_fds, sizeof(*out_fds));
                                return err;
+                       }
                }
        } while (err == -ECHRNG);
 


_______________________________________________
Xenomai-git mailing list
Xenomai-git@gna.org
https://mail.gna.org/listinfo/xenomai-git

Reply via email to