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