[or-cvs] r8858: added my code for the day (getting back into it ...) (bsockets/trunk/contrib/liboverlapped)

chiussi at seul.org chiussi at seul.org
Sun Oct 29 21:53:25 UTC 2006


Author: chiussi
Date: 2006-10-29 16:53:24 -0500 (Sun, 29 Oct 2006)
New Revision: 8858

Added:
   bsockets/trunk/contrib/liboverlapped/msg.c
   bsockets/trunk/contrib/liboverlapped/msg.h
Modified:
   bsockets/trunk/contrib/liboverlapped/Makefile
   bsockets/trunk/contrib/liboverlapped/cmd.c
   bsockets/trunk/contrib/liboverlapped/env.c
   bsockets/trunk/contrib/liboverlapped/env.h
   bsockets/trunk/contrib/liboverlapped/file.c
   bsockets/trunk/contrib/liboverlapped/misc.c
   bsockets/trunk/contrib/liboverlapped/misc.h
   bsockets/trunk/contrib/liboverlapped/overlapped.c
   bsockets/trunk/contrib/liboverlapped/socket.c
   bsockets/trunk/contrib/liboverlapped/socket.h
   bsockets/trunk/contrib/liboverlapped/test.c
   bsockets/trunk/contrib/liboverlapped/test.h
Log:
added my code for the day (getting back into it ...)


Modified: bsockets/trunk/contrib/liboverlapped/Makefile
===================================================================
--- bsockets/trunk/contrib/liboverlapped/Makefile	2006-10-29 17:28:34 UTC (rev 8857)
+++ bsockets/trunk/contrib/liboverlapped/Makefile	2006-10-29 21:53:24 UTC (rev 8858)
@@ -1,5 +1,5 @@
 
-overlapped_objs = env.o cmd.o list.o misc.o file.o socket.o overlapped.o
+overlapped_objs = env.o cmd.o list.o misc.o file.o socket.o overlapped.o msg.o
 
 overlapped_headers = overlapped.h misc.h
 
@@ -14,6 +14,8 @@
 test.exe: test.o liboverlapped.a test.h
 	gcc -g -o test.exe $< -L. -loverlapped -lws2_32
  
+test.o: test.c test.h
+	gcc -g -Wall -c test.c
 
 %.o: %.c $(overlapped_headers)
 	gcc -g -Wall -c $<

Modified: bsockets/trunk/contrib/liboverlapped/cmd.c
===================================================================
--- bsockets/trunk/contrib/liboverlapped/cmd.c	2006-10-29 17:28:34 UTC (rev 8857)
+++ bsockets/trunk/contrib/liboverlapped/cmd.c	2006-10-29 21:53:24 UTC (rev 8858)
@@ -85,34 +85,38 @@
 
 	cmd_next(&cmd,env);
 
-
 	if (cmd == NULL)
 		return;
 
 	cmd->wait = FALSE;
 
 	if (cmd->fd != -1) {
+
 		cmd->f = file_get(cmd->fd,env);
+
 		if (cmd->f == NULL) {
+
 			cmd_done(cmd,-1,errno);
 			cmd = NULL;
-		}
 
-		switch (cmd->f->type) {
 
-			case FT_SOCKET:
-				cmd->s = cmd->f->data;
-				ASSERT(cmd->s != NULL);
-			break;
+		} else {
 
-			default:
-				ASSERT(FALSE);
-			break;
+			switch (cmd->f->type) {
+
+				case FT_SOCKET:
+					cmd->s = cmd->f->data;
+					ASSERT(cmd->s != NULL);
+				break;
+
+				default:
+					ASSERT(FALSE);
+				break;
+			}
 		}
 	}
 
 	//todo -- check if is socket before using socket function
-
 	if (cmd != NULL) {
 
 		switch (cmd->type) {
@@ -127,15 +131,23 @@
 			break;
 
 			case CMD_SOCKET_NEW:
-				socket_new(cmd,env);
+				socket_create(cmd,env);
 			break;
 
 			case CMD_SOCKET_CONNECT:
 				socket_connect(cmd,env);
 			break;
 
+			case CMD_SOCKET_ACCEPT:
+				socket_accept(cmd,env);
+			break;
+
 			case CMD_FILE_CLOSE:
 
+				//todo
+				//we should be doing this for any system call
+				// if error, report error, then do nothing
+
 				//if there is an outstanding error, report it
 				if (cmd->f->err) {
 					out = -1;

Modified: bsockets/trunk/contrib/liboverlapped/env.c
===================================================================
--- bsockets/trunk/contrib/liboverlapped/env.c	2006-10-29 17:28:34 UTC (rev 8857)
+++ bsockets/trunk/contrib/liboverlapped/env.c	2006-10-29 21:53:24 UTC (rev 8858)
@@ -15,7 +15,7 @@
 	10
 };
 
-//make sure nothing is wrong with the options the user gave
+//todo -- make sure nothing is wrong with the options the user gave
 int env_check_options(struct _file_env_options *opt) {
 	return -1;
 }
@@ -50,6 +50,8 @@
 			break;
 		}
 	}
