IOCP ioqueue

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 19 Jul 2012 14:27:14 +0700 Benny Prijono <bennylp at teluu.com>
wrote:

> On Thu, Jul 19, 2012 at 1:19 PM, Timo Teras <timo.teras at iki.fi> wrote:
> 
> >
> > Solutions that come up to my mind:
> >
> >  - if the pool is deleted, the destructor should wait synchronously
> > that each cancel notification is received before continuing
> >
> Well I've figured what the alternative solutions are, it's just that I
> don't find them simple to implement.

Now that I actuall read the code, it seems that the
pj_ioqueue_unregister() is trying to achieve the synchronous operation
if PJ_IOQUEUE_HAS_SAFE_UNREG is defined. The SAFE_UNREG seems to also
enable lot of probably unnecessary "workaround" code.

However, this does not work if poll_iocp() is not called from another
thread while pj_ioqueue_unregister() is synchronizing in the busy loop.

Fundamental problem here seem to be that pj_ioqueue_unregister() is
assumed to be synchronous, but the underlaying windows API is
asynchronous. And it's not easy to convert it to synchronous one,
unless there're separate threads calling poll_iocp concurrently.
Do note that this is the standard design: one should have multiple
threads blocking in GetQueuedCompletionStatus() that act as a thread
pool to process the completions.

As a workaround in single threaded programs: the _unregister() could
instead of sleep(0) call GetQueuedCompletionStatus() and stuff the
received events in a "pending" list which would get priority on next
call of poll. And of course handle immediately the events for the
handle it's waiting for.

But yes - either of these can be slightly tricky due to
pj_ioqueue_unregister() being expected to be synchronous and the fact
that windows API works asynchronously.

Additionally - it would seem that sip_endpoint.c in udp_destroy() does
actually first call unregister for all keys, and then poll for the
actual cancel events. However, one should not stop polling when there's
no io events - windows driver clean up can take a little time, and make
a first poll return no events after cancel request is posted.

Sounds to me that the ioqueue is not well defined on how the
unregistration happens. And different parts of the code make slightly
different assumptions.

As final note - it seems one can have multiple ioqueues in a process.
It is also notable that in Windows you can have one thread call
GetQueuedCompletionStatus() for single queue only. The remarks say:
This function associates a thread with the specified completion port.
A thread can be associated with at most one completion port.
This is likely to tie it up the thread to be included in
CreateIoCompletionPort() call's NumberOfConcurrentThreads when the
thread is in running state.

This basically implies that each ioqueue should have their dedicated
pool of threads that handle the overlapped events. Dunno how the
ioqueues are nested in pjsip core code, though.

- Timo



[Index of Archives]     [Asterisk Users]     [Asterisk App Development]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [Linux API]
  Powered by Linux