[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] r10796: IOCP Loader code finished (testing ongoing) Current issue se (in libevent-urz/trunk: loaders sample)



Author: Urz
Date: 2007-07-12 07:08:55 -0400 (Thu, 12 Jul 2007)
New Revision: 10796

Added:
   libevent-urz/trunk/sample/IOCPconnector.c
   libevent-urz/trunk/sample/IOCPlistener.c
Modified:
   libevent-urz/trunk/loaders/IOCPloader.c
   libevent-urz/trunk/loaders/IOCPloader.h
   libevent-urz/trunk/sample/IOCPloader-test.c
   libevent-urz/trunk/sample/Makefile.am
   libevent-urz/trunk/sample/Makefile.in
Log:
IOCP Loader code finished (testing ongoing)
Current issue seems to be a deadlock on listLock.
Test code written
Note: May need to rewrite the loader/sa_bufferevents to remove the write polling loop, may be too CPU inefficient?

Modified: libevent-urz/trunk/loaders/IOCPloader.c
===================================================================
--- libevent-urz/trunk/loaders/IOCPloader.c	2007-07-12 05:45:02 UTC (rev 10795)
+++ libevent-urz/trunk/loaders/IOCPloader.c	2007-07-12 11:08:55 UTC (rev 10796)
@@ -113,6 +113,8 @@
     SOCKET workaround;
     int i;
     
+    listLock = mutex_new();
+    
     // Set up the IO Completion Port.
     // IOCPS.cpp:155 bRet&=CreateCompletionPort();
     // According to http://msdn2.microsoft.com/en-us/library/aa363862.aspx
@@ -133,24 +135,26 @@
 
     Threads[NO_WORKERS] = CreateThread(NULL, 0, &iocp_writer_thread, NULL, 0, NULL);
     
