Cliff Jansen commented on PROTON-668:

Preparing a patch to restore some of the old functionality has
revealed holes in my thinking.  Some accepted sockets are easy to
move, others less so.  Rewording the restrictions more related to

a given pn_io_t can service exactly one pn_selector_t or it can service an 
external loop, but not both

   (related: a pn_io_t can have at most one pn_selector_t, enforced by the API)

an external socket inserted into a Proton pn_selector_t/pn_io_t pair and using 
pn_recv/pn_send must maintain all further io through the pn_io_t.

a socket from pn_accept()/pn_listen()/pn_connect() from a pn_selector_t/pn_io_t 
pair must maintain all further io through the pn_io_t.

sockets created by a pn_io_t that have no pn_selector_t via 
pn_accept()/pn_listen()/pn_connect() may be used as any other OS socket

a "socket" pair from pn_pipe() may only be used with pn_read/pn_write within 
its origin pn_io_t

pn_recv/pn_send cannot be inter-mixed with direct OS send/recv calls on a socket

thread safety is as described earlier in this JIRA

> Document Proton-c IO restrictions for 0.8 release
> -------------------------------------------------
>                 Key: PROTON-668
>                 URL: https://issues.apache.org/jira/browse/PROTON-668
>             Project: Qpid Proton
>          Issue Type: Improvement
>          Components: proton-c
>    Affects Versions: 0.8
>            Reporter: Cliff Jansen
>            Assignee: Cliff Jansen
>            Priority: Blocker
>             Fix For: 0.8
> Proton is designed to provide an efficient IO layer that functions without 
> imposing a threading model on the application.  Applications may (1) roll 
> their own IO and just use the Proton engine, (2) use all Proton primitives, 
> (3) use some Proton primitives augmented by an external event loop.
> Case (1) is unrelated to this JIRA.  The others may be restated:
> Scenario 2: Proton event loop: a proton selector manages socket events for 
> all sockets placed in the selector, all associated sockets use pn_io_xxx() 
> calls.  Sockets outside the selector are "unmanaged" and passed through to 
> the OS socket function unchanged.
> Scenario 3: Third party event loop (no proton selector involved), all sockets 
> are treated as for "unmanaged" in scenario 2.
> Scenario 4, 5...: Others to support?
> The problem:
> The Proton Posix pattern for efficient IO is:
>   "tell me when your (OS) buffer is ready for io transfer (in or out)"
> Whereas the normal Windows pattern is somewhat reversed (IO completion ports):
>   "tell me when you are done transferring data (to or from) my (user space) 
> buffer"
> The current Windows IOCP implementation (PROTON-640) tries to make the latter 
> look like the former with some constraints.   There should be documentation 
> specifying reasonable limits on Proton usage that may be falsely implied by 
> the API but do not translate efficiently to Windows.  Assuming that future 
> Windows implementations may adopt more aggressive performance strategies 
> (especially on the read side), I would propose something along the lines of:
>   a socket may only ever be used with a single pn_io_t in its lifetime
>     exception: a socket from pn_accept() is not yet associated with any 
> pn_io_t and its first use can be with any pn_io_t (or never with a pn_io_t at 
> all)
>   send/recv/close may not be intermixed with similar non-Proton OS calls 
> (otherwise: out of order or lost data)
>   a socket can move once from an external loop to a proton loop, but never 
> the other way
>   pn_pipe() values can only be used with pn_read and pn_write and 
> pn_selector_select, they cannot participate in an external event loop.
>   Furthermore, there is no thread safety except:
>     threads may do concurrent pn_io_xxx() calls as long as no two are 
> simultaneous on the same socket (where xxx is send/recv/read/write)
>     pn_selector_select() is thread safe against 
> pn_read/pn_write/pn_send/pn_recv, but the outcome of the select is 
> indeterminate.  pn_selector_select() must be interrupted and restarted at any 
> time when other simultaneous IO may affect the outcome.
>     calls on different pn_io_t objects do not interact and are thread safe.
> If it is desirable for a socket to be used in an external loop after being 
> used in a Proton loop, we would need some sort of blocking calls along the 
> lines of:
>   pn_io_flush()
>   pn_io_drain()
> which would be no-ops on Posix but would unwind outstanding completions on 
> Windows.
> Early criticism of any of the above assumptions would be greatly appreciated. 
>  I will try to reword the above, or its evolution into the existing 
> documentation for 0.8.

This message was sent by Atlassian JIRA

Reply via email to