A pn_io_t is heavyweight in Windows, because it has an opposite usage
pattern and moves a lot of kernel stuff into user space compared to
POSIX.

The quoted documentation was my attempt to capture the Dispatch usage
pattern, which I assumed would be typical of an application trying to
spread proton engine use between threads: basically single access to
pn_selector_select() via a condition variable, and no more than one
thread working on a given selectable (using proton engine
encoding/decoding etc., not just io).

In the end, we could just add a zillion locks into the Windows code
and make it look like it is as thread safe as the POSIX counterpart
(which has implicit safety when it does in the kernel what Windows is
doing in user space), but that would defeat using IO completion ports
at all.  The documentation was my attempt of balancing performance
with sophisticated proton usage on multiple platforms.

Note that there is only one pn_selector_t allowed per pn_io_t (a very
strong Windows completion port requirement, and sockets are bound to a
single completion port for life).

On Wed, Feb 25, 2015 at 8:52 AM, Rafael Schloming <r...@alum.mit.edu> wrote:
> On Wed, Feb 25, 2015 at 10:49 AM, Ted Ross <tr...@redhat.com> wrote:
>
>> Would it be safe to assume that any operations on driver->io are not
>> thread safe?
>>
>> Dispatch is a multi-threaded application.  It looks to me as though
>> io->error is a resource shared across the threads in an unsafe way.
>>
>
> Interesting... so this is what the docs say:
>
> /**
>  * A ::pn_io_t manages IO for a group of pn_socket_t handles.  A
>  * pn_io_t object may have zero or one pn_selector_t selectors
>  * associated with it (see ::pn_io_selector()).  If one is associated,
>  * all the pn_socket_t handles managed by a pn_io_t must use that
>  * pn_selector_t instance.
>  *
>  * The pn_io_t interface is single-threaded. All methods are intended
>  * to be used by one thread at a time, except that multiple threads
>  * may use:
>  *
>  *   ::pn_write()
>  *   ::pn_send()
>  *   ::pn_recv()
>  *   ::pn_close()
>  *   ::pn_selector_select()
>  *
>  * provided at most one thread is calling ::pn_selector_select() and
>  * the other threads are operating on separate pn_socket_t handles.
>  */
>
> I think this has been somewhat modified by the constraints from the windows
> implementation, and I'm not sure I understand completely what the
> constraints are there, or entirely what is being described above, but on
> the posix front, the pn_io_t is little more than just a holder for an error
> slot, and you should have one of these per thread. It shouldn't be a
> problem to use send/recv/etc from multiple threads though so long as you
> pass in the pn_io_t from the current thread.
>
> --Rafael

Reply via email to