+
+
 }
 
 
@@ -71,6 +73,7 @@
 
 	struct _cmd cmd;
 	cmd.type = CMD_SHUTDOWN;
+	cmd.fd = -1;
 
 	cmd_post(&cmd,env);
 

Modified: bsockets/trunk/contrib/liboverlapped/env.h
===================================================================
--- bsockets/trunk/contrib/liboverlapped/env.h	2006-10-29 17:28:34 UTC (rev 8857)
+++ bsockets/trunk/contrib/liboverlapped/env.h	2006-10-29 21:53:24 UTC (rev 8858)
@@ -40,6 +40,10 @@
 	/*records the value of the last error that occured*/
 	int error;
 
+	/*records if this file has been excepted*/
+	//(we defined excepted to mean it has entered a state where it is no longer
+	// usable)
+	int excepted;
 
 };
 

Modified: bsockets/trunk/contrib/liboverlapped/file.c
===================================================================
--- bsockets/trunk/contrib/liboverlapped/file.c	2006-10-29 17:28:34 UTC (rev 8857)
+++ bsockets/trunk/contrib/liboverlapped/file.c	2006-10-29 21:53:24 UTC (rev 8858)
@@ -19,7 +19,6 @@
 	out = (struct _callback*) malloc(sizeof(struct _callback));
 
 	if (out != NULL) {
-
 		out->fun = fun;
 		out->data = data;
 	} else {
@@ -49,7 +48,7 @@
 }
 
 void file_control(struct _cmd *cmd, struct _file_env *env) {
-
+	//
 }
 
 void file_wait(struct _cmd *cmd, int state, struct _file_env *env) {
@@ -78,7 +77,9 @@
 				ASSERT(FALSE);
 			break;
 		}
+
 		CHECK(list_enqueue(cb,l) != NULL,0);
+
 	} else {
 		cmd_done(cmd,0,0);
 	}
@@ -97,7 +98,7 @@
 
 }
 
