changed the order of listen and multiplexer registeration to avoid spurious hangup event

This commit is contained in:
hyunghwan.chung 2018-05-16 07:03:01 +00:00
parent da0b655d40
commit f260c04b4e
3 changed files with 26 additions and 37 deletions

View File

@ -564,27 +564,7 @@ class ServerSocket(Socket)
clisck := (self acceptedSocketClass) __with: fd.
clisck beWatched.
self onSocketAccepted: clisck from: cliaddr.
}
(*--------------------------
clisck := self _accept: cliaddr.
if (clisck notNil) ## if nil, _accept: failed with EWOULDBLOCK/EAGAIN.
{
## the _accept method doesn't invoke the initialize method.
## i should invoke it manually here.
clisck initialize.
clisck beWatched.
self onSocketAccepted: clisck from: cliaddr.
###if (self.acceptedEventAction notNil)
####{
### clisck beWatched.
### self.acceptedEventAction value: self value: clisck value: cliaddr.
### clisck beWatched.
###}
###else { clisck close }.
}.
---------------------------*)
].
}
@ -614,9 +594,19 @@ class ServerSocket(Socket)
method listen: backlog
{
thisProcess addAsyncSemaphore: self.inreadysem.
| n |
## If listen is called before the socket handle is
## added to the multiplexer, a spurious hangup event might
## be generated. At least, such behavior was observed
## in linux with epoll in the level trigger mode.
### System signal: self.inreadysem onInput: self.handle.
### thisProcess addAsyncSemaphore: self.inreadysem.
### n := self _listen: backlog.
n := self _listen: backlog.
System signal: self.inreadysem onInput: self.handle.
^self _listen: backlog.
thisProcess addAsyncSemaphore: self.inreadysem.
^n.
}
method onSocketAccepted: clisck from: cliaddr

View File

@ -1354,7 +1354,7 @@ static int delete_sem_from_sem_io_tuple (moo_t* moo, moo_oop_semaphore_t sem, in
static void _signal_io_semaphore (moo_t* moo, moo_oop_semaphore_t sem)
{
moo_oop_process_t proc;
proc = signal_semaphore (moo, sem);
if (moo->processor->active == moo->nil_process && (moo_oop_t)proc != moo->_nil)
@ -1384,26 +1384,25 @@ static void signal_io_semaphore (moo_t* moo, moo_ooi_t io_handle, moo_ooi_t mask
moo_ooi_t sem_io_index;
sem_io_index = moo->sem_io_map[io_handle];
insem = moo->sem_io_tuple[sem_io_index].sem[MOO_SEMAPHORE_IO_TYPE_OUTPUT];
outsem = moo->sem_io_tuple[sem_io_index].sem[MOO_SEMAPHORE_IO_TYPE_INPUT];
if (insem)
{
if ((mask & (MOO_SEMAPHORE_IO_MASK_OUTPUT | MOO_SEMAPHORE_IO_MASK_ERROR)) ||
(!outsem && (mask & MOO_SEMAPHORE_IO_MASK_HANGUP)))
{
_signal_io_semaphore (moo, insem);
}
}
insem = moo->sem_io_tuple[sem_io_index].sem[MOO_SEMAPHORE_IO_TYPE_INPUT];
outsem = moo->sem_io_tuple[sem_io_index].sem[MOO_SEMAPHORE_IO_TYPE_OUTPUT];
if (outsem)
{
if (mask & (MOO_SEMAPHORE_IO_MASK_INPUT | MOO_SEMAPHORE_IO_MASK_HANGUP | MOO_SEMAPHORE_IO_MASK_ERROR))
if ((mask & (MOO_SEMAPHORE_IO_MASK_OUTPUT | MOO_SEMAPHORE_IO_MASK_ERROR)) ||
(!insem && (mask & MOO_SEMAPHORE_IO_MASK_HANGUP)))
{
_signal_io_semaphore (moo, outsem);
}
}
if (insem)
{
if (mask & (MOO_SEMAPHORE_IO_MASK_INPUT | MOO_SEMAPHORE_IO_MASK_HANGUP | MOO_SEMAPHORE_IO_MASK_ERROR))
{
_signal_io_semaphore (moo, insem);
}
}
}
else
{

View File

@ -1041,7 +1041,7 @@ static int _add_poll_fd (moo_t* moo, int fd, int event_mask)
/* epoll_wait may return again if the worker thread consumes events.
* switch to level-trigger. */
/* TODO: verify if EPOLLLET is desired */
ev.events |= EPOLLET;
ev.events |= EPOLLET/* | EPOLLRDHUP | EPOLLHUP */;
#endif
/*ev.data.ptr = (void*)event_data;*/
ev.data.fd = fd;