First of all, I wish to mention that this happens to be my first thread on the board. I wish to congratulate you all in it's success.

Now down to business. To explain my question, I must explain my ideas first.

To put it simply, I wanted to create a Win32 compatible, fast reliable server that accepts theoretically unlimited connections and relays data from 1 client to all others.

My idea was to have an Async listening socket running on the main GUI thread. Once the FD_ACCEPT message appeared in the WndProc, I create a worker thread which accepts the connection and stays open, recieving and sending data, until the connection is closed. Those sockets are also Async.

Well, I started to implement this server and then I hit a brick wall. I needed some way to communicate FD_READ, FD_WRITE and other messages to the correct worker threads. I also need to sync this. I had no idea how to do this. Anything I tried didn't work. I decided to hunt around a bit for a solution and a friend from IRC suggested the Winsock 2.2 event API functions which could be used to wait for certain messages and other useful things.

Naturally I searched the web for quite a while looking for information on how to actually use these functions. I found hardly any information at all. The information I did find (msdn and such) were lacking in detail and quite poor documenation.

I tried a few eperiments of my own which failed miserably.

So this is where you guys come in. I want to know firstly, is my idea plausable, are there any better ways of doing it? Secondly, (if my idea is sound) is the idea of using the event API functions a good one or is there again, a better way? If these are the best functions to use, then how do I actually use them (Documentation is useless like I said)?

Lastly, I would like to thank any replies in advance. And you guys own. ;)
Posted on 2003-01-09 14:57:16 by IRBMe
I usually make the threadproc look like this. Note that hEvent is a .data section variable, containing a handle to a event you use to synchronize the procs. hMyEvent is created and destroyed within the thread and is signalled when data is ready to be received or sent on the thread's socket.

MyProc proc hSock:dword

local hMyEvent:dword
local hServEvent:dword

m2m hServEvent,hEvent

invoke CreateEvent
mov hMyEvent,eax

invoke WSAEventSelect,hSocket,hMyEvent,FD_READ+FD_WRITE+FD_CLOSE

invoke WaitForMultipleObjects,2,addr hMyEvent,FALSE,INFINITE

; Handle the event. Note that it could be a socket event, or a sync message from the WndProc

jmp MainLoop

invoke DeleteObject,hMyEvent


MyProc endp
Posted on 2003-01-10 07:04:28 by Qweerdy
WSAEventSelect is what I was missing. Well, I'll have a try with it later and see what results it yields. Thanks for your reply.
Posted on 2003-01-10 07:54:20 by IRBMe
Originally posted by Qweerdy

MyProc proc hSock:dword
local hMyEvent:dword
local hServEvent:dword
invoke WaitForMultipleObjects,2,addr hMyEvent,FALSE,INFINITE

Shouldn't that be addr hServEvent? Since they are local variables and masm seems to put these in reverse order in the stackframe, hServEvent actually comes before hMyEvent.
I don't know if it's document in which order masm puts its locals on the stack, if you want to be sure put the two values in a struct or create an array of events (local events[2]:dword).

Posted on 2003-01-11 04:32:00 by Thomas

You're right. Strange, I thought it worked the other way around.

MyProc proc 

LOCAL Temp1:dword
LOCAL Temp2:dword

lea eax,Temp1
lea eax,Temp2


MyProc endp
assembles to...
00401000    55              push ebp

00401001 8BEC mov ebp,esp
00401003 83C4 F8 add esp,-8
00401006 8D45 FC lea eax,[ebp-4]
00401009 8D45 F8 lea eax,[ebp-8]
0040100C C9 leave
0040100D C3 retn
Posted on 2003-01-11 05:08:22 by Qweerdy
Does anybody know where to get a sample program showing this? I still don't think I understand and I'm still not sure how to implement certain things like sending messages to the correct thread and such. Also, I tried your code and it crashed my computer. I wasn't sure how to extract which event had been sent. After reading the documentation I kinda guessed how to do it. And well, it ust hung the computer. If any of you know where I can see this in action so I can study the code, that would be great. Thanks again.
Posted on 2003-01-11 09:19:51 by IRBMe
No matter. After a few hours of debugging, tracking exception errors and other such things...I managed to get it working ;)

Thanks for the help nonetheless.
Posted on 2003-01-11 15:29:00 by IRBMe
For the beneffit of anybody reading this thread who has the same problems, here is my ThreadProc for you to study:

; ThreadProc ;
ThreadProc Proc hSock:DWord

Local hEvent: DWord
Local pEvents: DWord

; --- Create a winsock event and store the handle and pointer.
Invoke WSACreateEvent
Mov hEvent, eax
Mov DWord Ptr [pEvents], eax

; --- We want to wait for the close message or the read message.
Invoke WSAEventSelect, hSock, hEvent, FD_CLOSE + FD_READ


; --- Wait for one of the messages and extract it.
Invoke WSAWaitForMultipleEvents, 1, Addr pEvents, FALSE, INFINITE, FALSE
Invoke WSAEnumNetworkEvents, hSock, hEvent, Addr WSAEvents

; --- Is it a read message.
Test WSAEvents.lNetworkEvents, FD_READ
Jz TestClose

; --- Yes. Handle RECV message here

; --- Is it a close message.
Test WSAEvents.lNetworkEvents, FD_CLOSE
Jz WaitNextEvent

; --- Yes. Close the socket, delete the event and close the thread.
Invoke closesocket, hSock
Invoke DeleteObject, hEvent


ThreadProc EndP

Hope this helps.
Posted on 2003-01-13 03:58:35 by IRBMe