gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r27745 - msh/src


From: gnunet
Subject: [GNUnet-SVN] r27745 - msh/src
Date: Thu, 4 Jul 2013 16:05:40 +0200

Author: harsha
Date: 2013-07-04 16:05:39 +0200 (Thu, 04 Jul 2013)
New Revision: 27745

Added:
   msh/src/test_scheduler_socket.c
Modified:
   msh/src/
   msh/src/Makefile.am
   msh/src/common.h
   msh/src/mshd.c
   msh/src/scheduler.c
   msh/src/scheduler.h
   msh/src/test_scheduler.c
   msh/src/util.c
   msh/src/util.h
Log:
extend scheduler with socket listen|connect

Index: msh/src
===================================================================
--- msh/src     2013-07-04 12:31:42 UTC (rev 27744)
+++ msh/src     2013-07-04 14:05:39 UTC (rev 27745)

Property changes on: msh/src
___________________________________________________________________
Modified: svn:ignore
## -4,6 +4,6 ##
 mshd
 mping
 test-suite.log
-test-scheduler
-test-scheduler.log
-test-scheduler.trs
+test-scheduler*
+test-scheduler*.log
+test-scheduler*.trs
Modified: msh/src/Makefile.am
===================================================================
--- msh/src/Makefile.am 2013-07-04 12:31:42 UTC (rev 27744)
+++ msh/src/Makefile.am 2013-07-04 14:05:39 UTC (rev 27745)
@@ -2,14 +2,20 @@
 
 mping_SOURCES = mping.c
 
-mshd_SOURCES = mshd.c util.c util.h
+mshd_SOURCES = mshd.c util.c util.h scheduler.c scheduler.h common.h
 mshd_LDADD = -levent
 
 check_PROGRAMS = \
-  test-scheduler
+  test-scheduler \
+  test-scheduler-socket
 
 test_scheduler_SOURCES = test_scheduler.c scheduler.c scheduler.h common.h
 test_scheduler_LDADD = -levent
 
+test_scheduler_socket_SOURCES = test_scheduler_socket.c scheduler.c 
scheduler.h \
+       common.h util.c util.h
+test_scheduler_socket_LDADD = -levent
+
 TESTS = \
-  test-scheduler
+  test-scheduler \
+  test-scheduler-socket

Modified: msh/src/common.h
===================================================================
--- msh/src/common.h    2013-07-04 12:31:42 UTC (rev 27744)
+++ msh/src/common.h    2013-07-04 14:05:39 UTC (rev 27745)
@@ -71,6 +71,10 @@
  */
 #define MSH_free_non_null(ptr) do { if (NULL != (ptr)) free (ptr); } while(0)
 
+/**
+ * Close a file descriptor while printing a warning upon any failure
+ */
+#define MSH_close(fd) do { if(0 != close(fd)) LOG_STRERROR ("close"); else fd 
= -1; } while (0)
 
 /* ******************** doubly-linked list *************** */
 /* To avoid mistakes: head->prev == tail->next == NULL     */

Modified: msh/src/mshd.c
===================================================================
--- msh/src/mshd.c      2013-07-04 12:31:42 UTC (rev 27744)
+++ msh/src/mshd.c      2013-07-04 14:05:39 UTC (rev 27745)
@@ -40,21 +40,75 @@
 static unsigned int rwidth;
 
 /**
- * event base for libevent
+ * Tasks for handling SIGINT and SIGTERM
  */
-static struct event_base *ebase;
+static struct Task *sigshut_tasks[2];
 
 /**
- * Select loop for a socket
- *
- * @param sock the fd corresponding to the socket
- * @param timeout the timeout in milliseconds
- * @return MSH_OK upon succes; MSH_SYSERR upon failure
+ * Task for running a round
  */
+static struct Task *rtask;
+
+/**
+ * Task for asynchronous accept on the socket
+ */
+static struct Task *atask;
+
+/**
+ * Array for checking which MPI processes have verified our addresses in the
+ * current round
+ */
+static uint8_t *barray;
+
+static size_t barray_size;
+
+static void
+barray_init ()
+{
+  barray_size = (rwidth + sizeof (barray[0]) - 1) / sizeof (barray[0]);
+  barray = MSH_malloc (barray_size);
+}
+
+static void
+barray_destroy ()
+{
+  free (barray);
+  barray = NULL;
+}
+
+static void
+barray_clear ()
+{
+  (void) memset (barray, 0, barray_size);
+}
+
+static void
+barray_set (unsigned int id)
+{
+  unsigned int off;
+  unsigned int idx;
+  typeof (barray[0]) one;
+  
+  off = id / sizeof (barray[0]);
+  idx = id % sizeof (barray[0]);
+  MSH_assert (off < barray_size);
+  one = (typeof (barray[0])) 1; /* cast */
+  MSH_assert (0 == (barray[off] & (one << idx)) );
+  barray[off] = barray[off] | (one << idx);
+}
+
 static int
-sock_select (int sock, long timeout)
+barray_isset (unsigned int id)
 {
-  return MSH_SYSERR;
+  unsigned int off;
+  unsigned int idx;
+  typeof (barray[0]) one;
+  
+  off = id / sizeof (barray[0]);
+  idx = id % sizeof (barray[0]);
+  MSH_assert (off < barray_size);
+  one = (typeof (barray[0])) 1; /* cast */
+  return (0 == (barray[off] & (one << idx)) ) ? 0 : 1;
 }
 
 
@@ -91,6 +145,42 @@
 
 
 /**
+ * Task to call accept and close on a listening socket
+ *
+ * @param sock the socket
+ * @param flags EV_* flags
+ * @param cls &atask
+ */
+static void
+accept_task (evutil_socket_t sock, short flags, void *cls)
+{
+  scheduler_remove (atask);
+  atask = NULL;
+  if (IS_SHUTDOWN_EVENT (flags))
+  {
+    (void) close (sock);
+    return;
+  }
+  LOG_DEBUG ("Got a connect\n");
+  
+}
+
+
+/**
+ * Send our addresses to an MPI processes
+ *
+ * @param rank the rank of the process which has to receive our request
+ * @return MSH_OK on success; MSH_SYSERR upon error
+ */
+static int
+send_addresses (int rank)
+{
+  MSH_break (0);
+  return MSH_OK;
+}
+
+
+/**
  * Verify IP addresses of all the hosts where mshd services are running
  *
  * @return MSH_OK if verification is successful; MSH_SYSERR upon error (an 
error
@@ -99,50 +189,22 @@
 static int
 verify_addresses ()
 {
-  struct sockaddr_in saddr;
+  struct sockaddr_in addr;
   socklen_t addrlen;
   int sock;
   unsigned int cnt;
 
-  /* open a listen socket */
-  sock = socket (AF_INET, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
+  addrlen = sizeof (struct sockaddr_in);
+  (void) memset (&addr, 0, addrlen);
+  sock = open_listen_socket ((struct sockaddr *) &addr, addrlen, rwidth);
   if (-1 == sock)
-  {
-    LOG_STRERROR ("socket");
     return MSH_SYSERR;
-  }
-  addrlen = sizeof (struct sockaddr_in);
-  (void) memset (&saddr, 0, addrlen);
-  saddr.sin_family = AF_INET;
-  if (-1 == bind (sock, &saddr, addrlen))
-  {
-    LOG_STRERROR ("bind");
-    goto clo_ret;
-  }
-  if (-1 == getsockname (sock, &saddr, &addrlen))
-  {
-    LOG_STRERROR ("getsockname");
-    goto clo_ret;
-  }
-  if (sizeof (struct sockaddr_in) != addrlen)
-  {
-    MSH_break (0);
-    goto clo_ret;
-  }
-  lport = ntohs (saddr.sin_port);
+  lport = ntohs (addr.sin_port);
   if (0 == lport)
   {
     MSH_break (0);
     goto clo_ret;
   }
-  if (-1 == listen (sock, rwidth))
-  {
-    LOG_STRERROR ("listen");
-    goto clo_ret;
-  }
-  goto contd;
-
- contd:
   LOG_DEBUG ("Bound to local port %u\n", lport);
   if (MPI_SUCCESS != MPI_Barrier (MPI_COMM_WORLD))
   {
@@ -150,13 +212,14 @@
     goto clo_ret;
   }
   for (cnt = 0; cnt < rwidth; cnt++)
-    //send_addresses ((round * rwidth) + cnt);
-  sock_select (sock, 0);
+    if (MSH_SYSERR == send_addresses ((round * rwidth) + cnt))
+      goto clo_ret;
   if (MPI_SUCCESS != MPI_Barrier (MPI_COMM_WORLD))
   {
     MSH_break (0);
     goto clo_ret;
   }
+  atask = scheduler_add_socket (sock, EV_READ, &accept_task, &atask, NULL);
   return MSH_OK;
 
  clo_ret:
@@ -166,46 +229,94 @@
 
 
 /**
- * Event callback for the first running task
+ * Event callback for handling shutdown signals
  *
+ * @param signal the signal
+ * @param flags EV_* flags
+ * @param cls pointer to the corresponding Task
+ */
+static void
+sig_shutdown (evutil_socket_t signal, short flags, void *cls)
+{
+  struct Task **task = cls;
+  unsigned int cnt;
+
+  scheduler_remove (*task);
+  *task = NULL;
+  if (IS_SHUTDOWN_EVENT (flags))
+    return;
+  LOG_DEBUG ("Got signal %d.  Exiting.\n", signal);
+  scheduler_shutdown ();
+}
+
+
+/**
+ * Task for running a round
+ *
  * @param nosock we have no sockets associated with this callback
  * @param flags EV_* flags
  * @param cls NULL
  */
 static void
-run (evutil_socket_t nosock, short flags, void *cls)
+run_round (evutil_socket_t nosock, short flags, void *cls);
+
+
+/**
+ * Schedules next round
+ */
+static void
+schedule_next_round ()
 {
-  LOG_DEBUG ("run task ran\n");
-  for (; round < nproc; round++)
+  MSH_assert (NULL == rtask);
+  if (round < ( (nproc + (rwidth - 1)) / rwidth) )
   {
+    round++;
+    rtask = scheduler_add (&run_round, NULL, TV_IMMEDIATE);
   }
 }
 
-#define N_SHUTDOWN_SIGNALS 2  /* SIGTERM, SIGINT */
-static struct event *ev_sigs[N_SHUTDOWN_SIGNALS];
 
+/**
+ * Task for running a round
+ *
+ * @param nosock we have no sockets associated with this callback
+ * @param flags EV_* flags
+ * @param cls NULL
+ */
+static void
+run_round (evutil_socket_t nosock, short flags, void *cls)
+{
+  scheduler_remove (rtask);
+  rtask = NULL;
+  if (IS_SHUTDOWN_EVENT (flags))
+    return;
+  if (MSH_OK == verify_addresses ())
+    schedule_next_round ();
+}
 
+
 /**
  * Event callback for the first running task
  *
- * @param signal the signal
+ * @param nosock we have no sockets associated with this callback
  * @param flags EV_* flags
  * @param cls NULL
  */
 static void
-sig_shutdown (evutil_socket_t signal, short flags, void *cls)
+run (evutil_socket_t nosock, short flags, void *cls)
 {
-  struct event **ev_sig = cls;
-  unsigned int cnt;
-
-  *ev_sig = NULL;
+  LOG_DEBUG ("Running main task\n");  
+  sigshut_tasks[0] = scheduler_add_signal (SIGTERM, &sig_shutdown,
+                                           &sigshut_tasks[0], NULL);
+  sigshut_tasks[1] = scheduler_add_signal (SIGTERM, &sig_shutdown,
+                                           &sigshut_tasks[1], NULL);
+  rtask = scheduler_add (&run_round, NULL, TV_IMMEDIATE);
 }
 
 
 int 
 main (int argc, char **argv)
 {
-  struct event *ev_run;
   int ret;
 
   ret = 1;
@@ -226,24 +337,23 @@
   }
   GNUNET_OS_network_interfaces_list (&net_if_processor, NULL);  
   if (0 == nips)
+  {
     LOG_ERROR ("No IP addresses found\n");
-  ebase = event_base_new ();
-  ev_run = evtimer_new (ebase, &run, NULL);
-  evtimer_add (ev_run, TV_IMMEDIATE);
-  if (0 != event_base_dispatch (ebase))
+    goto fail;
+  }
+  barray_init ();
+  if (MSH_OK != scheduler_run (&run, NULL))
   {
-    evtimer_del (ev_run);
-    LOG_ERROR ("Event loop dispatch error\n");
+    MSH_break (0);
+    barray_destroy ();
     goto fail;
   }
-  evtimer_del (ev_run);
-  ev_run = NULL;
+  barray_destroy ();
   ret = 0;
+
  fail:
   MSH_break (MPI_SUCCESS == MPI_Finalize());
   MSH_free_non_null (ip_addr_str);
-  if (NULL != ebase) 
-    event_base_free (ebase);
-  //libevent_global_shutdown ();
+  //libevent_global_shutdown ();  
   return ret;
 }

