[or-cvs] r10530: Sample code written, libevent + sample code compiles. Doesn' (in libevent-urz/trunk: . WIN32-Code sample)

Urz at seul.org Urz at seul.org
Fri Jun 8 09:30:59 UTC 2007


Author: Urz
Date: 2007-06-08 05:30:58 -0400 (Fri, 08 Jun 2007)
New Revision: 10530

Modified:
   libevent-urz/trunk/WIN32-Code/misc.c
   libevent-urz/trunk/WIN32-Code/misc.h
   libevent-urz/trunk/buffer.c
   libevent-urz/trunk/event.h
   libevent-urz/trunk/http.c
   libevent-urz/trunk/sa_evbuffer.c
   libevent-urz/trunk/sample/Makefile.in
   libevent-urz/trunk/sample/sa_evbuffer-test.c
Log:
Sample code written, libevent + sample code compiles. Doesn't yet work, select() returns 0 and does not call the set event. Must find out why.

Modified: libevent-urz/trunk/WIN32-Code/misc.c
===================================================================
--- libevent-urz/trunk/WIN32-Code/misc.c	2007-06-08 09:24:28 UTC (rev 10529)
+++ libevent-urz/trunk/WIN32-Code/misc.c	2007-06-08 09:30:58 UTC (rev 10530)
@@ -3,6 +3,7 @@
 #include <windows.h>
 #include <sys/timeb.h>
 #include <time.h>
+#include <Winsock2.h>
 
 #ifdef __GNUC__
 /*our prototypes for timeval and timezone are in here, just in case the above
@@ -65,6 +66,7 @@
 		return (dwBytesWritten);
 }
 
+/*
 int
 socketpair(int d, int type, int protocol, int *sv)
 {
@@ -73,7 +75,7 @@
 	HANDLE fd;
 	DWORD dwMode;
 	sprintf(buf, "\\\\.\\pipe\\levent-%d", count++);
-	/* Create a duplex pipe which will behave like a socket pair */
+	 Create a duplex pipe which will behave like a socket pair 
 	fd = CreateNamedPipe(buf, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_NOWAIT, 
 		PIPE_UNLIMITED_INSTANCES, 4096, 4096, 0, NULL);
 	if (fd == INVALID_HANDLE_VALUE)
@@ -89,3 +91,103 @@
 
 	return (0);
 }
+*/
+
+
+/* libevent's fake socketpair is broken, so I borrowed the one from tor */
+int
+socketpair(int family, int type, int protocol, int fd[2])
+{
+    /* This socketpair does not work when localhost is down. So
+     * it's really not the same thing at all. But it's close enough
+     * for now, and really, when localhost is down sometimes, we
+     * have other problems too.
+     */
+    int listener = -1;
+    int connector = -1;
+    int acceptor = -1;
+    struct sockaddr_in listen_addr;
+    struct sockaddr_in connect_addr;
+    int size;
+    int saved_errno = -1;
+
+    if (protocol
+#ifdef AF_UNIX
+        || family != AF_UNIX
+#endif
+        ) {
+#ifdef MS_WINDOWS
+      return -WSAEAFNOSUPPORT;
+#else
+      return -EAFNOSUPPORT;
+#endif
+    }
+    if (!fd) {
+      return -EINVAL;
+    }
+
+    listener = socket(AF_INET, type, 0);
+    if (listener < 0)
+      return -socket_errno(-1);
+    memset(&listen_addr, 0, sizeof(listen_addr));
+    listen_addr.sin_family = AF_INET;
+    listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+    listen_addr.sin_port = 0;   /* kernel chooses port.  */
+    if (bind(listener, (struct sockaddr *) &listen_addr, sizeof (listen_addr))
+        == -1)
+      goto tidy_up_and_fail;
+    if (listen(listener, 1) == -1)
+      goto tidy_up_and_fail;
+
+    connector = socket(AF_INET, type, 0);
+    if (connector < 0)
+      goto tidy_up_and_fail;
+    /* We want to find out the port number to connect to.  */
+    size = sizeof(connect_addr);
+    if (getsockname(listener, (struct sockaddr *) &connect_addr, &size) == -1)
+      goto tidy_up_and_fail;
+    if (size != sizeof (connect_addr))
+      goto abort_tidy_up_and_fail;
+    if (connect(connector, (struct sockaddr *) &connect_addr,
+                sizeof(connect_addr)) == -1)
+      goto tidy_up_and_fail;
+
+    size = sizeof(listen_addr);
+    acceptor = accept(listener, (struct sockaddr *) &listen_addr, &size);
+    if (acceptor < 0)
+      goto tidy_up_and_fail;
+    if (size != sizeof(listen_addr))
+      goto abort_tidy_up_and_fail;
+    closesocket(listener);
+    /* Now check we are talking to ourself by matching port and host on the
+       two sockets.  */
+    if (getsockname(connector, (struct sockaddr *) &connect_addr, &size) == -1)
+      goto tidy_up_and_fail;
+    if (size != sizeof (connect_addr)
+        || listen_addr.sin_family != connect_addr.sin_family
+        || listen_addr.sin_addr.s_addr != connect_addr.sin_addr.s_addr
+        || listen_addr.sin_port != connect_addr.sin_port) {
+      goto abort_tidy_up_and_fail;
+    }
+    fd[0] = connector;
+    fd[1] = acceptor;
+
+    return 0;
+
+  abort_tidy_up_and_fail:
+#ifdef MS_WINDOWS
+    saved_errno = WSAECONNABORTED;
+#else
+    saved_errno = ECONNABORTED; /* I hope this is portable and appropriate.  */
+#endif
+  tidy_up_and_fail:
+    if (saved_errno < 0)
+      saved_errno = errno;
+    if (listener != -1)
+      closesocket(listener);
+    if (connector != -1)
+      closesocket(connector);
+    if (acceptor != -1)
+      closesocket(acceptor);
+    return -saved_errno;
+}

