[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] r10530: Sample code written, libevent + sample code compiles. Doesn' (in libevent-urz/trunk: . WIN32-Code sample)
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;
+}