-    listLock = mutex_new();
 }
 
 DWORD WINAPI iocp_writer_thread(LPVOID pParam) {
     DWORD listpos;
     size_t unloaded;
     DWORD WSASendFlags = 0;
+    DWORD localListSize;
     
     while(1) {
         ev_lock(listLock);
         // Need this lock to read the listSize
+        localListSize = listSize;
+        ev_unlock(listLock);
+        Sleep(1000);
         
-        for(listpos = 0; listpos < listSize; listpos++) {
-        
-            ev_unlock(listLock);
+        for(listpos = 0; listpos < localListSize; listpos++) {
+            
             ev_lock(connList[listpos].lock);
             
-            if(connList[listpos].canSend) {
+            if(connList[listpos].canSend && connList[listpos].inUse) {
                 // grab data that needs to be sent
                 unloaded = sa_bufferevent_unload(connList[listpos].localbuf,
                         connList[listpos].sendbuf->buf, SUGGESTED_BUF_SIZE);
@@ -179,10 +183,7 @@
                     NULL
                     // no completion routine
                 );
-                ev_lock(listLock);
-                // read the listSize
             }
-            ev_unlock(listLock);
             ev_unlock(connList[listpos].lock);
         }
     }

Modified: libevent-urz/trunk/loaders/IOCPloader.h
===================================================================
--- libevent-urz/trunk/loaders/IOCPloader.h	2007-07-12 05:45:02 UTC (rev 10795)
+++ libevent-urz/trunk/loaders/IOCPloader.h	2007-07-12 11:08:55 UTC (rev 10796)
@@ -8,6 +8,7 @@
 void IOCPLoaderInit(void);
 DWORD WINAPI iocp_worker_thread(LPVOID);
 DWORD WINAPI iocp_writer_thread(LPVOID);
+int IOCPloader_bind(SOCKET *, struct sa_bufferevent *);
 
 #define SUGGESTED_BUF_SIZE 4096
 

Added: libevent-urz/trunk/sample/IOCPconnector.c
===================================================================
--- libevent-urz/trunk/sample/IOCPconnector.c	                        (rev 0)
+++ libevent-urz/trunk/sample/IOCPconnector.c	2007-07-12 11:08:55 UTC (rev 10796)
@@ -0,0 +1,6 @@
+#include "IOCPloader-test.c"
+
+int main() {
+    connector();
+    return 0;
+}
\ No newline at end of file

Added: libevent-urz/trunk/sample/IOCPlistener.c
===================================================================
--- libevent-urz/trunk/sample/IOCPlistener.c	                        (rev 0)
+++ libevent-urz/trunk/sample/IOCPlistener.c	2007-07-12 11:08:55 UTC (rev 10796)
@@ -0,0 +1,6 @@
+#include "IOCPloader-test.c"
+
+int main() {
+    listener();
+    return 0;
+}
\ No newline at end of file

Modified: libevent-urz/trunk/sample/IOCPloader-test.c
===================================================================
--- libevent-urz/trunk/sample/IOCPloader-test.c	2007-07-12 05:45:02 UTC (rev 10795)
+++ libevent-urz/trunk/sample/IOCPloader-test.c	2007-07-12 11:08:55 UTC (rev 10796)
@@ -26,7 +26,11 @@
  */
  
  /*
-  * Comment here
+  * On Windows and all kinds of lame:
+  * Windows has *no* fork, or anything which emulates fork.
+  * The closest is threading, or "CreateProcess" which is like fork() + exec()
+  * Thus, this file contains all code for both processes and is included from
+  * each processes' main c file.
   */
 
 #include <Winsock2.h>
@@ -37,6 +41,7 @@
 #include <unistd.h>
 
 #define BUF_SIZE 1000
+#define LISTEN_PORT 1025
 
 void gen_pattern_a(char *buf, size_t len) {
     size_t upto;
@@ -62,7 +67,7 @@
     }
 }
 
-int check_pattern_a(char *buf, size_t len) {
+int check_pattern_b(char *buf, size_t len) {
     size_t upto;
     for(upto = 0; upto < len; upto++) {
         if(buf[upto] != 'b') {
@@ -72,53 +77,166 @@
     return 1;
 }
 
+// check incoming data
+void listener_on_read(struct sa_bufferevent *sabe, void *isnull) {
+    char buf[BUF_SIZE+1];
+    size_t len_read;
+    
+    do {
+        len_read = sa_bufferevent_read(sabe, buf, BUF_SIZE);
+    
+        if(!check_pattern_b(buf, len_read)) {
+            buf[BUF_SIZE] = '\0';
+            printf("Recieved buffer failed pattern check b: recieved %s\n", buf);
+            exit(0);
+        }
+    } while (len_read != 0);
+    
+    printf("R");
+}
+
+// when outgoing data is sent, queue up more.
+void listener_on_write(struct sa_bufferevent *sabe, void *isnull) {
+    char buf[BUF_SIZE+1];
+    size_t len_read;
+    
+    gen_pattern_a(buf, BUF_SIZE);
+    sa_bufferevent_write(sabe, buf, BUF_SIZE);
+    
+    printf("W");
+}
+
 void listener() {
     WSADATA wsaData;
     struct sa_bufferevent* lsabe;
+    SOCKET Listen;
+    struct sockaddr_in listenAddr;
+    SOCKET Accept;
+    int bindingHandle = -1;
+    char buf[BUF_SIZE];
+    int error;
     
+    event_init();
+    
+    lsabe = sa_bufferevent_new(listener_on_read, NULL, NULL, NULL);
+    // Obviously one or more of these has to be changed to be not-null
+    
     WSAStartup(MAKEWORD( 2, 2 ), &wsaData);
-    event_init();
+    IOCPLoaderInit();
+    
+    Listen = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
+    
+    if(Listen == INVALID_SOCKET) {
+        printf("Oh noes! WSASocket failed\n");
+        exit(0);
+    }
+    
+    listenAddr.sin_family = AF_INET;
+    listenAddr.sin_port = htons(LISTEN_PORT);
+    listenAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+
+    if(bind(Listen, (struct sockaddr*) &listenAddr, sizeof(listenAddr)) == SOCKET_ERROR) {
+        printf("Oh noes! Bind failed\n");
+        exit(0);
+    }
+
+    if(listen(Listen, 1) == SOCKET_ERROR) {
+        printf("Oh noes! Listen failed\n");
+        exit(0);
+    }
+    
+    printf("Listening...\n");
+
+    Accept = accept(Listen, NULL, NULL);
+    if (Accept == INVALID_SOCKET) {
+        printf("Oh noes! Accept failed\n");
+        exit(0);
+    }
+
+    printf("Client Accepted...\n");
+
+    bindingHandle = IOCPloader_bind(&Accept, lsabe);
+    printf("IOCPLoader Bound (%d)\n", bindingHandle);
+    
+    gen_pattern_a(buf, BUF_SIZE);
+    printf("Generating Initial Pattern\n");
+    
+    sa_bufferevent_write(lsabe, buf, BUF_SIZE);
+    printf("Writing to buffer\n");
+    
+    printf("Starting Dispatch\n");
+    error = event_dispatch();
+    printf("Event dispach returned %d - error?\n", error);
 }
 
 void connector_on_read(struct sa_bufferevent *sabe, void *isnull) {
     char buf[BUF_SIZE+1];
     size_t len_read;
     
-    len_read = sa_bufferevent_read(sabe, buf, BUF_SIZE);
+    do {
+        len_read = sa_bufferevent_read(sabe, buf, BUF_SIZE);
     
-    if(!check_pattern_a(buf, len_read)) {
-        buf[BUF_SIZE] = '\0';
-        printf("Recieved buffer failed pattern check a: recieved %s\n", buf);
-        exit(0);
-    }
+        if(!check_pattern_a(buf, len_read)) {
+            buf[BUF_SIZE] = '\0';
+            printf("Recieved buffer failed pattern check a: recieved %s\n", buf);
+            exit(0);
+        }
+    } while (len_read != 0);
     
     gen_pattern_b(buf, BUF_SIZE);
     sa_bufferevent_write(sabe, buf, BUF_SIZE);
+    
+    printf(".");
 }
     
 
 void connector() {
     WSADATA wsaData;
     struct sa_bufferevent* csabe;
+    struct sockaddr_in socketAddr;
+    struct hostent* hostp;
+    struct in_addr* ipAddress;
+    SOCKET Connect;
+    int bindingHandle = -1;
+    int error;
+    int conret;
     
-    Sleep(10000);
-    // Wait for listener to set up.
-    
     WSAStartup(MAKEWORD( 2, 2 ), &wsaData);
+    IOCPLoaderInit();
     event_init();
     
     csabe = sa_bufferevent_new(connector_on_read, NULL, NULL, NULL);
     
-}
+    hostp = gethostbyname("localhost");
+    // It may be depriciated, but it's a lot easier to use than getaddrinfo
+    ipAddress = (struct in_addr*)hostp->h_addr_list[0];
 
+    socketAddr.sin_family = AF_INET;
+    socketAddr.sin_port = htons(LISTEN_PORT);
+    socketAddr.sin_addr.s_addr = ipAddress->s_addr;
 
-int main (int argc, char **argv)
-{
-    if(fork()) {
-        listener();
+    Connect = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
+    if(Connect == INVALID_SOCKET) {
+        printf("Oh noes! WSASocket failed\n");
+        exit(0);
+    }
+
+    printf("Connecting...\n");
+    conret = connect(Connect, (struct sockaddr*)&socketAddr, sizeof(socketAddr));
+    if(conret == SOCKET_ERROR) {
+        printf("Oh noes! Connect failed\n");
+        exit(0);
     } else {
-        connector();
+        printf("conret: %d\n", conret);
     }
     
-    return 0;
+    printf("Connected.\n");
+    
+    bindingHandle = IOCPloader_bind(&Connect, csabe);
+    
+    printf("IOCPLoader Bound (%d)\n", bindingHandle);
+    
+    printf("Starting Event Dispatch\n");
+    error = event_dispatch();
+    printf("Event dispach returned %d - error?\n", error);
 }

Modified: libevent-urz/trunk/sample/Makefile.am
===================================================================
--- libevent-urz/trunk/sample/Makefile.am	2007-07-12 05:45:02 UTC (rev 10795)
+++ libevent-urz/trunk/sample/Makefile.am	2007-07-12 11:08:55 UTC (rev 10796)
@@ -5,13 +5,18 @@
 CFLAGS = -I../compat -g
 
 #noinst_PROGRAMS = event-test time-test signal-test
-noinst_PROGRAMS = time-test signal-test sa_evbuffer-test
+noinst_PROGRAMS = time-test signal-test sa_evbuffer-test IOCPlistener IOCPconnector
 
 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
+IOCPlistener_sources = IOCPloader-test.c IOCPlistener.c
+IOCPconnector_sources = IOCPloader-test.c IOCPconnector.c
 
+IOCPlistener_CFLAGS = -g
+IOCPconnector_CFLAGS = -g
+
 verify:
 
 DISTCLEANFILES = *~

Modified: libevent-urz/trunk/sample/Makefile.in
===================================================================
--- libevent-urz/trunk/sample/Makefile.in	2007-07-12 05:45:02 UTC (rev 10795)
+++ libevent-urz/trunk/sample/Makefile.in	2007-07-12 11:08:55 UTC (rev 10796)
@@ -138,22 +138,38 @@
 CPPFPLAGS = -I.. 
 
 #noinst_PROGRAMS = event-test time-test signal-test
-noinst_PROGRAMS = time-test signal-test sa_evbuffer-test
+noinst_PROGRAMS = time-test signal-test sa_evbuffer-test IOCPlistener IOCPconnector
 
 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
+IOCPlistener_sources = IOCPloader-test.c IOCPlistener.c
+IOCPconnector_sources = IOCPloader-test.c IOCPconnector.c
 
+IOCPlistener_CFLAGS = -g
+IOCPconnector_CFLAGS = -g
+
 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) \
-	sa_evbuffer-test$(EXEEXT)
+	sa_evbuffer-test$(EXEEXT) IOCPlistener$(EXEEXT) \
+	IOCPconnector$(EXEEXT)
 PROGRAMS = $(noinst_PROGRAMS)
 
+IOCPconnector_SOURCES = IOCPconnector.c
+IOCPconnector_OBJECTS = IOCPconnector-IOCPconnector.$(OBJEXT)
+IOCPconnector_LDADD = $(LDADD)
+IOCPconnector_DEPENDENCIES = ../libevent.la
+IOCPconnector_LDFLAGS =
+IOCPlistener_SOURCES = IOCPlistener.c
+IOCPlistener_OBJECTS = IOCPlistener-IOCPlistener.$(OBJEXT)
+IOCPlistener_LDADD = $(LDADD)
+IOCPlistener_DEPENDENCIES = ../libevent.la
+IOCPlistener_LDFLAGS =
 sa_evbuffer_test_SOURCES = sa_evbuffer-test.c
 sa_evbuffer_test_OBJECTS = sa_evbuffer-test.$(OBJEXT)
 sa_evbuffer_test_LDADD = $(LDADD)
@@ -180,9 +196,10 @@
 CCLD = $(CC)
 LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
 	$(AM_LDFLAGS) $(LDFLAGS) -o $@
-DIST_SOURCES = sa_evbuffer-test.c signal-test.c time-test.c
+DIST_SOURCES = IOCPconnector.c IOCPlistener.c sa_evbuffer-test.c \
+	signal-test.c time-test.c
 DIST_COMMON = Makefile.am Makefile.in
-SOURCES = sa_evbuffer-test.c signal-test.c time-test.c
+SOURCES = IOCPconnector.c IOCPlistener.c sa_evbuffer-test.c signal-test.c time-test.c
 
 all: all-am
 
@@ -200,6 +217,14 @@
 	  echo " rm -f $$p $$f"; \
 	  rm -f $$p $$f ; \
 	done
+IOCPconnector-IOCPconnector.$(OBJEXT): IOCPconnector.c
+IOCPconnector$(EXEEXT): $(IOCPconnector_OBJECTS) $(IOCPconnector_DEPENDENCIES) 
+	@rm -f IOCPconnector$(EXEEXT)
+	$(LINK) $(IOCPconnector_LDFLAGS) $(IOCPconnector_OBJECTS) $(IOCPconnector_LDADD) $(LIBS)
+IOCPlistener-IOCPlistener.$(OBJEXT): IOCPlistener.c
+IOCPlistener$(EXEEXT): $(IOCPlistener_OBJECTS) $(IOCPlistener_DEPENDENCIES) 
+	@rm -f IOCPlistener$(EXEEXT)
+	$(LINK) $(IOCPlistener_LDFLAGS) $(IOCPlistener_OBJECTS) $(IOCPlistener_LDADD) $(LIBS)
 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)
@@ -225,6 +250,24 @@
 .c.lo:
 	$(LTCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
 
+IOCPconnector-IOCPconnector.o: IOCPconnector.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(IOCPconnector_CFLAGS) $(CFLAGS) -c -o IOCPconnector-IOCPconnector.o `test -f 'IOCPconnector.c' || echo '$(srcdir)/'`IOCPconnector.c
+
+IOCPconnector-IOCPconnector.obj: IOCPconnector.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(IOCPconnector_CFLAGS) $(CFLAGS) -c -o IOCPconnector-IOCPconnector.obj `if test -f 'IOCPconnector.c'; then $(CYGPATH_W) 'IOCPconnector.c'; else $(CYGPATH_W) '$(srcdir)/IOCPconnector.c'`
+
+IOCPconnector-IOCPconnector.lo: IOCPconnector.c
+	$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(IOCPconnector_CFLAGS) $(CFLAGS) -c -o IOCPconnector-IOCPconnector.lo `test -f 'IOCPconnector.c' || echo '$(srcdir)/'`IOCPconnector.c
+
+IOCPlistener-IOCPlistener.o: IOCPlistener.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(IOCPlistener_CFLAGS) $(CFLAGS) -c -o IOCPlistener-IOCPlistener.o `test -f 'IOCPlistener.c' || echo '$(srcdir)/'`IOCPlistener.c
+
+IOCPlistener-IOCPlistener.obj: IOCPlistener.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(IOCPlistener_CFLAGS) $(CFLAGS) -c -o IOCPlistener-IOCPlistener.obj `if test -f 'IOCPlistener.c'; then $(CYGPATH_W) 'IOCPlistener.c'; else $(CYGPATH_W) '$(srcdir)/IOCPlistener.c'`
+
+IOCPlistener-IOCPlistener.lo: IOCPlistener.c
+	$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(IOCPlistener_CFLAGS) $(CFLAGS) -c -o IOCPlistener-IOCPlistener.lo `test -f 'IOCPlistener.c' || echo '$(srcdir)/'`IOCPlistener.c
+
 mostlyclean-libtool:
 	-rm -f *.lo