Modified: msh/src/scheduler.c
===================================================================
--- msh/src/scheduler.c 2013-07-04 12:31:42 UTC (rev 27744)
+++ msh/src/scheduler.c 2013-07-04 14:05:39 UTC (rev 27745)
@@ -112,3 +112,79 @@
   event_base_free (ebase);  
   return (1 == ret) ? MSH_OK : MSH_SYSERR;
 }
+
+
+struct SocketOpenHandle
+{
+  socket_open_fn cb;
+
+  void *cls;
+
+  struct Task *task;
+
+  int sock;
+};
+
+static void
+open_socket_cb (evutil_socket_t sock, short flags, void *cls)
+{
+  struct SocketOpenHandle *h = cls;
+  socket_open_fn cb;
+  void *cbcls;
+  int errval;
+  socklen_t optlen;
+  
+  scheduler_remove (h->task);
+  h->task = NULL;
+  cb = h->cb;
+  cbcls = h->cls;
+  MSH_assert (h->sock == sock);
+  free (h);
+  if (IS_SHUTDOWN_EVENT (flags))
+    goto err_ret;
+  errval = 1;
+  optlen = sizeof (errval);
+  if (0 != getsockopt (sock, SOL_SOCKET, SO_ERROR, &errval, &optlen))
+  {
+    LOG_STRERROR ("getsockopt");
+    goto err_ret;
+  }
+  if (0 != errval)
+  {
+    LOG_ERROR ("connect() failed for a socket: %s\n", strerror (errval));
+    goto err_ret;
+  }
+  cb (sock, cbcls);
+  return;
+
+ err_ret:
+  MSH_close (sock);
+  cb (-1, cbcls);
+}
+
+
+struct SocketOpenHandle *
+scheduler_open_socket (const struct sockaddr *addr, const socklen_t addrlen,
+                       socket_open_fn cb, void *cls)
+{
+  struct SocketOpenHandle *h;
+  int sock;
+
+  MSH_assert (NULL != cb);
+  if (-1 == (sock = open_socket (addr, addrlen)))
+    return NULL;
+  h = MSH_malloc (sizeof (struct SocketOpenHandle));
+  h->cb = cb;
+  h->cls = cls;
+  h->sock = sock;
+  h->task = scheduler_add_socket (sock, EV_WRITE, &open_socket_cb, h, NULL);
+  return h;
+}
+
+void
+scheduler_open_socket_cancel (struct SocketOpenHandle *h)
+{
+  scheduler_remove (h->task);
+  MSH_close (h->sock);
+  free (h);
+}

Modified: msh/src/scheduler.h
===================================================================
--- msh/src/scheduler.h 2013-07-04 12:31:42 UTC (rev 27744)
+++ msh/src/scheduler.h 2013-07-04 14:05:39 UTC (rev 27745)
@@ -5,7 +5,7 @@
 
 #define TV_IMMEDIATE &tv_immediate
 
-#define is_shutdown_event(flags) ((flags & (EV_READ | EV_WRITE | EV_TIMEOUT)) 
== (EV_READ | EV_WRITE | EV_TIMEOUT))
+#define IS_SHUTDOWN_EVENT(flags) ((flags & (EV_READ | EV_WRITE | EV_TIMEOUT)) 
== (EV_READ | EV_WRITE | EV_TIMEOUT))
 
 struct Task;
 
@@ -29,3 +29,9 @@
 
 int
 scheduler_run (event_callback_fn cb, void *cls);
+
+typedef void (* socket_open_fn) (int sockfd, void *cls);
+
+struct SocketOpenHandle *
+scheduler_open_socket (const struct sockaddr *addr, const socklen_t addrlen,
+                       socket_open_fn cb, void *cls);

Modified: msh/src/test_scheduler.c
===================================================================
--- msh/src/test_scheduler.c    2013-07-04 12:31:42 UTC (rev 27744)
+++ msh/src/test_scheduler.c    2013-07-04 14:05:39 UTC (rev 27745)
@@ -18,7 +18,7 @@
   struct Task **sig_task = cls;
   
   scheduler_remove (*sig_task);
