Cliff Jansen created QPID-5668:
----------------------------------
Summary: Windows C++ AsynchIO layer enhancement
Key: QPID-5668
URL: https://issues.apache.org/jira/browse/QPID-5668
Project: Qpid
Issue Type: Improvement
Components: C++ Broker, C++ Client
Affects Versions: 0.26
Environment: Windows
Reporter: Cliff Jansen
Assignee: Cliff Jansen
Priority: Minor
The Windows AsynchIO and its SSL counterpart, as originally written by Steve
Huston, was lean and clean.
A lot of subsequent "fixes" have made the code less elegant and have merely
reduced the amount of errors without completely banishing them.
The problems arise from various differences in sockets, pollers, and library
teardown semantics between Posix and Windows. A socket close works quite a bit
differently on Windows. The optimistic use of completions leaves dangling
reads on close. Not all the functions you would like to use (say to cancel a
read) are available in all versions of Windows. And then there is the
lawlessness surrounding the death of the IO threads on exit versus a DLL unload.
After recent wading through the code, I would propose that it could be made
cleaner and more robust by the following:
back out the existing fixes for the hangs and exit-related catastrophes
add the following logic enforcement on a queueWriteClose:
no new queued writes
a reaper is enlisted to prevent hangs
Sunny case:
normal IO until last queued write completes
after last write, new reads are discarded (even eof notification), winsock
graceful shutdown() is called, closedCallback is invoked (even though not yet
closed, same as Posix), otherwise behave as for stopWatch()
keep monitoring completions until graceful close detected
tell reaper all is well
self delete as appropriate
Rainy case:
reaper thinks things are taking too long
does a hard/abortive close on the socket and otherwise forces the sunny case
activity to conclusion (no further hang possibilities).
As posited, this requires a separate thread to initiate reaper activity or some
cleverness with timeouts via poller::wait(t) to have the existing thread pool
look after regular reaping.
If all cleanup code is restricted to IO and reaper thread access (i.e. isolated
from the main user thread), then sudden death of these threads on exit has no
ill effect of resource leakage, and importantly, everything tidies up properly
for the DLL unload case.
If done properly, the original efficient and mostly lockless code can work as
originally intended, and all the special case code of the shutdown and cleanup
can be isolated to a reaper mechanism without hurting overall performance.
Of course, the devil is in the details. This is proposed as a future work item.
--
This message was sent by Atlassian JIRA
(v6.2#6252)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]