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

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 marked deleted on binding.

This fixes the return code select on half-closed RTnet TCP sockets from
-EIDRM to > 0 (for pending fds).

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