Modified: libevent-urz/trunk/WIN32-Code/misc.h
===================================================================
--- libevent-urz/trunk/WIN32-Code/misc.h	2007-06-08 09:24:28 UTC (rev 10529)
+++ libevent-urz/trunk/WIN32-Code/misc.h	2007-06-08 09:30:58 UTC (rev 10530)
@@ -8,4 +8,16 @@
 int gettimeofday(struct timeval *,struct timezone *);
 #endif
 
+int socketpair(int d, int type, int protocol, int *sv);
+
+#define EMFILE 1
+#define EAFNOSUPPORT 2
+#define EPROTONOSUPPORT 3
+#define EOPNOTSUPP 4
+#define EFAULT 5
+#define EINVAL 6
+#define ECONNABORTED 7
+
+#define socket_errno(sock)       (errno)
+
 #endif

Modified: libevent-urz/trunk/buffer.c
===================================================================
--- libevent-urz/trunk/buffer.c	2007-06-08 09:24:28 UTC (rev 10529)
+++ libevent-urz/trunk/buffer.c	2007-06-08 09:30:58 UTC (rev 10530)
@@ -40,10 +40,6 @@
 #include <sys/time.h>
 #endif
 
-#ifdef HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -59,6 +55,17 @@
 #include <process.h>
 #endif
 
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#else
+#ifdef WIN32
+/* Windows declares FIOREAD, but has different functions to
+ * use it, so let's just pretend it's not defined
+ */
+#undef FIONREAD
+#endif
+#endif
+
 #include "event.h"
 #include "event-internal.h"
 

Modified: libevent-urz/trunk/event.h
===================================================================
--- libevent-urz/trunk/event.h	2007-06-08 09:24:28 UTC (rev 10529)
+++ libevent-urz/trunk/event.h	2007-06-08 09:30:58 UTC (rev 10530)
@@ -39,6 +39,7 @@
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 #include <process.h>
+/* #include "compat/sys/_time.h" */
 #undef WIN32_LEAN_AND_MEAN
 typedef unsigned char u_char;
 typedef unsigned short u_short;

Modified: libevent-urz/trunk/http.c
===================================================================
--- libevent-urz/trunk/http.c	2007-06-08 09:24:28 UTC (rev 10529)
+++ libevent-urz/trunk/http.c	2007-06-08 09:30:58 UTC (rev 10530)
@@ -1238,9 +1238,11 @@
 		}
 	}
 		
+    /*
 	event_debug(("%s: bytes to read: %d (in buffer %d)\n",
 		__func__, req->ntoread,
 		EVBUFFER_LENGTH(evcon->input_buffer)));
+    */
 
 	return (0);
 }

Modified: libevent-urz/trunk/sa_evbuffer.c
===================================================================
--- libevent-urz/trunk/sa_evbuffer.c	2007-06-08 09:24:28 UTC (rev 10529)
+++ libevent-urz/trunk/sa_evbuffer.c	2007-06-08 09:30:58 UTC (rev 10530)
@@ -55,7 +55,7 @@
 #include <Winsock2.h>
 #include <windows.h>
 #include <process.h>
