Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

WSAEventSelect

167 views
Skip to first unread message

n.co...@gmail.com

unread,
Jan 12, 2006, 10:59:02 AM1/12/06
to
Hi,
I have a problem with the using of WSAEventSelect

Here's my program:
I use the semaphore to get messages from another thread.

-----
this->_hEvent = WSACreateEvent();

while (1)
{
HANDLE TabEvents[2];
TabEvents[0] = this->_th->_inSem->_hSemaphore;
TabEvents[1] = this->_hEvent;

DWORD WaitRes = WaitForMultipleObjects(2, TabEvents, FALSE, INFINITE);
if (WaitRes == WAIT_FAILED)
throw new NetworkException("WaitForMultipleObjects",
WSAGetLastError());

switch(WaitRes)
{
case WSA_WAIT_EVENT_0:
[...]
//NEW CLIENT ! (already accepted)
int iMode = 1;
if (ioctlsocket(client->getSocket(), FIONBIO, (u_long FAR*) &iMode)
==
SOCKET_ERROR)
[...] // error: close ....
int nRet = WSAEventSelect(cursocket, this->_hEvent,
FD_READ|FD_CLOSE|FD_WRITE);
if (nRet == SOCKET_ERROR)
[...] // error: close ...
break;
case WSA_WAIT_EVENT_0 + 1:
WSANETWORKEVENTS events;

for ([...]) //browse clients
{
int nRet = WSAEnumNetworkEvents(client->getSocket(), this->_hEvent,
&events);
int action = events.lNetworkEvents;

if (nRet == SOCKET_ERROR)
action = FD_CLOSE;

if (FD_READ & action)
{
if (this->receiveFromClient(client) != SOCKET_ERROR)
{
[...]
}
else
action = FD_CLOSE;
}
if (FD_WRITE & action)
{
[...]
}
if (FD_CLOSE & action)
{
this->closeClient(client);
}

}
break;
}
}
----

void closeClient([...])
{
int nRet = WSAEventSelect(client->getSocket(), this->_hEvent, 0);
if (nRet == SOCKET_ERROR)
throw new NetworkException("WSAEventSelect", WSAGetLastError());
closesocket ...
}

----

With this code I have sometimes an infinite loop: I already have unset
sockets on "this->_hEvent" but the WaitForMultipleObjects quits with
WSA_WAIT_EVENT_0 + 1 (this->_hEvent)...

Please Help, I don't know if I use well the WSAEventSelect function....

Thanks in advance.

Peter Duniho

unread,
Jan 12, 2006, 2:46:49 PM1/12/06
to
<n.co...@gmail.com> wrote in message
news:1137081542....@g44g2000cwa.googlegroups.com...
> [...]

> With this code I have sometimes an infinite loop: I already have unset
> sockets on "this->_hEvent" but the WaitForMultipleObjects quits with
> WSA_WAIT_EVENT_0 + 1 (this->_hEvent)...

You will have to be more specific. You've *coded* an infinite loop, so
without more details, there's no reason to believe the code isn't doing
exactly what you told it to do.

What is it that you think the code should do, what is it doing instead, and
under what circumstance does it do the wrong thing rather than the right
thing?

I skimmed through the code as best I could, and I don't see anything
obviously wrong. I may have missed something; you posted it without any
indentation whatsoever, making it VERY hard to read. I don't spend much
time trying to decipher hard-to-read code.

You do have a couple of superfluous elements. You don't need to set the
socket to non-blocking. WSAEventSelect() does this for you. And you don't
need to reset the WSAEventSelect() state for the socket before closing it.
That's just a waste of time.

Pete


n.co...@gmail.com

unread,
Jan 13, 2006, 3:33:55 AM1/13/06
to
Thank you for your answer.

> I may have missed something; you posted it without any
> indentation whatsoever, making it VERY hard to read.

I have posted the code with google groups and I have posted with
indentation:
http://groups.google.fr/group/alt.winsock.programming/browse_thread/thread/dcc62313db39cf07/e67fb86303750095#e67fb86303750095

> You do have a couple of superfluous elements. You don't need to set the
> socket to non-blocking.

Ok thanks for the information.

> And you don't need to reset the WSAEventSelect()
> state for the socket before closing it.

If I don't use it WaitForMultipleObjects quits evrey time on
WSA_WAIT_EVENT_0 + 1

I have some threads: It's a "kernel" implentation with some modules.
One module accept the connection, another read/write/close, another
treat the readed data ...

Modules have a semaphore to know when a message arrived from another
thread.