-  if (is_shutdown_event (flags))
+  if (IS_SHUTDOWN_EVENT (flags))
     return;
   LOG_DEBUG ("Got signal %d.  Shutting down.\n", sig);
   scheduler_shutdown ();
@@ -52,8 +52,8 @@
     return;
   }
   scheduler_remove (task);
-  //if (!is_shutdown_event (flags))
-  scheduler_shutdown ();
+  if (!IS_SHUTDOWN_EVENT (flags))
+    scheduler_shutdown ();
 }
 
 int main (int argc, char *argv[])

Added: msh/src/test_scheduler_socket.c
===================================================================
--- msh/src/test_scheduler_socket.c                             (rev 0)
+++ msh/src/test_scheduler_socket.c     2013-07-04 14:05:39 UTC (rev 27745)
@@ -0,0 +1,139 @@
+#include "common.h"
+#include "scheduler.h"
+
+struct Task *sig_tasks[2];
+
+struct Task *atask;
+
+struct SocketOpenHandle *oh;
+
+static int lsock;
+
+static int csock;
+
+static int result;
+
+
+/**
+ * Event callback for a signal
+ *
+ * @param sig the signal
+ * @param flags EV_* flags
+ * @param cls NULL
+ */
+static void
+shutdown_signal (evutil_socket_t sig, short flags, void *cls)
+{
+  struct Task **sig_task = cls;
+  
+  scheduler_remove (*sig_task);
+  if (IS_SHUTDOWN_EVENT (flags))
+    return;
+  LOG_DEBUG ("Got signal %d.  Shutting down.\n", sig);
+  scheduler_shutdown ();
+}
+
+
+/**
+ * Task to call accept and close on a listening socket
+ *
+ * @param sock the socket
+ * @param flags EV_* flags
+ * @param cls &atask
+ */
+static void
+accept_task (evutil_socket_t fd, short flags, void *cls)
+{
+  struct sockaddr_in caddr;
+  socklen_t caddrlen;
+
+  LOG_DEBUG ("accept task\n");
+  scheduler_remove (atask);
+  atask = NULL;
+  if (IS_SHUTDOWN_EVENT (flags))
+  {
+    MSH_close (lsock);
+    return;
+  }
+  MSH_assert (fd == lsock);
+  LOG_DEBUG ("Got a connect\n");
+  caddrlen = sizeof (caddr);
+  if (0 > (csock = accept4 (lsock, &caddr, &caddrlen, 
+                            SOCK_NONBLOCK | SOCK_CLOEXEC)))
+  {
+    LOG_STRERROR ("accept4");
+    MSH_close (lsock);
+    scheduler_shutdown ();
+  }
+  if (2 == ++result)
+    scheduler_shutdown ();
+}
+
+
+static void
+socket_connect_cb (int fd, void *cls)
+{
+  oh = NULL;
+  if (fd < 0)
+  {
+    MSH_break (0);
+    return;
+  }
+  LOG_DEBUG ("Connected to local listen socket\n");
+  MSH_close (fd);
+  MSH_close (csock);
+  MSH_close (lsock);
+  if (2 == ++result)
+    scheduler_shutdown ();
+}
+
+
+/**
+ * Event callback for the first running task
+ *
+ * @param nosock we have no sockets associated with this callback
+ * @param flags EV_* flags
+ * @param cls NULL
+ */
+static void
+run (evutil_socket_t nosock, short flags, void *cls)
+{
+  struct sockaddr_in addr;
+  socklen_t addrlen;
+  
+  if (IS_SHUTDOWN_EVENT (flags))
+    return;
+  MSH_assert (-1 == nosock);
+  MSH_assert (NULL == cls);
+  MSH_assert (0 != (EV_TIMEOUT & flags));
+  LOG_DEBUG ("Run\n");
+  sig_tasks[0] = scheduler_add_signal (SIGTERM, &shutdown_signal, 
&sig_tasks[0], 
+                                       NULL);
+  sig_tasks[1] = scheduler_add_signal (SIGINT, &shutdown_signal, &sig_tasks[1],
+                                       NULL);
+  addrlen = sizeof (addr);
+  (void) memset (&addr, 0, addrlen);
+  addr.sin_family = AF_INET;
+  if (-1 == (lsock = open_listen_socket (&addr, addrlen, 1)))
+    return;
+  atask = scheduler_add_socket (lsock, EV_READ, &accept_task, &atask, NULL);
+  /* connect to the listening socket */
+  addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+  oh = scheduler_open_socket ((struct sockaddr *) &addr, addrlen,
+                              socket_connect_cb, NULL);
+  if (NULL == oh)
+    scheduler_shutdown ();
+  //  ctask = scheduler_add (run2, NULL, TV_IMMEDIATE);
+}
+
+int main (int argc, char *argv[])
+{
+  int ret;
+
+  result = 0;
+  lsock = -1;
+  csock = -1;
+  if (MSH_OK != scheduler_run (run, NULL))
+    return 1;  
+  return (2 == result) ? 0 : 1;
+}

