ayttm-commits
[Top][All Lists]
Advanced

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

[Ayttm-commits] CVS: ayttm/src tcp_util.c,1.1,1.2 tcp_util.h,1.1,1.2


From: Philip S Tellis <address@hidden>
Subject: [Ayttm-commits] CVS: ayttm/src tcp_util.c,1.1,1.2 tcp_util.h,1.1,1.2
Date: Fri, 07 Feb 2003 05:02:50 -0500

Update of /cvsroot/ayttm/ayttm/src
In directory subversions:/tmp/cvs-serv19666/src

Modified Files:
        tcp_util.c tcp_util.h 
Log Message:
async connect

Index: tcp_util.c
===================================================================
RCS file: /cvsroot/ayttm/ayttm/src/tcp_util.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- tcp_util.c  7 Feb 2003 08:25:33 -0000       1.1
+++ tcp_util.c  7 Feb 2003 10:02:44 -0000       1.2
@@ -33,9 +33,21 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
 #include <errno.h>
-#include "tcp_util.h"  /* so the compiler tells us about mismatches */
-/* we should also use the proxy here */
+#include <values.h>
+
+#include "globals.h"
+#include "debug.h"
+#include "llist.h"
+#include "plugin_api.h"
+
+
+/* so the compiler tells us about mismatches */
+#include "tcp_util.h"
+
 
 /**
  * ay_socket_new
@@ -57,21 +69,20 @@
 
        if(last_host[0] || strcasecmp(last_host, host)!=0) {
                if(!(server = gethostbyname(host))) {
-                       /*WARNING(("failed to look up server (%s:%d)\n%d: %s", 
-                                               host, port,
-                                               h_errno, strerror(h_errno)));*/
                        errno=h_errno;
+                       eb_debug(DBG_CORE, "failed to look up server 
(%s:%d)\n%d: %s", 
+                                               host, port, errno, 
strerror(errno));
                        return -1;
                }
                strncpy(last_host, host, 255);
        }
 
        if((servfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
-               /*WARNING(("Socket create error (%d): %s", errno, 
strerror(errno)));*/
+               eb_debug(DBG_CORE, "Socket create error (%d): %s", errno, 
strerror(errno));
                return -1;
        }
 
-       /*LOG(("connecting to %s:%d\n", host, port));*/
+       eb_debug(DBG_CORE, "connecting to %s:%d\n", host, port);
 
        for (p = server->h_addr_list; *p; p++)
        {
@@ -80,7 +91,7 @@
                memcpy(&serv_addr.sin_addr.s_addr, *p, server->h_length);
                serv_addr.sin_port = htons(port);
 
-               /*LOG(("trying %s", *p));*/
+               eb_debug(DBG_CORE, "trying %s", *p);
                if(connect(servfd, (struct sockaddr *) &serv_addr, 
                                        sizeof(serv_addr)) == -1) {
 #ifdef __MINGW32__
@@ -95,13 +106,12 @@
                                break;
                        }
                } else {
-                       /*LOG(("connected"));*/
+                       eb_debug(DBG_CORE, "connected");
                        return servfd;
                }
        }
 
-       /*WARNING(("Could not connect to %s:%d\n%d:%s", host, port, errno, 
-                               strerror(errno)));*/
+       eb_debug(DBG_CORE, "Could not connect to %s:%d\n%d:%s", host, port, 
errno, strerror(errno));
        close(servfd);
        return -1;
 }
@@ -150,4 +160,136 @@
        return (n);
 }
 