My problem is with the read/write/close module: I have a while(1) with
a WaitForMultipleObjects on the semaphore and on sockets.

I am sure that my socket is closed but sometimes
WaitForMultipleObjects...

Thanks again for your help

Peter Duniho

unread,
Jan 13, 2006, 2:37:28 PM1/13/06
to
<n.co...@gmail.com> wrote in message
news:1137141235.2...@f14g2000cwb.googlegroups.com...

> I have posted the code with google groups and I have posted with
> indentation:

Don't post with Google Groups. It screws up your post, and people using
normal newsreaders don't see what you think they see.

You may think you included indendation, but I assure you that on this end,
there is none.

> [...]


>> And you don't need to reset the WSAEventSelect()
>> state for the socket before closing it.
>
> If I don't use it WaitForMultipleObjects quits evrey time on
> WSA_WAIT_EVENT_0 + 1

Well, that's a problem then. I suggest that, rather than doing the wrong
thing to fix a wrong thing, you figure out why the original wrong thing is
happening.

Personally, my bet is that you didn't reset the network event handle.
WSACreateEvent() gives you an event handle that does NOT auto-reset. Once
you've handled the event, you need to reset it yourself.

Calling WSAEventSelect() is not the right way to reset the event.

> I have some threads: It's a "kernel" implentation with some modules.
> One module accept the connection, another read/write/close, another
> treat the readed data ...
>
> Modules have a semaphore to know when a message arrived from another
> thread.

Fine. That was apparent from the original code, but still...fine.

> My problem is with the read/write/close module: I have a while(1) with
> a WaitForMultipleObjects on the semaphore and on sockets.

An infinite loop. Which you coded.

> I am sure that my socket is closed but sometimes
> WaitForMultipleObjects...

That's not a complete sentence.

> Thanks again for your help

I'm still not clear on what isn't working. I doubt anyone else is too. So
far, your only complaint is that there's an infinite loop, but as you've
explained twice already, the infinite loop is one you wrote yourself. It's
hardly a surprise there's an infinite loop.

Pete


n.co...@gmail.com

unread,
Jan 14, 2006, 10:51:06 AM1/14/06
to

Peter Duniho a écrit :

I'm sorry but i'm not english and I have a very poor level in emglish
so sorry again.


My problem is not the infinite loop but the fact that
WaitForMultipleObjects does not wait sometimes...

Casper

unread,
Jan 14, 2006, 11:32:14 AM1/14/06
to
Probably you should process WAIT_ABANDONED
or call WSAWaitForMultipleObjectsEx instead

Peter Duniho

unread,
Jan 14, 2006, 1:39:50 PM1/14/06
to
<n.co...@gmail.com> wrote in message
news:1137253866....@g43g2000cwa.googlegroups.com...

> My problem is not the infinite loop but the fact that
> WaitForMultipleObjects does not wait sometimes...

If WaitForMultipleObjects returns, it does so for a reason. Until you
describe the condition in which it returns, but you don't expect it to, it's
impossible for anyone to suggest why it is returning when you don't expect
it to.

I will agree with Casper that it might be better to use the Winsock "WSAxxx"
version of the function, and/or to do more complete handling of possible
return values. But doing so may or may not resolve your problem. No one
here can say until you tell us why WaitForMultipleObjects is returning, and
why it is you think it shouldn't be returning.

Pete


n.co...@gmail.com

unread,
Jan 14, 2006, 4:20:40 PM1/14/06
to
I can't use WSAWait... I am waiting for a semaphore and sockets, that's
why I have used WaitForMultipleObjects...

