Module: xenomai-head
Branch: master
Commit: 5c37ec64a0948ae34e86ea8f884443cc51f2bf06
URL:    
http://git.xenomai.org/?p=xenomai-head.git;a=commit;h=5c37ec64a0948ae34e86ea8f884443cc51f2bf06

Author: Philippe Gerum <r...@xenomai.org>
Date:   Tue Sep  8 16:23:33 2009 +0200

rtipc/iddp: introduce port auto-selection

---

 examples/rtdm/profiles/ipc/iddp-label.c |    8 +++++---
 ksrc/drivers/ipc/Kconfig                |    1 +
 ksrc/drivers/ipc/iddp.c                 |   28 ++++++++++++++++++++++------
 3 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/examples/rtdm/profiles/ipc/iddp-label.c 
b/examples/rtdm/profiles/ipc/iddp-label.c
index e11f450..7d32795 100644
--- a/examples/rtdm/profiles/ipc/iddp-label.c
+++ b/examples/rtdm/profiles/ipc/iddp-label.c
@@ -28,8 +28,7 @@
 
 pthread_t svtid, cltid;
 
-#define IDDP_SVPORT 12
-#define IDDP_CLPORT 13
+#define IDDP_CLPORT  27
 
 #define IDDP_PORT_LABEL  "iddp-demo"
 
@@ -91,9 +90,12 @@ void *server(void *arg)
         * it. Labeled ports will appear in the
         * /proc/xenomai/registry/rtipc/iddp directory once the socket
         * is bound.
+        *
+        * saddr.sipc_port specifies the port number to use. If -1 is
+        * passed, the IDDP driver will auto-select an idle port.
         */
        saddr.sipc_family = AF_RTIPC;
-       saddr.sipc_port = IDDP_SVPORT;
+       saddr.sipc_port = -1;   /* Pick next free */
        ret = bind(s, (struct sockaddr *)&saddr, sizeof(saddr));
        if (ret)
                fail("bind");
diff --git a/ksrc/drivers/ipc/Kconfig b/ksrc/drivers/ipc/Kconfig
index 38db875..a3921ac 100644
--- a/ksrc/drivers/ipc/Kconfig
+++ b/ksrc/drivers/ipc/Kconfig
@@ -35,6 +35,7 @@ config XENO_DRIVERS_RTIPC_XDDP
 
 config XENO_DRIVERS_RTIPC_IDDP
        depends on XENO_DRIVERS_RTIPC
+       select XENO_OPT_MAP
        bool "IDDP intra-domain datagram protocol"
        help
 
diff --git a/ksrc/drivers/ipc/iddp.c b/ksrc/drivers/ipc/iddp.c
index 174c1f0..ad7450e 100644
--- a/ksrc/drivers/ipc/iddp.c
+++ b/ksrc/drivers/ipc/iddp.c
@@ -23,6 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/vmalloc.h>
 #include <nucleus/heap.h>
+#include <nucleus/map.h>
 #include <rtdm/rtipc.h>
 #include "internal.h"
 
@@ -68,6 +69,8 @@ static struct sockaddr_ipc nullsa = {
        .sipc_port = -1
 };
 
+static struct xnmap *portbits;
+
 static struct iddp_socket *portmap[CONFIG_XENO_OPT_IDDP_NRPORT];
 
 static rtdm_event_t poolevt;
@@ -210,10 +213,10 @@ static int iddp_close(struct rtipc_private *priv,
        struct iddp_message *mbuf;
        LIST_HEAD(head);
 
-       RTDM_EXECUTE_ATOMICALLY(
-               if (sk->name.sipc_port > -1)
-                       portmap[sk->name.sipc_port] = NULL;
-       );
+       if (sk->name.sipc_port > -1) {
+               portmap[sk->name.sipc_port] = NULL;
+               xnmap_remove(portbits, sk->name.sipc_port);
+       }
 
        rtdm_sem_destroy(&sk->insem);
 
@@ -522,14 +525,14 @@ static ssize_t iddp_write(struct rtipc_private *priv,
 static int __iddp_bind_socket(struct iddp_socket *sk,
                              struct sockaddr_ipc *sa)
 {
+       int ret = 0, port;
        void *poolmem;
        size_t poolsz;
-       int ret = 0;
 
        if (sa->sipc_family != AF_RTIPC)
                return -EINVAL;
 
-       if (sa->sipc_port < 0 ||
+       if (sa->sipc_port < -1 ||
            sa->sipc_port >= CONFIG_XENO_OPT_IDDP_NRPORT)
                return -EINVAL;
 
@@ -541,6 +544,14 @@ static int __iddp_bind_socket(struct iddp_socket *sk,
        if (ret)
                return ret;
 
+       port = sa->sipc_port;
+       /* Will auto-select a free port number if unspec (-1). */
+       port = xnmap_enter(portbits, port, sk);
+       if (port < 0)
+               return port == -EEXIST ? -EADDRINUSE : -ENOMEM;
+       trace("selected port %d", port);
+       sa->sipc_port = port;
+
        /*
         * Allocate a local buffer pool if we were told to do so via
         * setsockopt() before we got there.
@@ -908,6 +919,10 @@ static int iddp_ioctl(struct rtipc_private *priv,
 
 static int __init iddp_init(void)
 {
+       portbits = xnmap_create(CONFIG_XENO_OPT_IDDP_NRPORT, 0, 0);
+       if (portbits == NULL)
+               return -ENOMEM;
+
        rtdm_event_init(&poolevt, 0);
 
        return 0;
@@ -916,6 +931,7 @@ static int __init iddp_init(void)
 static void __exit iddp_exit(void)
 {
        rtdm_event_destroy(&poolevt);
+       xnmap_delete(portbits);
 }
 
 struct rtipc_protocol iddp_proto_driver = {


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

Reply via email to