-#include "WIN32-Code/misc.c"
+#include "WIN32-Code/misc.h"
 #undef WIN32_LEAN_AND_MEAN
 #endif
 
@@ -73,7 +73,9 @@
 static struct event evbuffer_del_event;
 
 static void notify() {
+    printf("Notify Called\n");
     if(del_notifier_status == NOTIFIER_READY) {
+        printf("Notifying\n");
         write(del_notifier[EVBUFFER_END], ".", 1);
         del_notifier_status = NOTIFIER_PENDING;
     }
@@ -85,6 +87,8 @@
     char readdata;
     ssize_t readlen;
     
+    printf("Delayed Callback Called\n");
+    
     /* Read data out of socketpair */
     readlen = read(fd, &readdata, 1);
     
@@ -111,13 +115,16 @@
 /* Code to do setup / initialization of the evbuffer delayed callbacks 
  * Initially copied from ev_signal_init, then modified.
  */
-void evbuffer_del_init(void) 
+void sa_bufferevent_init(void) 
 {
     #ifdef WIN32
     u_long ioarg = 1;
     #endif
     
+    printf("sa_evbuffer initializing\n");
+    
     if(del_notifier_status != NOTIFIER_UNINIT) {
+        printf("Initialized already, returning\n");
         return;
     }
     
@@ -125,28 +132,35 @@
     LIST_INIT(&bufev_list_head);
     
     /* create the delayed notifier socketpair */
-	/*if (socketpair(AF_UNIX, SOCK_STREAM, 0, del_notifier) == -1) */
+	if (socketpair(AF_UNIX, SOCK_STREAM, 0, del_notifier) == -1) {
+        fprintf(stderr, "Could not create sa_bufferevent socketpair. Aborting\n");
+        exit(1);
+    }
 	/*	event_err(1, "%s: socketpair", __func__); */
 
 	FD_CLOSEONEXEC(del_notifier[0]);
 	FD_CLOSEONEXEC(del_notifier[1]);
 
     /* 
-     * sets calls to del_notifier[EVBUFFER_END] to be non-blocking
+     * sets calls to del_notifier[DISPATCH_END] to be non-blocking
      */
     #ifdef WIN32
-    ioctlsocket(del_notifier[EVBUFFER_END], FIONBIO, &ioarg);
+    ioctlsocket(del_notifier[DISPATCH_END], FIONBIO, &ioarg);
     /* see http://msdn2.microsoft.com/en-us/library/ms738573.aspx */
     #else
-	fcntl(del_notifier[EVBUFFER_END], F_SETFL, O_NONBLOCK);
+	fcntl(del_notifier[DISPATCH_END], F_SETFL, O_NONBLOCK);
     #endif
     
-	event_set(&evbuffer_del_event, del_notifier[DISPATCH_END], EV_READ,
+	event_set(&evbuffer_del_event, del_notifier[DISPATCH_END], EV_READ|EV_PERSIST,
 	    del_cb, NULL);
-        /* &ev_signal); */
-    /* I can't find any documentation for this, what does it do? */
-	evbuffer_del_event.ev_flags |= EVLIST_INTERNAL;
+
+	/* evbuffer_del_event.ev_flags |= EVLIST_INTERNAL; */
     
+    if(event_add(&evbuffer_del_event, NULL) == -1) {
+        fprintf(stderr, "Could not add sa_bufferevent event to main loop. Aborting\n");
+        exit(1);
+    }
+    
     del_notifier_status = NOTIFIER_READY;
 }
 
@@ -256,8 +270,9 @@
 {
 	struct sa_bufferevent *bufev;
     
+    printf("sa_bufferevent_new called\n");
     /* Ensure delayed callbacks are set up. */
-    evbuffer_del_init();
+    sa_bufferevent_init();
 
 	if ((bufev = calloc(1, sizeof(struct sa_bufferevent))) == NULL)
 		return (NULL);
@@ -437,9 +452,6 @@
 		bufev->wm_write.high = highmark;
 	}
 
-	/* If the watermarks changed then see if we should call read again */
-	sa_bufferevent_read_pressure_cb(bufev->input,
-	    0, EVBUFFER_LENGTH(bufev->input), bufev);
 }
 
 /*

Modified: libevent-urz/trunk/sample/Makefile.in
===================================================================
--- libevent-urz/trunk/sample/Makefile.in	2007-06-08 09:24:28 UTC (rev 10529)
+++ libevent-urz/trunk/sample/Makefile.in	2007-06-08 09:30:58 UTC (rev 10530)
@@ -138,20 +138,27 @@
 CPPFPLAGS = -I.. 
 
 #noinst_PROGRAMS = event-test time-test signal-test
-noinst_PROGRAMS = time-test signal-test
+noinst_PROGRAMS = time-test signal-test sa_evbuffer-test
 
 event_test_sources = event-test.c
 time_test_sources = time-test.c
 signal_test_sources = signal-test.c
+sa_evbuffer_test_sources = sa_evbuffer-test.c
 
 DISTCLEANFILES = *~
 subdir = sample
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
-noinst_PROGRAMS = time-test$(EXEEXT) signal-test$(EXEEXT)
+noinst_PROGRAMS = time-test$(EXEEXT) signal-test$(EXEEXT) \
+	sa_evbuffer-test$(EXEEXT)
 PROGRAMS = $(noinst_PROGRAMS)
 
+sa_evbuffer_test_SOURCES = sa_evbuffer-test.c
+sa_evbuffer_test_OBJECTS = sa_evbuffer-test.$(OBJEXT)
+sa_evbuffer_test_LDADD = $(LDADD)
+sa_evbuffer_test_DEPENDENCIES = ../libevent.la
+sa_evbuffer_test_LDFLAGS =
 signal_test_SOURCES = signal-test.c
 signal_test_OBJECTS = signal-test.$(OBJEXT)
 signal_test_LDADD = $(LDADD)
@@ -173,9 +180,9 @@
 CCLD = $(CC)
 LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
 	$(AM_LDFLAGS) $(LDFLAGS) -o $@
-DIST_SOURCES = signal-test.c time-test.c
+DIST_SOURCES = sa_evbuffer-test.c signal-test.c time-test.c
 DIST_COMMON = Makefile.am Makefile.in
-SOURCES = signal-test.c time-test.c
+SOURCES = sa_evbuffer-test.c signal-test.c time-test.c
 
 all: all-am
 
@@ -193,6 +200,9 @@
 	  echo " rm -f $$p $$f"; \
 	  rm -f $$p $$f ; \
 	done
+sa_evbuffer-test$(EXEEXT): $(sa_evbuffer_test_OBJECTS) $(sa_evbuffer_test_DEPENDENCIES) 
+	@rm -f sa_evbuffer-test$(EXEEXT)
+	$(LINK) $(sa_evbuffer_test_LDFLAGS) $(sa_evbuffer_test_OBJECTS) $(sa_evbuffer_test_LDADD) $(LIBS)
 signal-test$(EXEEXT): $(signal_test_OBJECTS) $(signal_test_DEPENDENCIES) 
 	@rm -f signal-test$(EXEEXT)
 	$(LINK) $(signal_test_LDFLAGS) $(signal_test_OBJECTS) $(signal_test_LDADD) $(LIBS)

Modified: libevent-urz/trunk/sample/sa_evbuffer-test.c
===================================================================
--- libevent-urz/trunk/sample/sa_evbuffer-test.c	2007-06-08 09:24:28 UTC (rev 10529)
+++ libevent-urz/trunk/sample/sa_evbuffer-test.c	2007-06-08 09:30:58 UTC (rev 10530)
@@ -40,17 +40,21 @@
   * the data out of the sa_bufferevent and writes it to the console.
   */
 
+/*#include "compat/sys/_time.h"*/
+#include <Winsock2.h>
 #include "event.h"
 #include <stdio.h>
 #include <stdlib.h>
-#include <stdlib.h>
+#include <Windows.h>
+#include <unistd.h>
 
 struct sa_bufferevent* logpipe;
 
 void log_data(char *data) 
 {
     size_t loaded = 0;
-    size_t toload = (size_t) strlen(data);
+    size_t toload = (size_t) strlen(data)+1;
+    /* +1 to inluce the \0 */
     
     while(toload > 0) {
         loaded = sa_bufferevent_load(logpipe, data, toload);
@@ -60,7 +64,7 @@
 }
 
 #define NO_TEMPLATES 6
-char **errtemplates = 
+char *errtemplates[] = 
 {
     "[%s module] Read of uninitialized value in %s, at %s:%d (%x)\n",
     "[%s module] Write not threadsafe in %s, at %s:%d (%x)\n",
@@ -68,20 +72,20 @@
     "[%s module] Write out of bounds in %s, at %s:%d (%x)\n",
     "[%s module] Jump based on uninitialized pointer in %s at %s:%d (%x)\n",
     "[%s module] SIGSEGV raised in %s, at %s:%d (%x)\n"
-}
+};
     
 #define NO_MODULES 5
-char **modules =
+char *modules[] =
 {
     "parser",
     "IO",
     "physics",
     "UI",
     "database"
-}
+};
 
 #define NO_FUNCTIONS 10
