Maybe my head is just thick today, but even staring at the docs a couple times and reading through what you have below, I can't say I quite understand what you're going for. What are the actual constraints for the windows APIs and what is the heavyweight stuff pn_io_t is doing?
--Rafael On Wed, Feb 25, 2015 at 1:02 PM, Cliff Jansen <cliffjan...@gmail.com> wrote: > 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 >