My problem is that WaitForMultipleObjects returns whereas I have no
more socket connected (I'm sure about that), I am sure that the return
is not due to the semaphore ...

Peter Duniho

unread,
Jan 14, 2006, 5:54:29 PM1/14/06
to
<n.co...@gmail.com> wrote in message
news:1137273640.9...@g14g2000cwa.googlegroups.com...
> [...]

> My problem is that WaitForMultipleObjects returns whereas I have no
> more socket connected (I'm sure about that), I am sure that the return
> is not due to the semaphore ...

Why is that a problem? Would you prefer that it NOT return when you have no
more sockets connected?

I still don't understand what behavior it is you expect to see. You passed
in an event handled corresponding to a socket. If the socket is
disconnected, that's a network event you would be alerted to. In that case,
WaitForMultipleObjects should return. If you don't want it to, then you
need to not set the flags that would cause that to happen (FD_READ and
FD_CLOSE).

The bottom line here:

WaitForMultipleObjects returns only under very specific conditions.
According to you, the condition is that the second event handle parameter
you pass to it is set. If you don't want WaitForMultipleObjects to return
in that situation, you need to ensure that it doesn't get set in that
situation.

Pete


n.co...@gmail.com

unread,
Jan 15, 2006, 1:33:19 PM1/15/06
to

Peter Duniho a écrit :

All sockets are closed, I have unset every socket in the handler. I
don't understand why the WaitForMultipleObjects return whereas I have
no socket set in the handler.

David Schwartz

unread,
Jan 15, 2006, 6:18:04 PM1/15/06
to

<n.co...@gmail.com> wrote in message
news:1137349999.0...@f14g2000cwb.googlegroups.com...

> All sockets are closed, I have unset every socket in the handler. I
> don't understand why the WaitForMultipleObjects return whereas I have
> no socket set in the handler.

It returns because it has nothing to wait for.

DS

Alun Jones

unread,
Jan 15, 2006, 8:54:44 PM1/15/06
to
In article <11sg0c9...@corp.supernews.com>, "Peter Duniho"
<NpOeS...@NnOwSlPiAnMk.com> wrote:
>Personally, my bet is that you didn't reset the network event handle.
>WSACreateEvent() gives you an event handle that does NOT auto-reset. Once
>you've handled the event, you need to reset it yourself.

Oh, no no no.

You should never reset the event yourself. The network stack should keep the
correspondence between events occurred and events signalled. Your job, as a
Winsock user, is to allow it to do so.

You accomplish this by calling the WSAEnumNetworkEvents function, so as to be
informed of the socket events that are associated with the WSAEVENT object
that was signalled. The socket stack will use that call to
WSAEnumNetworkEvents to reset the event, or to signal it if there are more
network events that occurred in between.

Resetting the event yourself will lead to race conditions that are hard to
debug, but result in occasional unreliability under stress.

>Calling WSAEventSelect() is not the right way to reset the event.

WSAEventSelect is about associating and disassociating a socket with an event,
and a possible mask of events. Note that for some events, calling
WSAEventSelect again will re-trigger an event notification that you have
already received.

Alun.
~~~~

[Please don't email posters, if a Usenet response is appropriate.]
--
Texas Imperial Software | Find us at http://www.wftpd.com or email
23921 57th Ave SE | al...@wftpd.com.
Washington WA 98072-8661 | WFTPD, WFTPD Pro are Windows FTP servers.
Fax/Voice +1(425)807-1787 | Try our NEW client software, WFTPD Explorer.

Peter Duniho

unread,
Jan 16, 2006, 12:59:30 AM1/16/06
to
"Alun Jones" <al...@texis.invalid> wrote in message
news:_MadnUvASem...@comcast.com...

>>Personally, my bet is that you didn't reset the network event handle.
>>WSACreateEvent() gives you an event handle that does NOT auto-reset. Once
>>you've handled the event, you need to reset it yourself.
>
> Oh, no no no.
>
> You should never reset the event yourself. The network stack should keep
> the
> correspondence between events occurred and events signalled. Your job, as
> a
> Winsock user, is to allow it to do so.

My bad. I knew the event is created as a manual reset. I forgot that it's
Winsock that handles the event handle state, not the application.

Thanks! :)

Pete


n.co...@gmail.com

unread,
Jan 16, 2006, 3:43:08 AM1/16/06
to

> WSAEventSelect is about associating and disassociating a socket with an event,
> and a possible mask of events. Note that for some events, calling
> WSAEventSelect again will re-trigger an event notification that you have
> already received.

And how can I flush an event ,after disassociating a socket. To be sure
that I will not receive another notification from the closed socket.

Alun Jones

unread,
Jan 18, 2006, 12:36:08 AM1/18/06
to
In article <1137400988.3...@g43g2000cwa.googlegroups.com>,

WSAEnumNetworkEvents will flush events as it tells you what they are;
closesocket will permanently disassociate the event and the socket handle;
WSAEventSelect may be used if you don't want to monitor events on a socket any
more, but want to keep the socket open. [Say, for instance, you're going to
hand it off to another piece of code that doesn't use events]

If that last is the case, you would do well to read the documentation:

"The WSAEventSelect function automatically sets socket s to nonblocking mode,
regardless of the value of lNetworkEvents. To set socket s back to blocking
mode, it is first necessary to clear the event record associated with socket s
via a call to WSAEventSelect with lNetworkEvents set to zero, in which case
the hEventObject parameter will be ignored. You can then call ioctlsocket or
WSAIoctl to set the socket back to blocking mode."

0 new messages