Modified: msh/src/util.c
===================================================================
--- msh/src/util.c      2013-07-04 12:31:42 UTC (rev 27744)
+++ msh/src/util.c      2013-07-04 14:05:39 UTC (rev 27745)
@@ -84,3 +84,85 @@
   *old = tmp;
   *oldCount = newCount;
 }
+
+
+/**
+ * Creates a new non-blocking socket and binds it to the given address and 
makes
+ * it a listen socket
+ *
+ * @param addr the address to bind to
+ * @param addrlen the length of the addr
+ * @param backlog the max length of the pending connections.  This will be
+ *          passed to listen()
+ * @return the socket's fd; -1 on error
+ */
+int
+open_listen_socket (struct sockaddr *addr, const socklen_t addrlen, int 
backlog)
+{
+  socklen_t newaddrlen;
+  int sock;
+    
+  sock = socket (AF_INET, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
+  if (-1 == sock)
+  {
+    LOG_STRERROR ("socket");
+    return -1;
+  }
+  if (-1 == bind (sock, addr, addrlen))
+  {
+    LOG_STRERROR ("bind");
+    goto clo_ret;
+  }
+  newaddrlen = addrlen;
+  if (-1 == getsockname (sock, addr, &newaddrlen))
+  {
+    LOG_STRERROR ("getsockname");
+    goto clo_ret;
+  }  
+  if (newaddrlen != addrlen)
+  {
+    MSH_break (0);
+    goto clo_ret;
+  }
+  if (-1 == listen (sock, backlog))
+  {
+    LOG_STRERROR ("listen");
+    goto clo_ret;
+  }
+  return sock;
+
+ clo_ret:
+  (void) close (sock);
+  return -1;
+}
+
+
+/**
+ * Creates a new non-blocking socket and binds it to the given address and 
makes
+ * it a listen socket
+ *
+ * @param addr the address to bind to
+ * @param addrlen the length of the addr
+ * @param backlog the max length of the pending connections.  This will be
+ *          passed to listen()
+ * @return the socket's fd; -1 on error
+ */
+int
+open_socket (const struct sockaddr *addr, const socklen_t addrlen)
+{
+  int sock;
+
+  sock = socket (AF_INET, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
+  if (-1 == sock)
+  {
+    LOG_STRERROR ("socket");
+    return -1;
+  }
+  if ((-1 == connect (sock, addr, addrlen)) && (EINPROGRESS != errno) )
+  {
+    LOG_STRERROR ("connect");
+    (void) close (sock);
+    return -1;
+  }
+  return sock;
+}

Modified: msh/src/util.h
===================================================================
--- msh/src/util.h      2013-07-04 12:31:42 UTC (rev 27744)
+++ msh/src/util.h      2013-07-04 14:05:39 UTC (rev 27745)
@@ -99,5 +99,19 @@
 #define MSH_array_append(arr,size,element) do { 
MSH_array_grow(arr,size,size+1); arr[size-1] = element; } while(0)
 
 
+/**
+ * Creates a new non-blocking socket and binds it to the given address and 
makes
+ * it a listen socket
+ *
+ * @param addr the address to bind to
+ * @param addrlen the length of the addr
+ * @param backlog the max length of the pending connections.  This will be
+ *          passed to listen()
+ * @return the socket's fd; -1 on error
+ */
+int
+open_listen_socket (struct sockaddr *addr, const socklen_t addrlen, int 
backlog);
+
+
 #endif /* #ifndef MSH_UTIL_H */
 /* end of MSH_UTIL_H */




reply via email to

[Prev in Thread] Current Thread [Next in Thread]