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: dev-unsubscr...@qpid.apache.org For additional commands, e-mail: dev-h...@qpid.apache.org