+
+struct connect_callback_data {
+       ay_socket_callback callback;
+       void * callback_data;
+
+       int ebi_tag;
+       int tag;
+};
+
+static LList * pending_connects;
+static int tag_pool=0;
+
+static void destroy_pending_connect(struct connect_callback_data * ccd)
+{
+       eb_input_remove(ccd->ebi_tag);
+       free(ccd);
+}
+
+static void connect_complete(void *data, int source, eb_input_condition 
condition)
+{
+       struct connect_callback_data *ccd = data;
+       int error, err_size = sizeof(error);
+       const ay_socket_callback callback = ccd->callback;
+       void * callback_data = ccd->callback_data;
+
+       pending_connects = l_list_remove(pending_connects, ccd);
+       destroy_pending_connect(ccd);
+
+       getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &err_size);
+
+       if(error) {
+               close(source);
+               source = -1;
+       }
+
+       callback(source, error, callback_data);
+}
+
+/**
+ * ay_socket_cancel_async
+ * @tag: a tag returned by ay_socket_new_async
+ *
+ * Description: cancels a pending connect.  Does nothing if the
+ * connect already completed or was never requested.
+ **/
+void ay_socket_cancel_async(int tag)
+{
+       LList * l;
+
+       for(l = pending_connects; l; l=l->next) {
+               struct connect_callback_data * ccd = l->data;
+               if(ccd->tag == tag) {
+                       pending_connects = l_list_remove_link(pending_connects, 
l);
+                       destroy_pending_connect(ccd);
+                       free(l);
+                       /* if this was the last entry, decrement tag_pool */
+                       if(tag == tag_pool)
+                               tag_pool--;
+                       return;
+               }
+       }
+}
+
+/**
+ * ay_socket_new_async
+ * @host: The host to connect to
+ * @port: The port to connect on
+ * @callback: The callback function to call after connect completes
+ * @callback_data: Callback data to pass to the callback function
+ *
+ * Description: Asynchronously connect a socket to the given host and 
+ * port.  NOTE: The callback function may get called before this
+ * function returns.  Call ay_socket_cancel_async to cancel a connect
+ * that hasn't yet called back.  Connects that callback do not need
+ * to be cancelled.
+ *
+ * Returns:  0 if connect succeeded immediately (callback is already called);
+ * -1 if connect failed immediately (callback is already called with errno);
+ * a tag that identifies the pending connect and can be used to cancel it.
+ **/
+int ay_socket_new_async(const char * host, int port, ay_socket_callback 
callback, void * callback_data)
+{
+       struct sockaddr_in serv_addr;
+       static struct hostent *server;
+       int servfd;
+       struct connect_callback_data * ccd;
+       int error;
+
+       if(tag_pool >= MAXINT)
+               return -1;
+
+       if(!(server = gethostbyname(host))) {
+               errno=h_errno;
+               eb_debug(DBG_CORE, "failed to look up server (%s:%d)\n%d: %s", 
+                                       host, port, errno, strerror(errno));
+               return -1;
+       }
+
+       if((servfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+               eb_debug(DBG_CORE, "Socket create error (%d): %s", errno, 
strerror(errno));
+               return -1;
+       }
+
+       fcntl(servfd, F_SETFL, O_NONBLOCK);
+       
+       eb_debug(DBG_CORE, "connecting to %s:%d\n", host, port);
+
+       memset(&serv_addr, 0, sizeof(serv_addr));
+       serv_addr.sin_family = AF_INET;
+       memcpy(&serv_addr.sin_addr.s_addr, *server->h_addr_list, 
server->h_length);
+       serv_addr.sin_port = htons(port);
+
+       error = connect(servfd, (struct sockaddr *) &serv_addr, 
sizeof(serv_addr));
+
+       if(!error) {
+               callback(servfd, 0, callback_data);
+               return 0;
+       } else if(error == -1 && errno == EINPROGRESS) {
+               ccd = calloc(1, sizeof(struct connect_callback_data));
+               ccd->callback = callback;
+               ccd->callback_data = callback_data;
+               ccd->tag = ++tag_pool;
+
+               pending_connects = l_list_append(pending_connects, ccd);
+               ccd->ebi_tag = eb_input_add(servfd, EB_INPUT_WRITE, 
connect_complete, ccd);
+               return ccd->tag;
+       } else {
+               close(servfd);
+               callback(-1, errno, callback_data);
+               return -1;
+       }
+}
 

Index: tcp_util.h
===================================================================
RCS file: /cvsroot/ayttm/ayttm/src/tcp_util.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- tcp_util.h  7 Feb 2003 08:25:33 -0000       1.1
+++ tcp_util.h  7 Feb 2003 10:02:45 -0000       1.2
@@ -31,7 +31,24 @@
 #ifndef __TCP_UTIL_H__
 #define __TCP_UTIL_H__
 
-int ay_socket_new(const char * host, int port);
-int ay_tcp_readline(char * buff, int maxlen, int fd);
+/**
+ * @fd: file descriptor to connected socket; -1 if connect fails
+ * @error: 0 on success, else one of the error values returned by connect
+ * @callback_data: callback_data passed to the ay_socket_new_async function
+ **/
+typedef void ( *ay_socket_callback )(int fd, int error, void *callback_data);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int  ay_socket_new(const char * host, int port);
+int  ay_socket_new_async(const char * host, int port, ay_socket_callback 
callback, void * callback_data);
+void ay_socket_cancel_async(int tag);
+int  ay_tcp_readline(char * buff, int maxlen, int fd);
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif





reply via email to

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