-char **functions =
+char *functions[] =
 {
     "load()",
     "unload()",
@@ -93,10 +97,10 @@
     "calc_offset()",
     "malloc()",
     "strcat()"
-}
+};
 
 #define NO_SRC_FILES 7
-char **src_files = 
+char *src_files[] = 
 {
     "circular_buffer.c",
     "memory.c",
@@ -105,17 +109,18 @@
     "loadsave.c",
     "engine.c",
     "setup.c"
-}
+};
     
   
-void worker_thread(void) 
+DWORD WINAPI worker_thread(LPVOID nodata) 
 {
     char output[1000];
-    int count = 0;
     char *template, *module, *func, *file;
     
-    while(count < 500) {
-        count++;
+    printf("Worker thread begun\n");
+    
+    while(1) {
+        Sleep(1000);
         
         template = errtemplates[rand() % NO_TEMPLATES];
         module = modules[rand() % NO_MODULES];
@@ -124,22 +129,37 @@
         
         sprintf(output, template, module, func, file, rand() % 5000, rand());
         log_data(output);
+        
+        printf("BufPrint:");
+        printf(logpipe->input->buffer);
     }
+    return 0;
 }
 
-void logmgr_thread(void) 
+DWORD WINAPI logmgr_thread(LPVOID nodata) 
 {
-    while(1) {
-        event_dispatch();
-    }
+    int error;
+    printf("Logmgr thread begun\n");
+
+    error = event_dispatch();
+    printf("Event dispach returned %d - error?\n", error);
+
+    return 0;
 }
 
 void logmgr_thread_on_read(struct sa_bufferevent *reader, void *isnull)
 {
     static size_t indata_size = 1000;
-    static char *indata = malloc(indata_size);
-    static char *floating_ptr = indata;
+    static char *indata = NULL;
+    static char *floating_ptr = NULL;
     
+    printf("OnRead Called\n");
+    
+    if(indata == NULL) {
+        indata = malloc(indata_size);
+        floating_ptr = indata;
+    }
+    
     char *str_term;
     size_t spaceleft = (indata + indata_size) - floating_ptr;
     size_t len_read;
@@ -161,7 +181,7 @@
         /* Only output error messages from IO or UI modules. */
         if(!strncmp(indata, "[IO", 3) || !strncmp(indata, "[UI", 3)) {
             /* We should really check this for errors, but it's a demo, so who cares */
-            sa_bufferevent_write(reader, indata, (size_t) str_term - indata);
+            sa_bufferevent_write(reader, indata, (size_t) (str_term - indata));
         } else {
             /* Found a message, that's not IO or UI. Therefore, discard */
             memmove(indata, str_term+1, (size_t) (floating_ptr - (str_term+1)));
@@ -169,12 +189,54 @@
     }
 }
 
+DWORD WINAPI printer_thread(LPVOID nodata) {
+    size_t ret;
+    char data[1001];
+    char *upto;
+    
+    printf("printer thread begun\n");
+    
+    while(1) {
+        Sleep(1000);
+        
+        ret = sa_bufferevent_unload(logpipe, data, 1000);
+        
+        if(ret == 0) {
+            continue;
+        }
+        
+        data[ret+1] = '\0';
+        upto = data;
+        
+        while(upto <= (data+ret+1)) {
+            printf(upto);
+            upto += strlen(upto);
+        }
+        
+    }
+    return 0;
+}
 
+
 int
 main (int argc, char **argv)
 {
+    WSADATA wsaData;
+    HANDLE Threads[2];
+    
+    WSAStartup(MAKEWORD( 2, 2 ), &wsaData);
+    
     event_init();
     logpipe = sa_bufferevent_new(logmgr_thread_on_read, NULL, NULL, NULL);
+    printf("If you haven't read the description of what this does, (comments in the source file)");
+    printf(" you should do that now, or you will get very confused.\n");
+    Sleep(1000);
     
+    Threads[0] = CreateThread(NULL, 0, &worker_thread, NULL, 0, NULL);
+    Threads[1] = CreateThread(NULL, 0, &printer_thread, NULL, 0, NULL);
+    logmgr_thread(NULL);
     
-}
\ No newline at end of file
+    WaitForMultipleObjects(2, Threads, TRUE, INFINITE);
+    /* This should never return */
+    return 0;
+}



More information about the tor-commits mailing list