-//get and set the last error for this file
+//get and reset the last error for this file
 void file_last_error(struct _file *f, int *r) {
 	*r = f->error;
 	f->error = 0;
@@ -105,19 +106,23 @@
 
 void file_exception(struct _file *f, int code, struct _file_env *env) {
 
-	//raise readable and writable
+	if (!f->excepted) {
 
-	switch (f->type) {
+		switch (f->type) {
 
-		case FT_SOCKET:
-			//todo -- unwatch socket events
-			closesocket((SOCKET) f->handle);
-		break;
+			case FT_SOCKET:
+				//todo -- unwatch socket events
+				closesocket((SOCKET) f->handle);
+			break;
 
-		default:
-			ASSERT(FALSE);
-		break;
+			default:
+				ASSERT(FALSE);
+			break;
+		}
+
+		f->excepted = TRUE;
 	}
+
 }
 
 void file_raise(struct _file *f, int type, int code, struct _file_env *env) {
@@ -125,34 +130,54 @@
 	struct _callback *cb;
 	struct _list *l;
 
-	/*set status bit*/
-	f->ready[type] = TRUE;
+	if (code) {
 
+		/*set status bit*/
+		f->ready[type] = TRUE;
 
-	switch (type) {
+		switch (type) {
 
-		case FILE_IS_READABLE:
-			l = f->read_callbacks;
-		break;
+			case FILE_IS_READABLE:
+				l = f->read_callbacks;
+			break;
 
-		case FILE_IS_WRITABLE:
-			l = f->write_callbacks;
-		break;
+			case FILE_IS_WRITABLE:
+				l = f->write_callbacks;
+			break;
 
-		default:
-			ASSERT(FALSE);
-		break;
-	}
+			default:
+				ASSERT(FALSE);
+			break;
+		}
 
-	/*does anyone want to know we are ready?*/
-	//todo -- iterate through list, dont use queue interface
-	while (list_dequeue(&cb,l) == 0) {
-		//todo -- if an epoll pointer, requeue, do not free
-		cb->fun(cb->data,0,0);
-		cb_free(cb);
+		/*does anyone want to know we are ready?*/
+		//todo -- iterate through list, don't use queue interface
+		while (list_dequeue(&cb,l) == 0) {
+			//todo -- if an epoll pointer, requeue, do not free
+			cb->fun(cb->data,0,0);
+			cb_free(cb);
+		}
+
+	} else {
+
+		f->ready[type] = FALSE;
+		//nobody will care if we aren't ready, so don't do anything else
 	}
 }
 
+void file_read(struct _cmd *cmd, struct _file *f, void *buf, int *len, struct _file_env *env) {
+
+	//pull last message from in_q, if nothing defer
+
+}
+
+void file_write(struct _file *f, void *buf, int len, int *res) {
+
+	//if not writable, defer
+	//invoke type specific write
+
+}
+
 void file_close(struct _file *f, struct _file_env *env) {
 
 	if (f->fd != -1) {
@@ -162,12 +187,12 @@
 	}
 
 	if (f->in_buf != NULL) {
-		//todo dump in buffer
+		//todo dump messsages held in buffer
 		list_free(f->in_buf);
 	}
 
 	if (f->out_buf != NULL) {
-		//todo dump out buffer
+		//todo same as above
 		list_free(f->out_buf);
 	}
 
@@ -199,6 +224,8 @@
 	f = (struct _file*) malloc(sizeof(struct _file));
 	CHECK(f != NULL,ENOMEM);
 
+	f->error = 0;
+
 	/*init everything to bad*/
 	f->fd = -1;
 	f->type = -1;
@@ -207,6 +234,7 @@
 	f->open = FALSE;
 	f->data = NULL;
 	f->blocking = TRUE;
+	f->excepted = FALSE;
 
 	f->read_callbacks = NULL;
 	f->write_callbacks = NULL;

Modified: bsockets/trunk/contrib/liboverlapped/misc.c
===================================================================
--- bsockets/trunk/contrib/liboverlapped/misc.c	2006-10-29 17:28:34 UTC (rev 8857)
+++ bsockets/trunk/contrib/liboverlapped/misc.c	2006-10-29 21:53:24 UTC (rev 8858)
@@ -2,6 +2,12 @@
 
 #include "misc.h"
 
+HANDLE new_thread(void *fun, void *data) {
+
+	return CreateThread(NULL,0,fun,data,0,NULL);
+
+}
+
 int unixify_w32err(DWORD err) {
 
 	int out;

Modified: bsockets/trunk/contrib/liboverlapped/misc.h
===================================================================
--- bsockets/trunk/contrib/liboverlapped/misc.h	2006-10-29 17:28:34 UTC (rev 8857)
+++ bsockets/trunk/contrib/liboverlapped/misc.h	2006-10-29 21:53:24 UTC (rev 8858)
@@ -4,6 +4,7 @@
 #include <stdio.h>
 
 int unixify_w32err(DWORD err);
+HANDLE new_thread(void*,void*);
 
 #define ASSERT(X)	if (!(X)) {printf("Assertion failed: [%s]\n\t file:%s line:%d errno:%d w32err: %d\n",#X,__FILE__,__LINE__,errno,(int) GetLastError()); fflush(stdout); _exit(1); }
 

Added: bsockets/trunk/contrib/liboverlapped/msg.c
===================================================================
--- bsockets/trunk/contrib/liboverlapped/msg.c	2006-10-29 17:28:34 UTC (rev 8857)
+++ bsockets/trunk/contrib/liboverlapped/msg.c	2006-10-29 21:53:24 UTC (rev 8858)
@@ -0,0 +1,54 @@
+
+#include <windows.h>
+
+#include "overlapped.h"
+#include "misc.h"
+#include "msg.h"
+
+void msg_free(struct _msg *msg) {
+	if (msg != NULL) {
+
+		if (msg->buffer != NULL) {
+			free(msg->buffer);
+		}
+
+		free(msg);
+	}
+}
+
+struct _msg *msg_new(int size, struct _file_env *env) {
+
+	struct _msg *m;
+	int out;
+
+	out = 0;
+
+	m = (struct _msg*) malloc(sizeof(struct _msg));
+	CHECK(m != NULL,ENOMEM);
+
+	m->buffer = NULL;
+
+	m->buffer = malloc(size);
+	CHECK(m->buffer != NULL,ENOMEM);
+
+	m->buf_size = size;
+	m->data = m->buffer;
+
+	m->wo.hEvent = m;
+
+	m->wb.len = size;
+	m->wb.buf = m->buffer;
+
+	m->flag = 0;
+	m->f = NULL;
+
+	fail:
+
+	if (out == -1) {
+		msg_free(m);
+		return NULL;
+	} else {
+		return m;
+	}
+
+}


Property changes on: bsockets/trunk/contrib/liboverlapped/msg.c
___________________________________________________________________
Name: svn:executable
   + *

Added: bsockets/trunk/contrib/liboverlapped/msg.h
===================================================================
--- bsockets/trunk/contrib/liboverlapped/msg.h	2006-10-29 17:28:34 UTC (rev 8857)
+++ bsockets/trunk/contrib/liboverlapped/msg.h	2006-10-29 21:53:24 UTC (rev 8858)
@@ -0,0 +1,28 @@
+#ifndef _MSG_H_
+#define _MSG_H_
+
+#define MSG_SIZE 4096
+
+
+struct _msg {
+
+	WSABUF wb;
+	WSAOVERLAPPED wo;
+
+	struct _file_env *env;
+	struct _file *f;
+
+	char *buffer;
+	char *data;
+
+	int buf_size;
+
+	int flag;
+
+
+};
+
+struct _msg *msg_new(int, struct _file_env*);
+void msg_free(struct _msg*);
+
+#endif


Property changes on: bsockets/trunk/contrib/liboverlapped/msg.h
___________________________________________________________________
Name: svn:executable
   + *

Modified: bsockets/trunk/contrib/liboverlapped/overlapped.c
===================================================================
--- bsockets/trunk/contrib/liboverlapped/overlapped.c	2006-10-29 17:28:34 UTC (rev 8857)
+++ bsockets/trunk/contrib/liboverlapped/overlapped.c	2006-10-29 21:53:24 UTC (rev 8858)
@@ -5,6 +5,7 @@
 #include "overlapped.h"
 #include "cmd.h"
 #include "file.h"
+#include "misc.h"
 
 struct _file_env *__GLOBAL_FILE_ENV_;
 
@@ -64,6 +65,9 @@
 
 		if (cmd.wait) {
 
+			//loop around this part while defer is true. just in case ready
+			//state gets reset by another thread
+
 			cmd2.type = CMD_FILE_WAIT;
 			cmd2.fd = fd;
 			cmd2.arg[0] = (void*) FILE_IS_WRITABLE;
@@ -94,26 +98,38 @@
 
 	struct _cmd cmd;
 
-	cmd.type = CMD_SOCKET_ACCEPT;
-	cmd.fd = fd;
-	cmd.arg[0] = name;
-	cmd.arg[1] = namelen;
+	while (TRUE) {
 
-	cmd_post(&cmd,__GLOBAL_FILE_ENV_);
+		cmd.type = CMD_SOCKET_ACCEPT;
+		cmd.fd = fd;
+		cmd.arg[0] = name;
+		cmd.arg[1] = namelen;
 
-	if (cmd.ret == -1) {
+		cmd_post(&cmd,__GLOBAL_FILE_ENV_);
 
-		if (cmd.wait) {
+		if (cmd.ret == -1)  {
 
+			if (cmd.wait) {
+
+				cmd.type = CMD_FILE_WAIT;
+				cmd.fd = fd;
+				cmd.arg[0] = (void*) FILE_IS_READABLE;
+				cmd_post(&cmd,__GLOBAL_FILE_ENV_);
+
+			} else {
+				errno = cmd.err;
+				return -1;
+			}
+
 		} else {
-			errno = cmd.err;
+			return cmd.ret;
 		}
 
-	} else {
-		return cmd.ret;
 	}
 
-	return -1;
+	//wtf
+	ASSERT(FALSE);
+
 }
 
 int bbind(int fd, struct sockaddr *name, int namelen) {

Modified: bsockets/trunk/contrib/liboverlapped/socket.c
===================================================================
--- bsockets/trunk/contrib/liboverlapped/socket.c	2006-10-29 17:28:34 UTC (rev 8857)
+++ bsockets/trunk/contrib/liboverlapped/socket.c	2006-10-29 21:53:24 UTC (rev 8858)
@@ -8,9 +8,15 @@
 #include "misc.h"
 #include "cmd.h"
 #include "list.h"
+#include "msg.h"
 
 //todo -- make sure we implment ALL system calls
 
+static struct _file *socket_new_socket(SOCKET, struct _file_env*);
+static void socket_invoke_read(struct _file *, struct _socket *, struct _file_env*);
+
+//
+
 struct __connect_data {
 	struct _file *f;
 	struct _socket *s;
@@ -48,6 +54,8 @@
 
 	memcpy(cd->name,name,namelen);
 
+	cd->namelen = namelen;
+
 	cd->f = f;
 	cd->s = s;
 
@@ -92,11 +100,8 @@
 
 			return;
 		}
-
 	}
-
 	ASSERT(FALSE);
-
 }
 
 void socket_get_name(struct _cmd *cmd, struct _file_env *env) {
@@ -110,59 +115,121 @@
 	} else {
 		cmd_done(cmd,-1,unixify_w32err(WSAGetLastError()));
 	}
-
 }
 
-void socket_listen(struct _cmd *cmd, struct _file_env *env) {
+static
+int socket_queue_connection(struct _cmd *cmd,struct _file_env *env) {
 
-	int r;
+	struct __connect_data *cd;
 
-	r = listen((SOCKET) cmd->f->handle, (int) cmd->arg[0]);
+	cd = cd_new(cmd->f,cmd->s,cmd->arg[0],(int)cmd->arg[1]);
 
-	if (r != SOCKET_ERROR) {
-		cmd_done(cmd,0,0);
+	if (cd != NULL) {
+
+		if (list_enqueue(cd,env->waiting_to_connect) != NULL) {
+			return 0;
+		} else {
+			cd_free(cd);
+			return -1;
+		}
+
 	} else {
-		cmd_done(cmd,-1,unixify_w32err(WSAGetLastError()));
+		return -1;
 	}
 }
 
-void socket_bind(struct _cmd *cmd, struct _file_env *env) {
+static
+void CALLBACK socket_read_callback(DWORD err, DWORD len, WSAOVERLAPPED *wo, DWORD flags) {
 
-	int r;
+	struct _msg *msg;
 
-	r = bind((SOCKET) cmd->f->handle,cmd->arg[0],(int) cmd->arg[1]);
 
-	if (r != SOCKET_ERROR) {
-		cmd_done(cmd,0,0);
+	msg = wo->hEvent;
+	ASSERT(msg != NULL);
+
+	if (len != 0) {
+
+		if (list_enqueue(msg,msg->f->in_buf) != NULL ) {
+			file_raise(msg->f,FILE_IS_READABLE,TRUE,msg->env);
+		} else {
+			msg_free(msg);
+			file_exception(msg->f,errno,msg->env);
+		}
+
+
 	} else {
-		cmd_done(cmd,-1,unixify_w32err(WSAGetLastError()));
+		msg_free(msg);
+		file_exception(msg->f,0,msg->env);
 	}
 
+	if (msg->flag == -1 && !msg->f->excepted) {
+		socket_invoke_read(msg->f,(struct _socket*) msg->f->data,msg->env);
+	}
 }
 
 static
-int socket_queue_connection(struct _cmd *cmd,struct _file_env *env) {
+void socket_invoke_read(struct _file *f, struct _socket *s,  struct _file_env *env) {
 
-	struct __connect_data *cd;
+	struct _msg *msg;
 
-	cd = cd_new(cmd->f,cmd->s,cmd->arg[0],(int)cmd->arg[1]);
+	int out;
+	int r;
 
-	if (cd != NULL) {
-		if (list_enqueue(cd,env->waiting_to_connect) != NULL) {
-			return 0;
+	int z;
+	int flags;
+
+	int resume;
+
+	int err;
+
+	out = 0;
+	msg = NULL;
+	resume = TRUE;
+
+	while (resume && !f->excepted) {
+
+		//todo -- make sure there is no memory leak
+		msg = msg_new(SOCKET_MSG_SIZE,env);
+		msg->f = f;
+
+		CHECK(msg != NULL,0);
+
+		r = WSARecv(
+				(SOCKET) f->handle,
+				&msg->wb,
+				1,
+				(DWORD*) &z,
+				(DWORD*) &flags,
+				&msg->wo,
+				socket_read_callback
+			);
+
+		if (r == SOCKET_ERROR) {
+
+			resume = FALSE;
+			err = WSAGetLastError();
+
+			CHECK(err == WSA_IO_PENDING,unixify_w32err(err));
+
 		} else {
-			cd_free(cd);
-			return -1;
+
+			msg->flag = -1;
+			socket_read_callback(0,z,&msg->wo,0);
 		}
-	} else {
-		return -1;
+
 	}
 
-}
+	fail:
 
-static
-void socket_start_reading(struct _file *f,struct _socket *s, struct _file_env *env) {
-	//add something to cmd_q that says "begin the reading"
+	if (out == -1) {
+
+		if (msg != NULL) {
+			msg_free(msg);
+		}
+
+		file_exception(f,errno,env);
+	}
+
 }
 
 static
@@ -174,8 +241,7 @@
 	f->open = TRUE;
 	s->connecting = FALSE;
 
-	socket_start_reading(f,s,env);
-
+	socket_invoke_read(f,s,env);
 }
 
 void socket_connect_callback(struct __connect_data *c, struct _file_env *env) {
@@ -185,6 +251,7 @@
 	int err;
 	int r;
 
+
 	r = WSAEnumNetworkEvents((SOCKET) c->f->handle,NULL,&we);
 	//failure indicates a programming error, not a copeable network error
 	ASSERT(r == 0);
@@ -193,6 +260,8 @@
 	//.. and nothing else
 	ASSERT((we.lNetworkEvents & (~FD_CONNECT)) == 0 );
 
+	socket_unwatch_event(c->f,c->s,env);
+
 	if ( (err = we.iErrorCode[FD_CONNECT_BIT]) == 0) {
 		socket_make_connected(c->f,c->s,env);
 	} else {
@@ -200,7 +269,6 @@
 	}
 
 	env->connections_half_open--;
-	socket_unwatch_event(c->f,c->s,env);
 	cd_free(c);
 
 }
@@ -230,6 +298,7 @@
 				case WSAEINVAL:
 					socket_watch_event
 						(cd->f,cd->s,socket_connect_callback,cd,FD_CONNECT,env);
+					//todo -- check that it is being decremented when appropriate
 					env->connections_half_open++;
 				break;
 
@@ -266,54 +335,181 @@
 	fail:
 
 	cmd_done(cmd,-1,errno);
+}
 
+static
+int socket_do_accept(struct _cmd *cmd,struct _file *f, struct _socket *s, struct _file_env *env) {
+
+	SOCKET client;
+	struct _file *c;
+
+	int err;
+
+	client = accept((SOCKET) f->handle,cmd->arg[0],cmd->arg[1]);
+
+	if (client == INVALID_SOCKET)  {
+
+		err = WSAGetLastError();
+
+		ASSERT(err != WSAEWOULDBLOCK);
+
+		errno = unixify_w32err(err);
+		return -1;
+
+	} else {
+
+
+
+		if ((c = socket_new_socket(client,env)) == NULL) {
+
+			closesocket(client);
+			return -1;
+
+		} else {
+
+			//todo -- deassociate with parent events
+
+			socket_make_connected(c,c->data,env);
+			return 0;
+
+		}
+	}
 }
 
-void socket_new(struct _cmd *cmd, struct _file_env *env) {
+void socket_accept_callback(struct _file *f, struct _file_env *env) {
 
+	WSANETWORKEVENTS we;
+
+	ASSERT( WSAEnumNetworkEvents((SOCKET) f->handle,NULL,&we) != SOCKET_ERROR);
+
+	ASSERT(we.lNetworkEvents & FD_ACCEPT);
+	ASSERT((we.lNetworkEvents & (~FD_ACCEPT)) == 0 );
+
+	file_raise(f,FILE_IS_READABLE,TRUE,env);
+
+	ASSERT( WSAResetEvent(env->ev[((struct _socket*) f->data)->watch_index] ))
+}
+
+void socket_accept(struct _cmd *cmd, struct _file_env *env) {
+
+	if (cmd->f->ready[FILE_IS_READABLE]) {
+
+		if ( socket_do_accept(cmd,cmd->f,cmd->f->data,env) ) {
+			cmd_done(cmd,-1,errno);
+		} else {
+			cmd_done(cmd,0,0);
+		}
+
+	} else {
+		cmd_defer(cmd,EAGAIN);
+	}
+
+}
+
+void socket_listen(struct _cmd *cmd, struct _file_env *env) {
+
+	int r;
+
+	r = listen((SOCKET) cmd->f->handle, (int) cmd->arg[0]);
+
+	if (r != SOCKET_ERROR) {
+		socket_watch_event
+			(cmd->f,cmd->f->data,socket_accept_callback,cmd->f,FD_ACCEPT,env);
+		cmd_done(cmd,0,0);
+	} else {
+		cmd_done(cmd,-1,unixify_w32err(WSAGetLastError()));
+	}
+}
+
+void socket_bind(struct _cmd *cmd, struct _file_env *env) {
+
+	int r;
+
+	r = bind((SOCKET) cmd->f->handle,cmd->arg[0],(int) cmd->arg[1]);
+
+	if (r != SOCKET_ERROR) {
+
+		cmd_done(cmd,0,0);
+	} else {
+
+		cmd_done(cmd,-1,unixify_w32err(WSAGetLastError()));
+	}
+
+}
+
+static
+struct _file *socket_new_socket(SOCKET sock, struct _file_env *env) {
+
 	struct _file *f;
 	struct _socket *s;
 
 	int out;
-	int nb;
 
-	out = 0;
-	nb = 1;
-
 	f = file_new(env);
 	CHECK(f != NULL,0);
 
-	s = (struct _socket*) malloc(sizeof(struct _socket));
-	CHECK(s != NULL,ENOMEM);
+	s = (struct _socket *) malloc(sizeof(struct _socket));
+	CHECK(s != NULL, ENOMEM);
 
-	//todo -- set tcp stack size to zero
+	f->handle = (void*) sock;
+	f->type = FT_SOCKET;
+	f->data = s;
 
-	f->handle = (void*)
-		WSASocket(	(int) cmd->arg[0],
+	s->connecting = FALSE;
+
+	fail:
+
+	if (out == -1) {
+
+		if (f == NULL) {
+			file_close(f,env);
+		}
+
+		return NULL;
+
+	} else {
+		return f;
+	}
+}
+
+void socket_create(struct _cmd *cmd, struct _file_env *env) {
+
+	SOCKET s;
+
+	struct _file *f;
+
+	int nb;
+	int out;
+
+
+	nb = 1;
+
+	s = 	WSASocket(	(int) cmd->arg[0],
 					(int) cmd->arg[1],
 					(int) cmd->arg[2],
 					NULL,
 					0,
 					WSA_FLAG_OVERLAPPED);
-	CHECK_(f->handle != (void*) INVALID_SOCKET);
 
+	CHECK_(s != INVALID_SOCKET);
+
 	//the underlying socket is always non-blocking
 	//there is no reason for this operation to fail
-	ASSERT(ioctlsocket((SOCKET) f->handle,FIONBIO,(DWORD*) &nb) == 0);
+	ASSERT(ioctlsocket(s,FIONBIO,(DWORD*) &nb) == 0);
 
-	f->type = FT_SOCKET;
-	s->connecting = FALSE;
-	f->data = s;
+	f = socket_new_socket(s,env);
+	CHECK(f != NULL,0);
 
-	out = f->fd;
-
 	fail:
 
-	if (out == -1 && f != NULL) {
-		file_close(f,env);
+	if (out == -1) {
+		cmd_done(cmd,-1,errno);
+	} else {
+		cmd_done(cmd,f->fd,0);
 	}
 
-	cmd_done(cmd,out,errno);
 
 
 }
+
+

Modified: bsockets/trunk/contrib/liboverlapped/socket.h
===================================================================
--- bsockets/trunk/contrib/liboverlapped/socket.h	2006-10-29 17:28:34 UTC (rev 8857)
+++ bsockets/trunk/contrib/liboverlapped/socket.h	2006-10-29 21:53:24 UTC (rev 8858)
@@ -1,6 +1,8 @@
 #ifndef _SOCKET_H_
 #define _SOCKET_H_
 
+#define SOCKET_MSG_SIZE	4096
+
 struct _socket {
 	int connecting;
 	int watch_index;
@@ -9,11 +11,14 @@
 struct _cmd;
 struct _file_env;
 
-void socket_new(struct _cmd *, struct _file_env *);
+
+void socket_accept(struct _cmd *, struct _file_env *);
+void socket_create(struct _cmd *, struct _file_env *);
 void socket_connect(struct _cmd *, struct _file_env *);
 void socket_bind(struct _cmd *, struct _file_env *);
 void socket_listen(struct _cmd*, struct _file_env *);
 void socket_get_name(struct _cmd*, struct _file_env *);
 
+
 #endif
 

Modified: bsockets/trunk/contrib/liboverlapped/test.c
===================================================================
--- bsockets/trunk/contrib/liboverlapped/test.c	2006-10-29 17:28:34 UTC (rev 8857)
+++ bsockets/trunk/contrib/liboverlapped/test.c	2006-10-29 21:53:24 UTC (rev 8858)
@@ -3,12 +3,13 @@
 
 #include "overlapped.h"
 #include "test.h"
-		#include "env.h"
+#include "env.h"
+#include "misc.h"
 
 #define MAX_FILES 2000
 #define MAX_SOCKETS 1500
 
-struct sockaddr_in lh;
+struct sockaddr_in lo;
 
 static struct _file_env_options fo = {
 	MAX_FILES,
@@ -44,53 +45,101 @@
 	return 0;
 }
 
-//do some simple stuff with connect
-int test_connect() {
 
-	struct sockaddr_in lh2;
+//make a simple client/server and send some trivial data over it
+int test_clientserver_client(int ho_port) {
 
-	int client;
+	int s;
+	int r;
+
+//	int msg;
+
+	s = bsocket(AF_INET,SOCK_STREAM,0);
+	TESTne(s,-1);
+
+	lo.sin_port = ho_port;
+
+	r = bconnect(s,(struct sockaddr*)&lo,sizeof(lo));
+	TESTne(r,-1);
+
+	/*read 666*/
+//	r = brecv(s,&msg,sizeof(msg));
+//	TESTeq(r == sizeof(msg));
+//	TESTeq(msg == 666);
+
+	/*send 666*/
+//	r = bsend(s,&msg,sizeof(msg));
+//	TESTeq(r == sizeof(msg));
+
+	return 0;
+}
+
+int test_clientserver() {
+
+	HANDLE client;
+
+	struct sockaddr_in out;
+	int out_size;
+
+	struct sockaddr_in host_name;
+	int host_name_size;
+
+	int mega_tests = 10;
+	//int tests = 1000;
+
 	int server;
-	int tests = 100;
+
 	int r;
-	int z;
 
-	TESTeq(env_init(&fo),0);
+	while (mega_tests--) {
 
-	while (tests--) {
+		TESTeq(env_init(&fo),0);
 
-		/*simple blocking server*/
 		server = bsocket(AF_INET,SOCK_STREAM,0);
-		TEST(server != -1);
+		TESTne(server,-1);
 
-		client = bsocket(AF_INET,SOCK_STREAM,0);
-		TEST(client != -1);
+		r = bbind(server,(struct sockaddr*) &lo,sizeof(lo));
+		TESTne(r,-1);
 
-		r = bbind(server,(struct sockaddr*) &lh,sizeof(lh));
-		TEST(r != -1);
+		host_name_size = sizeof(host_name);
+		r = bgetsockname(server,(struct sockaddr*) &host_name,&host_name_size);
+		TESTne(r,-1);
 
 		r = blisten(server,10);
-		TEST(r != -1);
+		TESTne(r,-1);
 
-		z = sizeof(lh2);
-		r =  bgetsockname(server,(struct sockaddr*) &lh2,&z);
-		TEST(r != -1);
+		//is this a good cast?
+		client = new_thread(test_clientserver_client,(void*) (int) host_name.sin_port);
 
-		r = bconnect(client,(struct sockaddr*) &lh2,sizeof(lh2));
-		TEST(r != -1);
+		out_size = sizeof(out);
+		r = baccept(server,(struct sockaddr*) &out,&out_size);
+		TESTne(r,-1);
 
-		r = baccept(server,NULL,NULL);
-		TEST(r != -1);
+		/*send 666*/
 
+		/*read 666*/
 
-	}
+		/*wait for client to die*/
+		r = WaitForSingleObject(client,INFINITE);
+		TESTeq(r,WAIT_OBJECT_0);
 
-	env_shutdown();
+		TEST(GetExitCodeThread(client,(DWORD*) &r));
 
+		TESTeq(r,0);
+
+		CloseHandle(new_thread);
+
+		env_shutdown();
+
+	}
 	return 0;
 }
 
+
 //make sure connect/accept behave properly
+
+//do the same tests with UDP ... why not??
+
 int test_blocking_server() {
 	TEST(FALSE);
 	return 0;
@@ -101,7 +150,6 @@
 	return 0;
 }
 
-
 struct test_case {
 	int (*fun)();
 	char *desc;
@@ -109,7 +157,7 @@
 
 struct test_case tc[] = {
 //	{test_fileinit,"Test creating and destroying some sockets"},
-	{test_connect,"Test usage of connect()"},
+	{test_clientserver,"Test usage of connect()"},
 //	{test_basic_epoll,"Test basic usage of epoll()"},
 //	{test_blocking_server,"Test blocking implementation of echo server."},
 //	{test_nonblocking_server,"\t(non-blocking"},
@@ -151,9 +199,9 @@
 	int good=0;
 	int bad=0;
 
-	lh.sin_family = AF_INET;
-	lh.sin_addr.s_addr = inet_addr("127.0.0.1");
-	lh.sin_port = 0;
+	lo.sin_family = AF_INET;
+	lo.sin_addr.s_addr = inet_addr("127.0.0.1");
+	lo.sin_port = htons(0);
 
 	if ( winsock_start() != 0) {
 		printf("Couldn't init winsock: %d",WSAGetLastError());
@@ -178,7 +226,7 @@
 	printf("\nTesting report: passed %d, failed %d\n",good,bad);
 	fflush(stdout);
 
-	return 0;
+	return bad;
 
 }
 

Modified: bsockets/trunk/contrib/liboverlapped/test.h
===================================================================
--- bsockets/trunk/contrib/liboverlapped/test.h	2006-10-29 17:28:34 UTC (rev 8857)
+++ bsockets/trunk/contrib/liboverlapped/test.h	2006-10-29 21:53:24 UTC (rev 8858)
@@ -4,14 +4,23 @@
 int res_;
 int res2_;
 
-#define TESTeq(A,B)  	if ( (res_ = A) != (res2_ = B) ) {\
-							printf("\nTest failed: %s [%d] != %s [%d]\n\tline:%d   errno:%d w32err:%d\n"\
-							,#A,res_,#B,res2_,__LINE__,errno,(int) WSAGetLastError()\
-								);\
-							return 1;\
-						}\
+char *xxxx;
 
-#define TEST(X)	TESTeq(X,TRUE);
+#define TESTeq(A,B) TEST_(A,B,==);
 
+#define TESTne(A,B) TEST_(A,B,!=);
 
+#define TEST(A)	TEST_(A,TRUE,==);
+
+#define TEST_(A,B,F)\
+		if (!( (res_ = A) F (res2_ = B) )) {\
+		\
+			printf("\nTest Failed: %s [%d] %s %s [%d]\n\tline:%d errno:%d w32err: %d wsaerr: %d \n\n"\
+			,#A,res_,#F,#B,res2_,__LINE__,errno,(int)GetLastError(),(int)WSAGetLastError()\
+				);\
+			xxxx = NULL; xxxx[0] = 0;\
+			return 1;\
+		\
+		}\
+
 #endif



More information about the tor-commits mailing list