[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] r8858: added my code for the day (getting back into it ...) (bsockets/trunk/contrib/liboverlapped)
- To: or-cvs@xxxxxxxxxxxxx
- Subject: [or-cvs] r8858: added my code for the day (getting back into it ...) (bsockets/trunk/contrib/liboverlapped)
- From: chiussi@xxxxxxxx
- Date: Sun, 29 Oct 2006 16:53:25 -0500 (EST)
- Delivered-to: archiver@seul.org
- Delivered-to: or-cvs-outgoing@seul.org
- Delivered-to: or-cvs@seul.org
- Delivery-date: Sun, 29 Oct 2006 16:53:35 -0500
- Reply-to: or-talk@xxxxxxxxxxxxx
- Sender: owner-or-cvs@xxxxxxxxxxxxx
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