Uploaded image for project: 'Qpid'
  1. Qpid
  2. QPID-5668

Windows C++ AsynchIO layer enhancement

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Open
    • Minor
    • Resolution: Unresolved
    • 0.26
    • None
    • C++ Broker, C++ Client
    • None
    • Windows

    Description

      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.

      Attachments

        Activity

          People

            cliffjansen Clifford Jansen
            cliffjansen Clifford Jansen
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated: